feat(cmd/a): make archive idempotent

Amolith and Crush created

Co-authored-by: Crush <crush@charm.land>

Change summary

cmd/a.go | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)

Detailed changes

cmd/a.go 🔗

@@ -6,6 +6,7 @@ package cmd
 
 import (
 	"fmt"
+	"os"
 
 	"git.secluded.site/np/cmd/shared"
 	"github.com/spf13/cobra"
@@ -24,11 +25,33 @@ func runArchiveSession(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	sessionDoc, found, err := shared.ActiveSession(cmd, env)
+	cwd, err := os.Getwd()
+	if err != nil {
+		return fmt.Errorf("determine working directory: %w", err)
+	}
+
+	// Try to get active session (without printing error message)
+	sessionDoc, found, err := env.ActiveSession(cmd.Context(), cwd)
 	if err != nil {
 		return err
 	}
+
 	if !found {
+		// Check if there's already an archived session (idempotency check)
+		archivedDoc, foundArchived, err := env.SessionStore.LatestArchivedByPath(cmd.Context(), cwd)
+		if err != nil {
+			return err
+		}
+
+		if foundArchived {
+			// Session already archived, idempotent operation
+			out := cmd.OutOrStdout()
+			_, _ = fmt.Fprintf(out, "Session %s archived.\n", archivedDoc.SID)
+			return nil
+		}
+
+		// No session at all (neither active nor archived)
+		_, _ = fmt.Fprintln(cmd.OutOrStdout(), "No active session. Start one with `np s`.")
 		return nil
 	}
 
@@ -38,6 +61,6 @@ func runArchiveSession(cmd *cobra.Command, args []string) error {
 	}
 
 	out := cmd.OutOrStdout()
-	fmt.Fprintf(out, "Session %s archived.\n", archived.SID)
+	_, _ = fmt.Fprintf(out, "Session %s archived.\n", archived.SID)
 	return nil
 }