Adapters translate runtime-specific trace records into TraceCC canonical events.
When tracecc has central config in ~/.TraceCC/config.toml, adapter
selection can be guided by configured trace roots before content probing runs.
The current implementation ships three adapters:
claudecodexhermes
It parses current Claude Code JSONL traces incrementally and emits canonical events into the compile pipeline.
An adapter must be able to:
- identify whether it can parse a source
- parse input incrementally
- emit canonical events in source order
- expose a rule version for bundle provenance
The Claude adapter currently handles:
- line-by-line JSONL parsing
- auto-detection based on current Claude Code record fields such as
sessionId,message.content, andpermissionMode - dropped/noise record filtering
- hidden preservation of startup metadata such as permission mode and attachments
- assistant
message.content[]lowering into thinking, assistant text, tool calls, and artifacts - XML-ish harness markup stripping
- ANSI/control character stripping
- readable tool input normalization
- compaction boundary recognition
- pairing
tool_useblocks with latertool_resultwrappers - artifact reference extraction for base64-backed document and image records
The Codex adapter currently handles:
- current Codex desktop session JSONL detection via
session_meta/response_itemrecords - session metadata capture from
session_metaandturn_context - project stamping from Codex session
cwd, since Codex stores sessions in date buckets instead of project-specific directories - project-aware filtering when a configured Codex trace root is compiled from inside a known project root, so mixed same-day sessions do not bleed across projects
- user message extraction from
response_item.message - assistant commentary/final message extraction from
event_msg.agent_message - tool-call lowering from
response_item.function_call - tool-result pairing by
call_id exec_commandresult extraction fromevent_msg.exec_command_end- generic tool output extraction from
response_item.function_call_output - noisy duplicate suppression where Codex logs both an event stream and a response-item mirror
The Hermes adapter handles traces from the Hermes Agent, stored in ~/.hermes/sessions/ as JSONL files:
- auto-detection via
session_metarecords withplatformandtoolsfields (distinguishing from Codex which usesoriginatorinstead) - session metadata capture from
session_metaincluding platform and model - user message extraction from
role: "user"records - assistant text and reasoning extraction from
role: "assistant"records, with reasoning emitted as thinking events - tool-call lowering from the
tool_callsarray on assistant records (OpenAI function-calling format withid,function.name,function.arguments) - tool-result pairing by
tool_call_idfromrole: "tool"records - tool error detection for results containing "error", "failed", or "permission denied"
Hermes sessions are flat (not organized by project directory), so the trace root uses no project_mode.
internal/adapter/util.go provides common helpers used by all adapters:
SanitizeText— strips control characters and normalizes line endingsParseTimestamp— parses RFC3339, RFC3339Nano, andYYYY-MM-DD HH:MM:SSstrings, or Unix epoch floatsMergeAttrs— merges two attribute mapsCloneEvent— shallow-copies a canonical event with a fresh attribute mapReadableParts— sanitizes text and wraps it as a singleTextPartFirstString— returns the first non-empty value from a record for a list of keysValueMap,ValueSlice,ValueString— safe type assertions for parsed JSON valuesCoalesce— returns the first non-empty string
Adapters that need additional sanitization (e.g. ANSI or XML stripping) layer their own transforms on top of SanitizeText.
internal/policy/noise/noise.go provides a single IsDropped function used during adapter parsing to skip records that carry no semantic content. A record is dropped if:
- it has a
dropped: trueattribute, or - its record type is one of:
ping,heartbeat,noop,debug,trace
Adapters should normalize into a shape that is stable for:
- IR construction
- line assignment
- search
- cross-runtime rendering
That means runtime-specific quirks should stay in the adapter layer whenever possible.
The package layout is designed to support additional adapters later, such as:
- Responses-style traces
- OTEL-derived traces
Those should target the same canonical event model instead of introducing renderer-specific branches.