mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 14:39:42 +02:00
fix(codex): review fixes — envelope handling, mode guards, UI parity
Blocker: runCodex read raw response shapes, but the global
preSerialization hook (server.ts) wraps every payload in the
{ success, data } envelope — status.available was always undefined, so
the UI unconditionally printed "Codex CLI not found" and could never
start a session; the created session was also never auto-selected
(data.sessionId vs data.data.sessionId). Fixed both reads to match
runOpenCode, and updated the test mocks to the real wire shape (plus a
selectSession assertion) so envelope drift fails the test.
Guard parity: export isExternalCliMode() from session.ts and use it in
the ralph-config guard, all three respawn guards, and the six restore/
setup guards in server.ts that previously only excluded 'opencode' —
codex sessions could otherwise get a Ralph tracker or respawn
controller attached (idle detection is Claude-specific and output-
silence respawn cycling would misfire on a quiet codex TUI).
UI parity: cx tab badge, "Kill Tmux & Codex" dialog title, and the
missing CSS (.run-mode-dot.codex, .tab-mode.codex, .mode-codex button
colors — purple) so the Codex menu dot is no longer invisible. Removed
the dead object-literal runMode getter that Object.assign flattens
(superseded by the defineProperty accessor this PR adds).
Verified end-to-end on an isolated instance with a stub codex binary:
10/10 Playwright checks (menu/dot/label/button styling, session
created + auto-selected, cx badge, TUI output streamed, ralph+respawn
guards reject codex) and --dangerously-bypass-approvals-and-sandbox
+ --model observed on the spawned command line.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,10 +97,12 @@ describe('Codex quick start settings', () => {
|
||||
document: {
|
||||
getElementById: (id: string) => elements[id] ?? null,
|
||||
},
|
||||
// Mock responses use the real wire shape: the global preSerialization hook in
|
||||
// server.ts wraps route payloads into the { success, data } envelope.
|
||||
fetch: async (url: string, init?: { body?: string }) => {
|
||||
requests.push({ url, body: init?.body ? JSON.parse(init.body) : undefined });
|
||||
if (url === '/api/codex/status') return { json: async () => ({ available: true }) };
|
||||
if (url === '/api/quick-start') return { json: async () => ({ success: true, sessionId: 'sess-1' }) };
|
||||
if (url === '/api/codex/status') return { json: async () => ({ success: true, data: { available: true } }) };
|
||||
if (url === '/api/quick-start') return { json: async () => ({ success: true, data: { sessionId: 'sess-1' } }) };
|
||||
throw new Error(`unexpected fetch: ${url}`);
|
||||
},
|
||||
console,
|
||||
@@ -116,7 +118,10 @@ describe('Codex quick start settings', () => {
|
||||
});
|
||||
app.getCaseSettings = () => ({});
|
||||
app.buildEnvOverrides = () => ({});
|
||||
app.selectSession = async () => {};
|
||||
const selected: string[] = [];
|
||||
app.selectSession = async (id: string) => {
|
||||
selected.push(id);
|
||||
};
|
||||
|
||||
await app.runCodex();
|
||||
|
||||
@@ -125,5 +130,6 @@ describe('Codex quick start settings', () => {
|
||||
mode: 'codex',
|
||||
codexConfig: { dangerouslyBypassApprovals: true, renderMode: 'hybrid' },
|
||||
});
|
||||
expect(selected).toEqual(['sess-1']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user