From c6c93648786d23d433bd76cc7c1d8261c1c1900c Mon Sep 17 00:00:00 2001 From: Deltoyd Date: Mon, 14 Sep 2026 15:50:23 +0200 Subject: [PATCH 1/3] fix: recognize Codex CLI "Ask Codex to do anything" ready prompt Codex CLI 0.154.0 (as launched via a custom codex-nono agent) renders its idle input prompt as "> Ask Codex to do anything" instead of the "> Type your message" text the readiness detector already handled. AGENT_READY_TAIL_PATTERNS only matched "Type your message" or a bare ">", so the coordinator never saw the agent as ready and automatic prompt delivery stayed stuck at "Waiting to send prompt...". Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0159pgngC1aN4DEVBQoiCGNc --- electron/mcp/agent-frame-fixtures.ts | 8 ++++++++ electron/mcp/prompt-detect.test.ts | 9 +++++++++ electron/shared/prompt-detect.ts | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/electron/mcp/agent-frame-fixtures.ts b/electron/mcp/agent-frame-fixtures.ts index ad78a1a4c..b44f48a2a 100644 --- a/electron/mcp/agent-frame-fixtures.ts +++ b/electron/mcp/agent-frame-fixtures.ts @@ -51,6 +51,14 @@ export const READY_AGENT_FRAME_FIXTURES: AgentFrameFixture[] = [ '> Type your message or @path/to/file', ].join('\n'), }, + { + name: 'Codex CLI 0.154.0 "Ask Codex to do anything" prompt (custom nono agent wrapper)', + frame: [ + '> Ask Codex to do anything', + '', + 'gpt-5.5 default · /Users/brooksc/git/parallel-code/.worktrees/task-031-nono', + ].join('\n'), + }, ]; export const NOT_READY_AGENT_FRAME_FIXTURES: NotReadyAgentFrameFixture[] = [ diff --git a/electron/mcp/prompt-detect.test.ts b/electron/mcp/prompt-detect.test.ts index 159ee21df..4830b9b0f 100644 --- a/electron/mcp/prompt-detect.test.ts +++ b/electron/mcp/prompt-detect.test.ts @@ -259,6 +259,15 @@ describe('chunkContainsAgentPrompt', () => { ).toBe(true); }); + it('returns true for Codex CLI 0.154.0 "Ask Codex to do anything" prompt', () => { + expect(chunkContainsAgentPrompt('> Ask Codex to do anything')).toBe(true); + }); + + it('returns true for Codex CLI "Ask Codex to do anything" prompt above footer/status text', () => { + const footer = '\n\ngpt-5.5 default · ~/repo/worktree'; + expect(chunkContainsAgentPrompt(`> Ask Codex to do anything${footer}`)).toBe(true); + }); + it('does not treat Codex startup screens as ready', () => { expect( chunkContainsAgentPrompt('Starting MCP servers (0/2): codex_apps, parallel-code\n›'), diff --git a/electron/shared/prompt-detect.ts b/electron/shared/prompt-detect.ts index 63f1ecd72..08a0a05be 100644 --- a/electron/shared/prompt-detect.ts +++ b/electron/shared/prompt-detect.ts @@ -30,7 +30,7 @@ export const AGENT_READY_TAIL_PATTERNS: RegExp[] = [ /^\s*❯\s*$/, /^\s*--\s*INSERT\s*--(?:$|\s|[^\w].*$)/i, /^\s*›\s*$/, - /^\s*>\s*(?:Type your message|$)/i, + /^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i, ]; export const AGENT_READY_TAIL_CHARS = 1000; From 37839dc04ce284ab6d2c7b260b178a009902cd38 Mon Sep 17 00:00:00 2001 From: Deltoyd Date: Mon, 14 Sep 2026 15:56:48 +0200 Subject: [PATCH 2/3] test: sync coordinator-test-harness prompt-detect mock with readiness fix coordinator-test-harness.ts vi.mock's ../shared/prompt-detect.js with a hand-duplicated copy of AGENT_READY_TAIL_PATTERNS instead of importing the real module, so the previous commit's regex fix wasn't reflected here and the new "Ask Codex to do anything" fixture failed only in coordinator.test.ts's it.each suites. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0159pgngC1aN4DEVBQoiCGNc --- electron/mcp/coordinator-test-harness.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/electron/mcp/coordinator-test-harness.ts b/electron/mcp/coordinator-test-harness.ts index fccf4f24e..7112508b0 100644 --- a/electron/mcp/coordinator-test-harness.ts +++ b/electron/mcp/coordinator-test-harness.ts @@ -146,7 +146,7 @@ vi.mock('../shared/prompt-detect.js', () => ({ .slice(-1000) .split(/\r\n?|\n/) .some((line) => - /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|$)/i.test( + /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i.test( line.trim(), ), ); @@ -171,7 +171,7 @@ vi.mock('../shared/prompt-detect.js', () => ({ return tail .split(/\r\n?|\n/) .some((line) => - /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|$)/i.test( + /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i.test( line.trim(), ), ); From 77a9cb5d9ad80dc02cc8c9a3cc7f0a227a50a9c0 Mon Sep 17 00:00:00 2001 From: Deltoyd Date: Mon, 14 Sep 2026 17:23:32 +0200 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20match=20Codex's=20actual=20=E2=80=BA?= =?UTF-8?q?=20prompt=20char,=20not=20a=20plain=20>?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The original bug report described the Codex 0.154.0 idle prompt as literal "> Ask Codex to do anything", so the first pass extended only the ">" branch of AGENT_READY_TAIL_PATTERNS. A screenshot of the real app confirms Codex still renders its usual "›" prompt character, just with the new placeholder text trailing it ("› Ask Codex to do anything") instead of standing alone the way the readiness detector expected. The bare "›" pattern required end-of-line right after the character, so it never matched either. Merges the bare-"›" and ">"-with-placeholder patterns into one that accepts either prompt character followed by either known placeholder (or nothing, preserving the old bare-prompt behavior), and fixes the fixture/tests to use the real "›" character instead of the transcribed ">". Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_0159pgngC1aN4DEVBQoiCGNc --- electron/mcp/agent-frame-fixtures.ts | 4 ++-- electron/mcp/coordinator-test-harness.ts | 4 ++-- electron/mcp/prompt-detect.test.ts | 14 ++++++++++---- electron/shared/prompt-detect.ts | 3 +-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/electron/mcp/agent-frame-fixtures.ts b/electron/mcp/agent-frame-fixtures.ts index b44f48a2a..70dcd1ada 100644 --- a/electron/mcp/agent-frame-fixtures.ts +++ b/electron/mcp/agent-frame-fixtures.ts @@ -54,9 +54,9 @@ export const READY_AGENT_FRAME_FIXTURES: AgentFrameFixture[] = [ { name: 'Codex CLI 0.154.0 "Ask Codex to do anything" prompt (custom nono agent wrapper)', frame: [ - '> Ask Codex to do anything', + '› Ask Codex to do anything', '', - 'gpt-5.5 default · /Users/brooksc/git/parallel-code/.worktrees/task-031-nono', + 'gpt-5.6-luna high · /Users/brooksc/git/parallel-code/.worktrees/task-031-nono', ].join('\n'), }, ]; diff --git a/electron/mcp/coordinator-test-harness.ts b/electron/mcp/coordinator-test-harness.ts index 7112508b0..7896700b9 100644 --- a/electron/mcp/coordinator-test-harness.ts +++ b/electron/mcp/coordinator-test-harness.ts @@ -146,7 +146,7 @@ vi.mock('../shared/prompt-detect.js', () => ({ .slice(-1000) .split(/\r\n?|\n/) .some((line) => - /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i.test( + /(?:^|\s)❯\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*[›>]\s*(?:Type your message|Ask Codex to do anything|$)/i.test( line.trim(), ), ); @@ -171,7 +171,7 @@ vi.mock('../shared/prompt-detect.js', () => ({ return tail .split(/\r\n?|\n/) .some((line) => - /(?:^|\s)[❯›]\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i.test( + /(?:^|\s)❯\s*$|^\s*--\s*INSERT\s*--\s*$|^\s*[›>]\s*(?:Type your message|Ask Codex to do anything|$)/i.test( line.trim(), ), ); diff --git a/electron/mcp/prompt-detect.test.ts b/electron/mcp/prompt-detect.test.ts index 4830b9b0f..9fd9d4547 100644 --- a/electron/mcp/prompt-detect.test.ts +++ b/electron/mcp/prompt-detect.test.ts @@ -259,13 +259,19 @@ describe('chunkContainsAgentPrompt', () => { ).toBe(true); }); - it('returns true for Codex CLI 0.154.0 "Ask Codex to do anything" prompt', () => { - expect(chunkContainsAgentPrompt('> Ask Codex to do anything')).toBe(true); + it('returns true for Codex CLI 0.154.0 "Ask Codex to do anything" prompt (› prompt char)', () => { + expect(chunkContainsAgentPrompt('› Ask Codex to do anything')).toBe(true); }); it('returns true for Codex CLI "Ask Codex to do anything" prompt above footer/status text', () => { - const footer = '\n\ngpt-5.5 default · ~/repo/worktree'; - expect(chunkContainsAgentPrompt(`> Ask Codex to do anything${footer}`)).toBe(true); + const footer = '\n\ngpt-5.6-luna high · ~/repo/worktree'; + expect(chunkContainsAgentPrompt(`› Ask Codex to do anything${footer}`)).toBe(true); + }); + + it('returns true for a plain-> variant of the "Ask Codex to do anything" prompt', () => { + // Defensive: some agent builds may render the composer with a plain `>` + // instead of Codex's usual `›` — both should be recognized as ready. + expect(chunkContainsAgentPrompt('> Ask Codex to do anything')).toBe(true); }); it('does not treat Codex startup screens as ready', () => { diff --git a/electron/shared/prompt-detect.ts b/electron/shared/prompt-detect.ts index 08a0a05be..8c8420e49 100644 --- a/electron/shared/prompt-detect.ts +++ b/electron/shared/prompt-detect.ts @@ -29,8 +29,7 @@ export const PROMPT_PATTERNS: RegExp[] = [ export const AGENT_READY_TAIL_PATTERNS: RegExp[] = [ /^\s*❯\s*$/, /^\s*--\s*INSERT\s*--(?:$|\s|[^\w].*$)/i, - /^\s*›\s*$/, - /^\s*>\s*(?:Type your message|Ask Codex to do anything|$)/i, + /^\s*[›>]\s*(?:Type your message|Ask Codex to do anything|$)/i, ]; export const AGENT_READY_TAIL_CHARS = 1000;