diff --git a/packages/cli/__tests__/commands/spawn.test.ts b/packages/cli/__tests__/commands/spawn.test.ts index 9b9df9af3..e16c9be6b 100644 --- a/packages/cli/__tests__/commands/spawn.test.ts +++ b/packages/cli/__tests__/commands/spawn.test.ts @@ -202,7 +202,7 @@ describe("spawn command", () => { const content = readFileSync(metaFile, "utf-8"); expect(content).toContain("branch=feat/INT-100"); - expect(content).toContain("status=spawning"); + expect(content).toContain("status=working"); expect(content).toContain("project=my-app"); expect(content).toContain("issue=INT-100"); }); diff --git a/packages/cli/src/commands/spawn.ts b/packages/cli/src/commands/spawn.ts index e27c56946..d43bc403a 100644 --- a/packages/cli/src/commands/spawn.ts +++ b/packages/cli/src/commands/spawn.ts @@ -164,7 +164,8 @@ async function spawnSession( writeMetadata(join(sessionDir, sessionName), { worktree: worktreePath, branch: liveBranch || branch || "detached", - status: "spawning", + status: "working", + runtimeHandle: JSON.stringify({ id: sessionName, runtimeName: "tmux" }), project: projectId, ...(issueId ? { issue: issueId } : {}), createdAt: new Date().toISOString(), diff --git a/packages/core/src/lifecycle-manager.ts b/packages/core/src/lifecycle-manager.ts index 1827ed97c..32b2664a0 100644 --- a/packages/core/src/lifecycle-manager.ts +++ b/packages/core/src/lifecycle-manager.ts @@ -11,6 +11,8 @@ */ import { randomUUID } from "node:crypto"; +import { join } from "node:path"; +import { existsSync } from "node:fs"; import type { LifecycleManager, SessionManager, diff --git a/packages/plugins/agent-claude-code/src/index.ts b/packages/plugins/agent-claude-code/src/index.ts index b09bd6895..4d497a4fd 100644 --- a/packages/plugins/agent-claude-code/src/index.ts +++ b/packages/plugins/agent-claude-code/src/index.ts @@ -498,7 +498,8 @@ function classifyTerminalOutput(terminalOutput: string): ActivityState { // Check the last line FIRST — if the prompt is visible, the agent is idle // regardless of historical output (e.g. "Reading file..." from earlier). // The ❯ is Claude Code's prompt character. - if (/^[❯>$#]\s*$/.test(lastLine)) return "idle"; + // Bare prompt is idle ONLY when not actively processing (no "esc to interrupt") + if (/^[❯>$#]\s*$/.test(lastLine) && !hasEscToInterrupt) return "idle"; // Claude Code shows inline suggestions after the prompt when idle, e.g. // "❯ check CI status on the PR". Distinguish from active processing by