The connector hooks into Codex CLI’s event system and captures structured data from each session. This page documents what events are captured and how they map to Infinium traces.
Hook Events
The connector listens for these Codex CLI hook events:
| Event | When It Fires | What’s Captured |
|---|---|---|
SessionStart | Codex CLI session begins (startup or resume) | Session ID, model, working directory, source (startup/resume) |
UserPromptSubmit | User sends a prompt | Prompt text |
PreToolUse | Before a tool executes (Bash) | Tool name, tool_input.command |
PostToolUse | After a tool completes | Success/failure (tool_response is a boolean from Codex) |
Stop | Assistant finishes responding | Final assistant message, triggers trace send |
Codex has no explicit
SessionEndevent. The connector handles cleanup viaStopand a stale-session timer.
tool_responsefrom Codex is a boolean —truefor success,falsefor failure. The connector translates this into"Command succeeded"/"Command failed"output summaries. The actual command output isn’t available to hooks.
How Events Become Traces
Events are grouped into turns — each turn is one prompt-response cycle:
Turn 1:
UserPromptSubmit → "Fix the failing npm test"
PreToolUse → Bash("npm test")
PostToolUse → true ← Command succeeded
Stop → "All tests passed after fixing..."
↓
Trace sent to Infinium
Turn 2:
UserPromptSubmit → "Now add a regression test"
PreToolUse → Bash("touch test_auth.py")
PostToolUse → true
PreToolUse → Bash("git diff")
PostToolUse → true
Stop → "Regression test added..."
↓
Trace sent to Infinium
Each Stop event triggers a trace send. Background workers do the aggregation + send so Codex CLI is never blocked.
Timestamps
Codex CLI does not include timestamps in hook events. The connector injects an ISO-8601 timestamp as each event arrives, so every event has a reliable ordering in the JSONL session file and the trace.
Trace Structure
Each trace sent to Infinium contains:
Top-Level Fields
| Field | Source | Example |
|---|---|---|
name | First user prompt (truncated to 30 chars) | "Fix the failing npm test" |
description | First user prompt (full) | "Fix the failing npm test" |
duration | Session timing | 15.2 (seconds) |
input_summary | First prompt | "Fix the failing npm test" |
output_summary | Last assistant message | "All tests pass" |
Execution Steps
Each trace includes an ordered list of steps:
| Step Type | Action | Fields |
|---|---|---|
| User prompt | user_prompt | description, input_preview, output_preview |
| Tool call | tool_use | description (e.g. "Tool: Bash"), input_preview (the command), output_preview, duration_ms |
| Tool error | tool_use with error | error.error_type = "ToolError", error.message = "Command failed", error.recoverable = true |
Environment Context
Every trace includes environment metadata:
| Tag | Value |
|---|---|
model | Codex model (e.g. gpt-5-codex) |
session_id | Codex session identifier |
working_directory | Project directory path |
permission_mode | Codex permission mode (e.g. workspace-write) |
session_source | startup or resume |
framework | "codex-cli" |
LLM Usage
On flush, the connector reads Codex’s session transcript (a JSONL file containing turn.completed entries) and attaches cumulative token usage to the trace:
| Field | Source |
|---|---|
prompt_tokens | Sum of usage.input_tokens across turn.completed entries |
completion_tokens | Sum of usage.output_tokens |
cached_input_tokens | Sum of usage.cached_input_tokens (preserved in custom_tags since the SDK has no dedicated field) |
api_calls_count | Number of turn.completed entries |
provider | "openai" |
model | From session events |
For per-turn traces, the delta against the previous snapshot is sent so totals don’t double-count.
Error Tracking
Tool failures (PostToolUse with tool_response: false) are captured as structured errors:
| Field | Description |
|---|---|
error_type | "ToolError" |
message | "Command failed" |
recoverable | true |
Data Truncation
To keep payloads manageable, the connector truncates:
- Prompt text: First 200 characters (configurable via
CONNECTOR_MAX_INPUT_PREVIEW) - Tool output preview: First 300 characters (configurable via
CONNECTOR_MAX_OUTPUT_PREVIEW) - Payload size: Progressive truncation if the total payload exceeds ~950KB
Full data is never sent — only summaries that give Maestro enough context to evaluate quality.