Add Codex session reader and CLI integration#1
Conversation
Introduce support for Codex sessions: add a parseCodexSession reader, tests, and JSONL fixtures; export the parser from the reader package. Add a new CLI subcommand and wrapper (burn codex) that spawns the codex binary, finds new session files, parses turns, appends them to the ledger, and stamps enrichments. Refactor ingestion: consolidate ingestion logic into ingestOne/ingestAll and add ingestCodexSessions; update summary and by-tool commands to call ingestAll instead of the Claude-only ingest. The Codex parser computes per-turn usage deltas, extracts function/custom tool calls, maps filesTouched from patch_apply_end events, and preserves sessionPath when provided.
There was a problem hiding this comment.
Pull request overview
Adds first-class support for ingesting Codex session logs into the Relayburn ledger, and wires that support into the CLI so existing reporting commands include Codex usage alongside Claude.
Changes:
- Add
parseCodexSessionreader with tests + JSONL fixtures for multi-turn usage deltas and tool/file extraction. - Add
burn codexCLI wrapper command and refactor ingestion intoingestOne+ingestAll(Claude + Codex). - Update
summaryandby-toolcommands to ingest from all supported sources.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/fixtures/codex/with-tool-call.jsonl | Codex fixture covering function/custom tool calls and patch-derived filesTouched. |
| tests/fixtures/codex/simple-turn.jsonl | Codex fixture for a basic one-turn session and token_count handling. |
| tests/fixtures/codex/multi-turn.jsonl | Codex fixture validating per-turn usage deltas across multiple turns. |
| packages/reader/src/index.ts | Exports Codex parser/types from the reader package. |
| packages/reader/src/codex.ts | Implements Codex JSONL parsing into TurnRecords (usage deltas, tool calls, files touched). |
| packages/reader/src/codex.test.ts | Adds unit coverage for Codex parsing behavior and stability guarantees (argsHash). |
| packages/cli/src/ingest.ts | Refactors ingestion into ingestOne and adds Codex ingestion + ingestAll. |
| packages/cli/src/commands/summary.ts | Switches summary to ingest all sources before querying. |
| packages/cli/src/commands/by-tool.ts | Switches by-tool to ingest all sources before querying. |
| packages/cli/src/commands/codex.ts | Adds burn codex wrapper to spawn codex and ingest newly created session files + stamp tags. |
| packages/cli/src/cli.ts | Registers the new codex subcommand and updates help text. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- ingestAll loads HWM once and saves once, removing double I/O and reducing clobber risk when multiple passes share state. - Factor walkJsonl into packages/cli/src/walk.ts; reuse from ingest and codex wrapper to keep traversal logic in one place. - Drop the mtime-vs-spawn-start filter in findNewSessions; preSnapshot already excludes pre-existing files, and the 1ms cushion is fragile on filesystems with coarse timestamp granularity. - If session_meta arrives after task_started, propagate its cwd to the open turn's project when still unset. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class support for ingesting and analyzing OpenAI Codex CLI sessions alongside existing Claude Code ingestion, including a new reader/parser, fixtures/tests, and CLI wiring.
Changes:
- Add
parseCodexSessionto the reader package with JSONL fixtures + unit tests. - Refactor CLI ingestion into shared
ingestOne/ingestAlland add Codex session ingestion via recursive JSONL discovery. - Add
burn codexwrapper subcommand and updatesummary/by-toolto ingest all sources.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/fixtures/codex/with-tool-call.jsonl | Fixture covering function calls, custom tool calls, and patch-based file touches. |
| tests/fixtures/codex/simple-turn.jsonl | Fixture for a minimal single-turn Codex session with token usage. |
| tests/fixtures/codex/multi-turn.jsonl | Fixture validating multi-turn usage deltas across cumulative token counts. |
| packages/reader/src/index.ts | Exports Codex parser + options from the reader package entrypoint. |
| packages/reader/src/codex.ts | Implements Codex JSONL session parsing into TurnRecords (usage deltas, tool calls, files touched). |
| packages/reader/src/codex.test.ts | Adds node:test coverage for parsing, usage deltas, targets, argsHash stability, sessionPath. |
| packages/cli/src/walk.ts | Adds shared recursive JSONL file discovery helper for CLI ingestion/wrapper flows. |
| packages/cli/src/ingest.ts | Consolidates ingestion logic and adds Codex ingestion + ingestAll(). |
| packages/cli/src/commands/summary.ts | Switches summary command ingestion from Claude-only to ingestAll(). |
| packages/cli/src/commands/codex.ts | Adds burn codex wrapper to spawn Codex and ingest newly created sessions. |
| packages/cli/src/commands/by-tool.ts | Switches by-tool ingestion from Claude-only to ingestAll(). |
| packages/cli/src/cli.ts | Wires the new burn codex subcommand into the CLI dispatcher and help text. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const st = await stat(file); | ||
| const prior = hwm[file]; | ||
| if (prior && prior.mtimeMs >= st.mtimeMs) return; | ||
|
|
||
| const turns = await parse(file); |
Wrap the stat/parse/append block in try/catch so a single bad session file (removed mid-scan, permission denied, malformed JSONL that the parser chokes on) logs to stderr and is skipped instead of aborting the entire ingestion pass. Matches the error-swallowing posture of the surrounding directory traversal helpers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class Codex session support to relayburn by introducing a Codex JSONL session parser in @relayburn/reader, integrating Codex ingestion into the CLI ingestion flow, and adding a burn codex wrapper command to spawn Codex and ingest the resulting sessions into the ledger.
Changes:
- Implement
parseCodexSession(with fixtures + tests) and export it from@relayburn/reader. - Refactor CLI ingestion into shared helpers and add Codex ingestion (
ingestAll,ingestCodexSessions,walkJsonl). - Add
burn codexwrapper command and updatesummary/by-toolto ingest from all supported sources.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/fixtures/codex/with-tool-call.jsonl | Codex fixture covering function + custom tool calls and patch events. |
| tests/fixtures/codex/simple-turn.jsonl | Codex fixture for a minimal single-turn session + token_count shapes. |
| tests/fixtures/codex/multi-turn.jsonl | Codex fixture validating per-turn cumulative-usage deltas across turns. |
| packages/reader/src/index.ts | Exports Codex parser + options from the reader package. |
| packages/reader/src/codex.ts | New Codex JSONL session parser producing TurnRecord[]. |
| packages/reader/src/codex.test.ts | Tests for parsing, tool call extraction, filesTouched mapping, usage deltas, and sessionPath. |
| packages/cli/src/walk.ts | Shared directory walker to find .jsonl files recursively. |
| packages/cli/src/ingest.ts | Refactors ingestion into ingestOne + adds Codex ingestion + ingestAll. |
| packages/cli/src/commands/summary.ts | Uses ingestAll so summary includes Codex sessions. |
| packages/cli/src/commands/codex.ts | Adds burn codex wrapper: spawn codex, detect new session files, ingest + stamp tags. |
| packages/cli/src/commands/by-tool.ts | Uses ingestAll so by-tool includes Codex sessions. |
| packages/cli/src/cli.ts | Registers the new codex subcommand and updates help text. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const newTurns = prior | ||
| ? turns.filter( | ||
| (t) => | ||
| t.ts > prior.lastTs || (t.ts === prior.lastTs && t.messageId !== prior.lastMessageId), | ||
| ) | ||
| : turns; | ||
|
|
| for (const file of newFiles) { | ||
| const turns = await parseCodexSession(file, { sessionPath: file }); | ||
| if (turns.length === 0) continue; | ||
| await appendTurns(turns); | ||
| const sessionId = turns[0]!.sessionId; | ||
| if (sessionId) await stamp({ sessionId }, tags); | ||
| process.stderr.write(`[burn] ingested ${turns.length} turns from ${file}\n`); | ||
| } |
| const turns = await parseCodexSession(file, { sessionPath: file }); | ||
| if (turns.length === 0) continue; | ||
| await appendTurns(turns); | ||
| const sessionId = turns[0]!.sessionId; | ||
| if (sessionId) await stamp({ sessionId }, tags); | ||
| process.stderr.write(`[burn] ingested ${turns.length} turns from ${file}\n`); |
- Swap delegation/planning priority so spawning a subagent dominates a plan-mode transition (Copilot #1). - Promote non-edit turns to debugging when any tool call errored, so a failing pytest/git push/build lands in debugging rather than testing/git/build-deploy (Copilot #2). - Add classifier tests covering the failed-bash promotion (Copilot #3). - Thread lastUserText through parseClaudeSessionIncremental options and result, persist it on ClaudeCursor, and pass it back from the CLI ingest loop, so the user prompt survives a resume when endOffset backed up past it to defer an incomplete assistant turn. Without this the resumed turn classified as coding instead of debugging (Devin).
Introduce support for Codex sessions: add a parseCodexSession reader, tests, and JSONL fixtures; export the parser from the reader package. Add a new CLI subcommand and wrapper (burn codex) that spawns the codex binary, finds new session files, parses turns, appends them to the ledger, and stamps enrichments. Refactor ingestion: consolidate ingestion logic into ingestOne/ingestAll and add ingestCodexSessions; update summary and by-tool commands to call ingestAll instead of the Claude-only ingest. The Codex parser computes per-turn usage deltas, extracts function/custom tool calls, maps filesTouched from patch_apply_end events, and preserves sessionPath when provided.