You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(framework): one file per tool in the journal hook, not five tables #683
Adding a fifth tool to the run journal means writing one file, not editing five tables in three files.
The drift
The journal hook currently spreads each tool across five separate lookup tables:
Table
File
VENDOR_FIELD_BY_HOST
hooks/lib/record.js
SESSION_ID_READER_BY_HOST
hooks/lib/record.js
CWD_READER_BY_HOST
hooks/lib/repo.js
WRITTEN_PATH_EXTRACTOR_BY_HOST
hooks/lib/file-writes.js
STEP_START_BY_HOST
hooks/lib/step-starts.js
Every table is keyed by host, so none of them branches on a tool name — that part is right, and it is why the dispatcher stays tool-agnostic. What is wrong is the axis. Adding a tool touches five places. Understanding a tool means reading five places. Neither cost is visible until you try.
The CLI already solved this on its own side: cli/src/domain/tools/ai/claude.ts holds everything about Claude Code — directory, capabilities, telemetry activation, export shape — in one file implementing one contract. The hook has drifted from a pattern that exists ten metres away.
Scope
Includes: one module per host under hooks/lib/tools/, each exporting the same contract — how the session id is read, how the working directory is read, which export attribute the id joins to, how a step start is recognised, how a written path is extracted.
Includes: a dispatcher that loads the module and knows no tool name.
Includes: the constraint that makes this non-obvious — hooks/ is zero-dependency CommonJS copied verbatim into user projects with no install step, so the contract is a plain object, not a class hierarchy or anything requiring a build.
Excludes: changing what any extractor does. This is the same behaviour, on a different axis.
Excludes: the CLI side, which already has the shape being adopted.
Done When
Every per-tool fact for one host lives in one file, and a reader can answer "what does the journal know about Cursor" without opening a second.
Adding a host is adding a file plus one registry line; no existing extractor changes.
The dispatcher contains no tool name, and neither does any file outside hooks/lib/tools/.
The 159 existing hook tests pass unchanged, because behaviour did not change.
Not urgent, and worth saying why
Nothing is broken. This is the cost of the next tool, paid now instead of later. It should follow #663 rather than block it.
Activity
refactor(framework): one file per tool, not five tables
blafourcade commentedon Sep 2, 2026
Delivered by #706, squash-merged into
nextas 627408f.