s.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5package cmd
 6
 7import (
 8	"errors"
 9	"fmt"
10	"os"
11
12	"git.secluded.site/np/internal/session"
13	"github.com/spf13/cobra"
14)
15
16var sCmd = &cobra.Command{
17	Use:   "s",
18	Short: "Start session",
19	Long:  `Start a new working-directory-scoped session`,
20	RunE:  runStartSession,
21}
22
23func runStartSession(cmd *cobra.Command, args []string) error {
24	env, err := requireEnvironment()
25	if err != nil {
26		return err
27	}
28
29	ctx := cmd.Context()
30	cwd, err := os.Getwd()
31	if err != nil {
32		return fmt.Errorf("determine working directory: %w", err)
33	}
34
35	doc, err := env.SessionStore.Start(ctx, cwd)
36	if err != nil {
37		var already session.AlreadyActiveError
38		if errors.As(err, &already) {
39			return printExistingSession(cmd, already.Session)
40		}
41		return err
42	}
43
44	printSessionStarted(cmd, doc)
45	return nil
46}
47
48func printExistingSession(cmd *cobra.Command, existing session.Document) error {
49	out := cmd.OutOrStdout()
50	_, _ = fmt.Fprintf(out, "Session %s is already active for %s.\n", existing.SID, existing.DirPath)
51	_, _ = fmt.Fprintln(out, "Ask your operator whether they want to resume (`np r`) or archive (`np a`) it.")
52	return nil
53}
54
55func printSessionStarted(cmd *cobra.Command, doc session.Document) {
56	out := cmd.OutOrStdout()
57	_, _ = fmt.Fprintf(out, "Session %s is now active for %s.\n\n", doc.SID, doc.DirPath)
58
59	_, _ = fmt.Fprintln(out, "Set the goal immediately with `np g s -t \"goal title\" -d \"goal description\"`.")
60	_, _ = fmt.Fprintln(out, "Include ticket numbers, file paths, and any other references inside the goal description.")
61	_, _ = fmt.Fprintln(out, "Once the goal is set, read the referenced files and add tasks:")
62	_, _ = fmt.Fprintln(out, "  Single task:   `np t a -t \"task\" -d \"details\"`")
63	_, _ = fmt.Fprintln(out, "  Multiple tasks: `np t a -t \"first task\" -d \"step 1 details\" -t \"second task\" -d \"step 2 with\\nmulti-line description\"`")
64	_, _ = fmt.Fprintln(out, "Keep task statuses up to date as you work:")
65	_, _ = fmt.Fprintln(out, "  Single update:  `np t u -i task-id -s in_progress|completed|failed|cancelled`")
66	_, _ = fmt.Fprintln(out, "  Batch updates:  `np t u -i abc123 -s completed -i def456 -s in_progress`")
67	_, _ = fmt.Fprintln(out, "Use `np p` whenever you need to review the full plan.")
68}