From 5ad370e8d11658d1a451cb6dcb82858dbc357ec5 Mon Sep 17 00:00:00 2001 From: adil Date: Tue, 7 Apr 2026 14:05:41 +0530 Subject: [PATCH] fix(cli): simplify spawn success message, use ao session attach (#947) Replace verbose multi-line spawn output (worktree, branch, raw tmux attach) with a single-line message that directs users to the dashboard or `ao session attach ` instead of exposing internal tmux session hashes. Co-Authored-By: Claude Opus 4.6 --- packages/cli/__tests__/commands/spawn.test.ts | 8 +++++--- packages/cli/src/commands/spawn.ts | 18 +++++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/cli/__tests__/commands/spawn.test.ts b/packages/cli/__tests__/commands/spawn.test.ts index 3a54a4282..961d14f0f 100644 --- a/packages/cli/__tests__/commands/spawn.test.ts +++ b/packages/cli/__tests__/commands/spawn.test.ts @@ -281,7 +281,7 @@ describe("spawn command", () => { }); }); - it("shows tmux attach command using runtimeHandle.id (hash-based name)", async () => { + it("shows ao session attach command instead of raw tmux attach", async () => { const fakeSession: Session = { id: "app-7", projectId: "my-app", @@ -303,7 +303,9 @@ describe("spawn command", () => { await program.parseAsync(["node", "test", "spawn"]); const output = consoleSpy.mock.calls.map((c) => String(c[0])).join("\n"); - expect(output).toContain("8474d6f29887-app-7"); + expect(output).toContain("ao session attach app-7"); + expect(output).not.toContain("tmux attach"); + expect(output).not.toContain("8474d6f29887-app-7"); }); it("passes --agent flag to sessionManager.spawn()", async () => { @@ -432,7 +434,7 @@ describe("spawn command", () => { const output = consoleSpy.mock.calls.map((c) => String(c[0])).join("\n"); expect(output).toContain("https://github.com/org/repo/pull/123"); - expect(output).toContain("feat/claimed-pr"); + expect(output).toContain("ao session attach app-1"); }); it("passes GitHub assignment flag through to claimPR", async () => { diff --git a/packages/cli/src/commands/spawn.ts b/packages/cli/src/commands/spawn.ts index e6713758f..aa9a95bc4 100644 --- a/packages/cli/src/commands/spawn.ts +++ b/packages/cli/src/commands/spawn.ts @@ -102,7 +102,6 @@ async function spawnSession( agent, }); - let branchStr = session.branch ?? ""; let claimedPrUrl: string | null = null; if (claimOptions?.claimPr) { @@ -111,7 +110,6 @@ async function spawnSession( const claimResult = await sm.claimPR(session.id, claimOptions.claimPr, { assignOnGithub: claimOptions.assignOnGithub, }); - branchStr = claimResult.pr.branch; claimedPrUrl = claimResult.pr.url; } catch (err) { throw new Error( @@ -127,14 +125,16 @@ async function spawnSession( : `Session ${chalk.green(session.id)} created`, ); - console.log(` Worktree: ${chalk.dim(session.workspacePath ?? "-")}`); - if (branchStr) console.log(` Branch: ${chalk.dim(branchStr)}`); - if (claimedPrUrl) console.log(` PR: ${chalk.dim(claimedPrUrl)}`); + const issueLabel = issueId ? ` for issue #${issueId}` : ""; + const claimLabel = claimedPrUrl ? ` (claimed ${claimedPrUrl})` : ""; + console.log( + `Session ${session.id} spawned${issueLabel}${claimLabel}. ` + + `View it in the dashboard or attach with: ${chalk.cyan(`ao session attach ${session.id}`)}`, + ); // Warn if prompt delivery failed (for post-launch agents like Claude Code) const promptDelivered = session.metadata?.promptDelivered; if (promptDelivered === "false") { - console.log(); console.warn( chalk.yellow( ` ⚠ Prompt delivery failed — agent may be idle.\n` + @@ -143,14 +143,10 @@ async function spawnSession( ); } - // Show the tmux name for attaching (stored in metadata or runtimeHandle) - const tmuxTarget = session.runtimeHandle?.id ?? session.id; - console.log(` Attach: ${chalk.dim(`tmux attach -t ${tmuxTarget}`)}`); - console.log(); - // Open terminal tab if requested if (openTab) { try { + const tmuxTarget = session.runtimeHandle?.id ?? session.id; await exec("open-iterm-tab", [tmuxTarget]); } catch { // Terminal plugin not available