diff --git a/cli/package.json b/cli/package.json index ef27f656..fc916db5 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@openrouter/spawn", - "version": "0.2.45", + "version": "0.2.46", "type": "module", "bin": { "spawn": "cli.js" diff --git a/cli/src/__tests__/commands-error-paths.test.ts b/cli/src/__tests__/commands-error-paths.test.ts index 459e9cc5..74a3c89c 100644 --- a/cli/src/__tests__/commands-error-paths.test.ts +++ b/cli/src/__tests__/commands-error-paths.test.ts @@ -359,8 +359,8 @@ describe("Commands Error Paths", () => { await expect(cmdRun("sprite", "claude")).rejects.toThrow("process.exit"); expect(processExitSpy).toHaveBeenCalledWith(1); - const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" ")); - expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); + const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); + expect(infoCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); }); it("should suggest the correct argument order when swapped", async () => { @@ -373,8 +373,8 @@ describe("Commands Error Paths", () => { it("should suggest correct order for hetzner/aider swap", async () => { await expect(cmdRun("hetzner", "aider")).rejects.toThrow("process.exit"); - const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" ")); - expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); + const infoCalls2 = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); + expect(infoCalls2.some((msg: string) => msg.includes("swapped"))).toBe(true); const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); expect(infoCalls.some((msg: string) => msg.includes("spawn aider hetzner"))).toBe(true); diff --git a/cli/src/__tests__/commands-swap-resolve.test.ts b/cli/src/__tests__/commands-swap-resolve.test.ts index 5c6facbb..ffda4ba0 100644 --- a/cli/src/__tests__/commands-swap-resolve.test.ts +++ b/cli/src/__tests__/commands-swap-resolve.test.ts @@ -113,10 +113,8 @@ describe("detectAndFixSwappedArgs via cmdRun", () => { // May throw from script execution } - const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" ")); - expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); - const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); + expect(infoCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); expect(infoCalls.some((msg: string) => msg.includes("spawn claude sprite"))).toBe(true); }); @@ -221,8 +219,8 @@ describe("detectAndFixSwappedArgs via cmdRun", () => { } // Should detect the swap - const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" ")); - expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); + const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); + expect(infoCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); // Should then fail at implementation check const errorCalls = mockLogError.mock.calls.map((c: any[]) => c.join(" ")); @@ -552,8 +550,8 @@ describe("prompt handling with swapped args", () => { } // Should detect swap - const warnCalls = mockLogWarn.mock.calls.map((c: any[]) => c.join(" ")); - expect(warnCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); + const infoCalls = mockLogInfo.mock.calls.map((c: any[]) => c.join(" ")); + expect(infoCalls.some((msg: string) => msg.includes("swapped"))).toBe(true); // Should show launch message with prompt const stepCalls = mockLogStep.mock.calls.map((c: any[]) => c.join(" ")); diff --git a/cli/src/commands.ts b/cli/src/commands.ts index 4fe02cc2..300cd4be 100644 --- a/cli/src/commands.ts +++ b/cli/src/commands.ts @@ -319,7 +319,7 @@ function detectAndFixSwappedArgs( cloud: string ): { agent: string; cloud: string } { if (!manifest.agents[agent] && manifest.clouds[agent] && manifest.agents[cloud]) { - p.log.warn(`It looks like you swapped the agent and cloud arguments.`); + p.log.info(`It looks like you swapped the agent and cloud arguments.`); p.log.info(`Running: ${pc.cyan(`spawn ${cloud} ${agent}`)}`); return { agent: cloud, cloud: agent }; } @@ -762,18 +762,27 @@ export async function cmdList(agentFilter?: string, cloudFilter?: string): Promi for (const r of records) { const when = formatTimestamp(r.timestamp); - console.log( + let line = pc.green(r.agent.padEnd(20)) + r.cloud.padEnd(20) + - pc.dim(when) - ); + pc.dim(when); + if (r.prompt) { + const preview = r.prompt.length > 40 ? r.prompt.slice(0, 40) + "..." : r.prompt; + line += pc.dim(` --prompt "${preview}"`); + } + console.log(line); } console.log(); // Show rerun hint for the most recent spawn (first record since list is newest-first) const latest = records[0]; - console.log(`Rerun last: ${pc.cyan(`spawn ${latest.agent} ${latest.cloud}`)}`); + if (latest.prompt) { + const shortPrompt = latest.prompt.length > 30 ? latest.prompt.slice(0, 30) + "..." : latest.prompt; + console.log(`Rerun last: ${pc.cyan(`spawn ${latest.agent} ${latest.cloud} --prompt "${shortPrompt}"`)}`); + } else { + console.log(`Rerun last: ${pc.cyan(`spawn ${latest.agent} ${latest.cloud}`)}`); + } console.log(pc.dim(`${records.length} spawn${records.length !== 1 ? "s" : ""} recorded`)); console.log(pc.dim(`Filter: ${pc.cyan("spawn list -a ")} or ${pc.cyan("spawn list -c ")}`)); @@ -833,11 +842,12 @@ export async function cmdClouds(): Promise { const c = manifest.clouds[key]; const implCount = getImplementedAgents(manifest, key).length; const countStr = `${implCount}/${allAgents.length}`; - console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${c.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(`${countStr.padEnd(6)} ${c.description}`)}`); + const authHint = c.auth.toLowerCase() === "none" ? "" : ` auth: ${c.auth}`; + console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${c.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(`${countStr.padEnd(6)} ${c.description}`)}${authHint ? pc.dim(authHint) : ""}`); } } console.log(); - console.log(pc.dim(` Run ${pc.cyan("spawn ")} for details, or ${pc.cyan("spawn ")} to launch.`)); + console.log(pc.dim(` Run ${pc.cyan("spawn ")} for setup instructions, or ${pc.cyan("spawn ")} to launch.`)); console.log(); }