Adding an agent
Every feature in Turnlog is built on the normalized layer, never on a vendor’s file format. Search, replay, spend, lenses, export and MCP all read one record shape. So an adapter is the whole job: land it and the rest works.The shape
An adapter is a pure function:NormalizedRecord carries what every agent has in common — identity and threading
(uuid, parentUuid), kind, role, timestamp, tool name and pairing id, error flag,
model, token counts, cwd, git branch, files touched, searchable text, and the original
line verbatim.
Anything the agent does not record is null. Reporting a gap honestly is correct;
inventing a value is not.
The rules
Never crash, never drop. An unrecognized record becomeskind: 'unknown' with its raw
JSON kept. A malformed line must not lose the rest of the file.
Pure and synchronous. No I/O, no clock, no randomness — that is what makes golden
snapshots meaningful.
Stream, never slurp. Files are read line by line with byte offsets so indexing can
resume mid-file.
Text is for search. Put in what a person would search for. Leave out what would
drown the index — a giant instructions blob belongs in raw, not in text.
The checklist
- Corpus fixtures — real-shaped sample files, added to
fixtures/. - The adapter — a pure function in
src/parser/adapters/. - Discovery — where the agent’s logs live, skipped silently when absent.
- Goldens —
npm run golden:update, then read the diff. That is what it is for. - A version constant — per agent, so bumping one does not reindex the others. Bump it whenever normalization output changes; it forces a re-index that backfills the change.
- Identity — one
--agent-*colour token, one brand mark, one registry entry.