package cli_test import ( "context" "os" "path/filepath" "strings" "testing" "go.uber.org/zap" clipkg "iop/apps/node/internal/adapters/cli" "iop/apps/node/internal/adapters/cli/internal/testutil" noderuntime "iop/apps/node/internal/runtime" "iop/packages/go/config" ) func TestCLIExecuteAntigravityPrintResumesLogicalSession(t *testing.T) { testutil.RequireUnixShell(t) agy := writeFakeAgy(t, `#!/usr/bin/env sh log_file="" conversation="" prompt="" while [ "$#" -gt 0 ]; do case "$1" in --log-file) log_file="$2" shift 2 ;; --conversation) conversation="$2" shift 2 ;; --print-timeout) shift 2 ;; --dangerously-skip-permissions|--print) shift ;; *) prompt="$1" shift ;; esac done if [ -z "$log_file" ]; then echo "missing --log-file" >&2 exit 9 fi if [ -z "$conversation" ]; then printf 'I0000 server.go:747] Created conversation 11111111-2222-3333-4444-555555555555\n' >> "$log_file" printf 'reply:first:%s\n' "$prompt" else printf 'I0000 printmode.go:71] Print mode: starting (promptLength=1, model="", conversationID="%s")\n' "$conversation" >> "$log_file" printf 'reply:resume:%s:%s\n' "$conversation" "$prompt" fi `) cfg := config.CLIConf{ Enabled: true, Profiles: map[string]config.CLIProfileConf{ "antigravity": { Command: agy, Args: []string{ "--dangerously-skip-permissions", "--print-timeout", "10m", "--print", }, Mode: "antigravity-print", ResumeArgs: []string{ "--dangerously-skip-permissions", "--print-timeout", "10m", "--conversation", }, }, }, } c := clipkg.New(cfg, zap.NewNop()) ctx := context.Background() first := &testutil.FakeSink{} if err := c.Execute(ctx, noderuntime.ExecutionSpec{ RunID: "run-1", Target: "antigravity", SessionID: "session-a", Input: map[string]any{"prompt": "first"}, }, first); err != nil { t.Fatalf("first execute: %v", err) } if combined := testutil.CollectDeltas(first.Events()); !strings.Contains(combined, "reply:first:first") { t.Fatalf("first execute output: %q", combined) } second := &testutil.FakeSink{} if err := c.Execute(ctx, noderuntime.ExecutionSpec{ RunID: "run-2", Target: "antigravity", SessionID: "session-a", Input: map[string]any{"prompt": "second"}, }, second); err != nil { t.Fatalf("second execute: %v", err) } if combined := testutil.CollectDeltas(second.Events()); !strings.Contains(combined, "reply:resume:11111111-2222-3333-4444-555555555555:second") { t.Fatalf("second execute output: %q", combined) } } func TestCLIExecuteAntigravityPrint_MissingResumeArgsErrors(t *testing.T) { testutil.RequireUnixShell(t) agy := writeFakeAgy(t, `#!/usr/bin/env sh echo "should not be called when resume_args is missing" >&2 exit 42 `) cfg := config.CLIConf{ Enabled: true, Profiles: map[string]config.CLIProfileConf{ "antigravity": { Command: agy, Args: []string{"--print"}, Mode: "antigravity-print", ResumeArgs: nil, }, }, } c := clipkg.New(cfg, zap.NewNop()) err := c.Execute(context.Background(), noderuntime.ExecutionSpec{ RunID: "run-1", Target: "antigravity", SessionID: "session-a", Input: map[string]any{"prompt": "first"}, }, &testutil.FakeSink{}) if err == nil { t.Fatalf("expected error due to missing resume_args, got nil") } if !strings.Contains(err.Error(), "resume_args") { t.Fatalf("expected error to mention resume_args, got: %v", err) } } func writeFakeAgy(t *testing.T, script string) string { t.Helper() dir := t.TempDir() path := filepath.Join(dir, "agy") if err := os.WriteFile(path, []byte(script), 0o755); err != nil { t.Fatalf("write fake agy: %v", err) } return path }