Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 6 additions & 20 deletions packages/effect-codex-app-server/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ export const makeCodexAppServerPatchedProtocol = Effect.fn("makeCodexAppServerPa
const incomingRequests = yield* Queue.unbounded<CodexAppServerIncomingRequest>();
const pending = yield* Ref.make(new Map<string, CodexAppServerPendingRequest>());
const nextRequestId = yield* Ref.make(1);
const remainder = yield* Ref.make("");
const terminationHandled = yield* Ref.make(false);

const logProtocol = (event: CodexAppServerProtocolLogEvent) => {
Expand Down Expand Up @@ -353,31 +352,18 @@ export const makeCodexAppServerPatchedProtocol = Effect.fn("makeCodexAppServerPa

yield* options.stdio.stdin.pipe(
Stream.decodeText(),
Stream.runForEach((chunk) =>
Ref.modify(remainder, (current) => {
const combined = current + chunk;
const lines = combined.split("\n");
const nextRemainder = lines.pop() ?? "";
return [lines.map((line) => line.replace(/\r$/, "")), nextRemainder] as const;
}).pipe(Effect.flatMap((lines) => Effect.forEach(lines, handleLine, { discard: true }))),
),
Stream.splitLines,
Stream.runForEach(handleLine),
Comment on lines +355 to +356

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add focused coverage for fragmented JSONL frames

This replaces the JSONL framing state, but the commit adds no test that splits one JSON object across stdin chunks or delivers multiple frames in one chunk; the existing protocol tests only enqueue complete newline-terminated frames. Those boundaries are precisely the behavior being changed, so a buffering or final-frame-flushing regression could strand pending requests without CI detecting it. Add a focused protocol test covering fragmented, coalesced, and unterminated-at-EOF input.

AGENTS.md reference: AGENTS.md:L108-L108

Useful? React with 👍 / 👎.

Effect.matchEffect({
onFailure: (error) =>
handleTermination(() =>
Effect.succeed(normalizeIncomingError(error, "read-input-stream")),
),
onSuccess: () =>
Ref.get(remainder).pipe(
Effect.flatMap((line) => (line.trim().length === 0 ? Effect.void : handleLine(line))),
Effect.matchEffect({
onFailure: (error) => handleTermination(() => Effect.succeed(error)),
onSuccess: () =>
handleTermination(
() =>
options.terminationError ??
Effect.succeed(new CodexError.CodexAppServerInputStreamEndedError({})),
),
}),
handleTermination(
() =>
options.terminationError ??
Effect.succeed(new CodexError.CodexAppServerInputStreamEndedError({})),
),
}),
Effect.forkScoped,
Expand Down
Loading