From 2cc4e079eb41f930fb9f05c1b358062ebb5f8e83 Mon Sep 17 00:00:00 2001 From: A <258483684+la14-1@users.noreply.github.com> Date: Mon, 9 Feb 2026 19:48:17 -0800 Subject: [PATCH] fix: Polish CLI UX with better hints, legends, and descriptions (#116) - Add legend to `spawn list` matrix output (+ implemented, - not yet available) - Show cloud identifier keys in `spawn ` info output for easy copy-paste - Add CLI shortcut hint in interactive mode after selection - Add agent descriptions to `spawn agents` output - Add agent counts to `spawn clouds` output for consistency - Fix misleading "Updating" spinner in `spawn update` (it only checks) - Add `spawn help` to help text command listing - Improve footer hints in agents/clouds output with actionable commands Agent: ux-engineer Co-authored-by: A <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) --- cli/src/commands.ts | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/cli/src/commands.ts b/cli/src/commands.ts index 6855453b..58d4e55b 100644 --- a/cli/src/commands.ts +++ b/cli/src/commands.ts @@ -174,6 +174,7 @@ export async function cmdInteractive(): Promise { const agentName = manifest.agents[agentChoice].name; const cloudName = manifest.clouds[cloudChoice].name; p.log.step(`Launching ${pc.bold(agentName)} on ${pc.bold(cloudName)}`); + p.log.info(`Next time, run directly: ${pc.cyan(`spawn ${agentChoice} ${cloudChoice}`)}`); p.outro("Handing off to spawn script..."); await execScript(cloudChoice, agentChoice); @@ -374,12 +375,19 @@ export async function cmdList(): Promise { const impl = countImplemented(manifest); const total = agents.length * clouds.length; console.log(); + console.log(`${pc.green("+")} implemented ${pc.dim("-")} not yet available`); console.log(pc.green(`${impl}/${total} combinations implemented`)); console.log(); } // ── Agents ───────────────────────────────────────────────────────────────────── +function getImplementedAgents(manifest: Manifest, cloud: string): string[] { + return agentKeys(manifest).filter( + (a: string): boolean => matrixStatus(manifest, cloud, a) === "implemented" + ); +} + export async function cmdAgents(): Promise { const manifest = await loadManifestWithSpinner(); @@ -389,10 +397,10 @@ export async function cmdAgents(): Promise { for (const key of agentKeys(manifest)) { const a = manifest.agents[key]; const implCount = getImplementedClouds(manifest, key).length; - console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${a.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(`${implCount} clouds`)}`); + console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${a.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(`${implCount} clouds ${a.description}`)}`); } console.log(); - console.log(pc.dim(` Usage: spawn `)); + console.log(pc.dim(` Run ${pc.cyan("spawn ")} for details, or ${pc.cyan("spawn ")} to launch.`)); console.log(); } @@ -406,10 +414,11 @@ export async function cmdClouds(): Promise { console.log(); for (const key of cloudKeys(manifest)) { const c = manifest.clouds[key]; - console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${c.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(c.description)}`); + const implCount = getImplementedAgents(manifest, key).length; + console.log(` ${pc.green(key.padEnd(NAME_COLUMN_WIDTH))} ${c.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim(`${implCount} agents ${c.description}`)}`); } console.log(); - console.log(pc.dim(` Usage: spawn `)); + console.log(pc.dim(` Run ${pc.cyan("spawn ")} to launch.`)); console.log(); } @@ -430,7 +439,7 @@ export async function cmdAgentInfo(agent: string): Promise { const status = matrixStatus(manifest, cloud, agentKey); if (status === "implemented") { const c = manifest.clouds[cloud]; - console.log(` ${pc.green(c.name.padEnd(NAME_COLUMN_WIDTH))} ${pc.dim("spawn " + agentKey + " " + cloud)}`); + console.log(` ${pc.green(cloud.padEnd(NAME_COLUMN_WIDTH))} ${c.name.padEnd(NAME_COLUMN_WIDTH)} ${pc.dim("spawn " + agentKey + " " + cloud)}`); found = true; } } @@ -498,7 +507,7 @@ export async function cmdUpdate(): Promise { return; } - s.message(`Updating v${VERSION} -> v${remoteVersion}...`); + s.message(`Found v${remoteVersion}...`); // Run the install script to update const installRes = await fetch(`${RAW_BASE}/cli/install.sh`); @@ -538,6 +547,7 @@ ${pc.bold("USAGE")} spawn improve [--loop] Run improvement system spawn update Check for CLI updates spawn version Show version + spawn help Show this help message ${pc.bold("EXAMPLES")} spawn ${pc.dim("# Pick interactively")}