Skip to content

Commit b5bbb6d

Browse files
Quentinjuliusmarminge
authored andcommitted
feat(web): implement approved plans in new worktrees
1 parent 837a151 commit b5bbb6d

4 files changed

Lines changed: 4 additions & 150 deletions

File tree

apps/server/src/codexAppServerManager.test.ts

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { EventEmitter } from "node:events";
21
import { describe, expect, it, vi } from "vitest";
32
import { randomUUID } from "node:crypto";
43
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
@@ -206,77 +205,6 @@ describe("classifyCodexStderrLine", () => {
206205
message: line,
207206
});
208207
});
209-
210-
it("emits process/stderr as a notification event", () => {
211-
const manager = new CodexAppServerManager();
212-
const events: Array<{ method: string; kind: string; message?: string }> = [];
213-
manager.on("event", (event) => {
214-
events.push({
215-
method: event.method,
216-
kind: event.kind,
217-
...(event.message ? { message: event.message } : {}),
218-
});
219-
});
220-
221-
const output = new EventEmitter();
222-
const stderr = new EventEmitter();
223-
const child = new EventEmitter() as EventEmitter & { stderr: EventEmitter };
224-
child.stderr = stderr;
225-
226-
type ProcessListenerHarnessContext = {
227-
session: {
228-
provider: "codex";
229-
status: "ready";
230-
threadId: ThreadId;
231-
runtimeMode: "full-access";
232-
createdAt: string;
233-
updatedAt: string;
234-
};
235-
child: EventEmitter & { stderr: EventEmitter };
236-
output: EventEmitter;
237-
pending: Map<string, unknown>;
238-
pendingApprovals: Map<string, unknown>;
239-
pendingUserInputs: Map<string, unknown>;
240-
nextRequestId: number;
241-
stopping: boolean;
242-
};
243-
244-
const context: ProcessListenerHarnessContext = {
245-
session: {
246-
provider: "codex" as const,
247-
status: "ready" as const,
248-
threadId: asThreadId("thread-1"),
249-
runtimeMode: "full-access" as const,
250-
createdAt: "2026-02-10T00:00:00.000Z",
251-
updatedAt: "2026-02-10T00:00:00.000Z",
252-
},
253-
child,
254-
output,
255-
pending: new Map(),
256-
pendingApprovals: new Map(),
257-
pendingUserInputs: new Map(),
258-
nextRequestId: 1,
259-
stopping: false,
260-
};
261-
262-
(
263-
manager as unknown as {
264-
attachProcessListeners: (context: ProcessListenerHarnessContext) => void;
265-
}
266-
).attachProcessListeners(context);
267-
268-
const line =
269-
"2026-03-10T01:03:53.921955Z ERROR codex_core::models_manager::manager: failed to renew cache TTL: EOF while parsing a value at line 1 column 0";
270-
stderr.emit("data", Buffer.from(`${line}\n`));
271-
272-
expect(events).toEqual([
273-
{
274-
method: "process/stderr",
275-
kind: "notification",
276-
message: line,
277-
},
278-
]);
279-
});
280208
});
281209

282210
describe("process stderr events", () => {

apps/server/src/codexAppServerManager.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,7 +1046,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve
10461046
continue;
10471047
}
10481048

1049-
this.emitNotificationEvent(context, "process/stderr", classified.message);
1049+
this.emitErrorEvent(context, "process/stderr", classified.message);
10501050
}
10511051
});
10521052

@@ -1342,22 +1342,6 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve
13421342
});
13431343
}
13441344

1345-
private emitNotificationEvent(
1346-
context: CodexSessionContext,
1347-
method: string,
1348-
message: string,
1349-
): void {
1350-
this.emitEvent({
1351-
id: EventId.makeUnsafe(randomUUID()),
1352-
kind: "notification",
1353-
provider: "codex",
1354-
threadId: context.session.threadId,
1355-
createdAt: new Date().toISOString(),
1356-
method,
1357-
message,
1358-
});
1359-
}
1360-
13611345
private emitErrorEvent(context: CodexSessionContext, method: string, message: string): void {
13621346
this.emitEvent({
13631347
id: EventId.makeUnsafe(randomUUID()),

apps/server/src/provider/Layers/CodexAdapter.test.ts

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -651,50 +651,9 @@ lifecycleLayer("CodexAdapterLive lifecycle", (it) => {
651651
assert.equal(firstEvent.payload.reason, "Sandbox setup failed");
652652
}
653653

654-
assert.equal(secondEvent?.type, "runtime.warning");
655-
if (secondEvent?.type === "runtime.warning") {
656-
assert.equal(secondEvent.payload.message, "Sandbox setup failed");
657-
}
658-
}),
659-
);
660-
661-
it.effect("maps process/stderr notifications into runtime warnings", () =>
662-
Effect.gen(function* () {
663-
const adapter = yield* CodexAdapter;
664-
const eventsFiber = yield* Stream.runCollect(Stream.take(adapter.streamEvents, 1)).pipe(
665-
Effect.timeoutOption(1_000),
666-
Effect.forkChild,
667-
);
668-
669-
const event: ProviderEvent = {
670-
id: asEventId("evt-process-stderr"),
671-
kind: "notification",
672-
provider: "codex",
673-
threadId: asThreadId("thread-1"),
674-
createdAt: new Date().toISOString(),
675-
method: "process/stderr",
676-
message:
677-
"2026-03-10T01:03:53.921955Z ERROR codex_core::models_manager::manager: failed to renew cache TTL: EOF while parsing a value at line 1 column 0",
678-
};
679-
680-
lifecycleManager.emit("event", event);
681-
const maybeEvents = yield* Fiber.join(eventsFiber);
682-
683-
assert.equal(Option.isSome(maybeEvents), true);
684-
if (Option.isNone(maybeEvents)) {
685-
return;
686-
}
687-
688-
const events = Array.from(maybeEvents.value);
689-
assert.equal(events.length, 1);
690-
691-
const warningEvent = events[0];
692-
assert.equal(warningEvent?.type, "runtime.warning");
693-
if (warningEvent?.type === "runtime.warning") {
694-
assert.equal(
695-
warningEvent.payload.message,
696-
"2026-03-10T01:03:53.921955Z ERROR codex_core::models_manager::manager: failed to renew cache TTL: EOF while parsing a value at line 1 column 0",
697-
);
654+
assert.equal(secondEvent?.type, "runtime.warning");
655+
if (secondEvent?.type === "runtime.warning") {
656+
assert.equal(secondEvent.payload.message, "Sandbox setup failed");
698657
}
699658
}),
700659
);

apps/server/src/provider/Layers/CodexAdapter.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -696,23 +696,6 @@ function mapToRuntimeEvents(
696696
];
697697
}
698698

699-
if (event.method === "process/stderr") {
700-
if (!event.message) {
701-
return [];
702-
}
703-
704-
return [
705-
{
706-
type: "runtime.warning",
707-
...runtimeEventBase(event, canonicalThreadId),
708-
payload: {
709-
message: event.message,
710-
...(event.payload !== undefined ? { detail: event.payload } : {}),
711-
},
712-
},
713-
];
714-
}
715-
716699
if (event.method === "thread/started") {
717700
const payloadThreadId = asString(asObject(payload?.thread)?.id);
718701
const providerThreadId = payloadThreadId ?? asString(payload?.threadId);

0 commit comments

Comments
 (0)