From e5bb6a5600f47ce81ece861b1ce4271c71f8ea54 Mon Sep 17 00:00:00 2001 From: Hop Date: Sat, 11 Jul 2026 16:09:33 -0700 Subject: [PATCH] Fix portable prompt record export command routing Hop-State: A_06FN6WBVEZC485TNKJEW7T0 Hop-Proposal: R_06FN6WAJ8346WS9XJEJY32R Hop-Task: T_06FN6VQSN9Z7GEWHBVEFAJG Hop-Attempt: AT_06FN6VQSN9TK8EEXTFR77ZG --- internal/hop/cli.go | 17 ++++++++--------- internal/hop/service_smoke_test.go | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/internal/hop/cli.go b/internal/hop/cli.go index 070e730..7f6475f 100644 --- a/internal/hop/cli.go +++ b/internal/hop/cli.go @@ -206,6 +206,14 @@ func RunCLIWithInput(args []string, stdin io.Reader, stdout, stderr io.Writer) i fmt.Fprintln(stderr, "usage: hop checkpoint STATE") return 2 } + state, err := service.Checkpoint(ctx, commandArgs[0]) + if err != nil { + return printCLIError(err, jsonOutput, stdout, stderr) + } + value = state + if !jsonOutput { + fmt.Fprintf(stdout, "Created checkpoint %s · tree %s\n", state.ID, shortHash(state.SourceTree)) + } case "export": fs := flag.NewFlagSet("export", flag.ContinueOnError) @@ -229,15 +237,6 @@ func RunCLIWithInput(args []string, stdin io.Reader, stdout, stderr io.Writer) i } fmt.Fprintf(stdout, "Exported %d prompt records to %s\n", len(ledger.Prompts), filepath.Join(root, ".hop", "records", "prompts")) } - state, err := service.Checkpoint(ctx, commandArgs[0]) - if err != nil { - return printCLIError(err, jsonOutput, stdout, stderr) - } - value = state - if !jsonOutput { - fmt.Fprintf(stdout, "Created checkpoint %s · tree %s\n", state.ID, shortHash(state.SourceTree)) - } - case "check": stateID, argv, ok := splitCommand(commandArgs) if !ok { diff --git a/internal/hop/service_smoke_test.go b/internal/hop/service_smoke_test.go index 442aba6..e3bffe5 100644 --- a/internal/hop/service_smoke_test.go +++ b/internal/hop/service_smoke_test.go @@ -345,6 +345,28 @@ func TestCLIJSONWorkflow(t *testing.T) { } } +func TestCLIExportWritesPortablePromptRecords(t *testing.T) { + t.Setenv("HOP_ROOT", "") + root := t.TempDir() + writeTestFile(t, filepath.Join(root, "base.txt"), "base\n") + previousDirectory, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + if err := os.Chdir(root); err != nil { + t.Fatal(err) + } + t.Cleanup(func() { _ = os.Chdir(previousDirectory) }) + + runCLIJSONTest(t, []string{"init", "--json"}) + runCLIJSONTest(t, []string{"begin", "--agent", "codex", "--json", "Publish prompt records"}) + runCLIJSONTest(t, []string{"export", "--output", ".", "--json"}) + entries, err := filepath.Glob(filepath.Join(root, ".hop", "records", "prompts", "P_*.json")) + if err != nil || len(entries) != 1 { + t.Fatalf("portable prompt records = %v, err=%v", entries, err) + } +} + func TestCLIBeginAutoInitializesAndContinuesCodexSession(t *testing.T) { t.Setenv("HOP_ROOT", "") root := t.TempDir()