From 4a1808297351d7d6c72c4aee021fbded33fed438 Mon Sep 17 00:00:00 2001 From: Amolith Date: Wed, 29 Oct 2025 17:00:08 -0600 Subject: [PATCH] feat(cmd/s): implement session start Start command is the entry point for creating directory-scoped sessions. - Replace stub with full implementation - Handle AlreadyActiveError with helpful message - Print next steps after session creation Co-authored-by: Crush --- cmd/s.go | 54 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/cmd/s.go b/cmd/s.go index cd2d577f8c9456cfec5ea2a529d53117858b1757..d33f3f44142c39b0854203abdb156990fa11bdc0 100644 --- a/cmd/s.go +++ b/cmd/s.go @@ -5,8 +5,11 @@ package cmd import ( + "errors" "fmt" + "os" + "git.secluded.site/np/internal/session" "github.com/spf13/cobra" ) @@ -14,21 +17,52 @@ var sCmd = &cobra.Command{ Use: "s", Short: "Start session", Long: `Start a new working-directory-scoped session`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("[STUB] Start new working-directory-scoped session") - }, + RunE: runStartSession, } func init() { rootCmd.AddCommand(sCmd) +} + +func runStartSession(cmd *cobra.Command, args []string) error { + env, err := requireEnvironment() + if err != nil { + return err + } + + ctx := cmd.Context() + cwd, err := os.Getwd() + if err != nil { + return fmt.Errorf("determine working directory: %w", err) + } + + doc, err := env.SessionStore.Start(ctx, cwd) + if err != nil { + var already session.AlreadyActiveError + if errors.As(err, &already) { + return printExistingSession(cmd, already.Session) + } + return err + } - // Here you will define your flags and configuration settings. + printSessionStarted(cmd, doc) + return nil +} + +func printExistingSession(cmd *cobra.Command, existing session.Document) error { + out := cmd.OutOrStdout() + fmt.Fprintf(out, "Session %s is already active for %s.\n", existing.SID, existing.DirPath) + fmt.Fprintln(out, "There's already an active session for this directory; ask your operator whether they want to resume or archive it.") + return nil +} - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // sCmd.PersistentFlags().String("foo", "", "A help for foo") +func printSessionStarted(cmd *cobra.Command, doc session.Document) { + out := cmd.OutOrStdout() + fmt.Fprintf(out, "Session %s is now active for %s.\n\n", doc.SID, doc.DirPath) - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // sCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + fmt.Fprintln(out, "Set the goal immediately with `np g s -t \"goal title\" -d \"goal description\"`.") + fmt.Fprintln(out, "Include ticket numbers, file paths, and any other references inside the goal description.") + fmt.Fprintln(out, "Once the goal is set, read the referenced files and add tasks with `np t a -t \"task\" -d \"details\"`.") + fmt.Fprintln(out, "Keep task statuses up to date with `np t u -i task-id -s in_progress|completed|failed|cancelled` as you work.") + fmt.Fprintln(out, "Use `np p` whenever you need to review the full plan.") }