Repository navigation
Make trail work in Claude Desktop and Codex - #733
anirudhkumar-nanonets wants to merge 2 commits into
Conversation
🌱 graft blast radius4 areas changed → 5 areas can be affected. 20 dependent symbols, depth 2. flowchart TB
A0(("Host Registry<br/>6 symbols"))
A1(("Installation Paths<br/>5 symbols"))
A2(("Note Persistence<br/>4 symbols"))
A3(("CLI Entry Point<br/>3 symbols"))
A4(("Session Learning<br/>2 symbols"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2,A3,A4 reached;
Who knows this code — 1 person across 9 areas
Ownership is git history over each area's own files, weighted towards recent work (120-day half-life). Merge commits and bots are dropped, and you are dropped from your own PR. A name with no All 20 dependent symbols, grouped by areaHost Registry — 6 symbols in 6 files
Installation Paths — 5 symbols in 2 files
Note Persistence — 4 symbols in 2 files
CLI Entry Point — 3 symbols in 2 files
Session Learning — 2 symbols in 1 file
Test signal per changed area — 3 ✓ · 1 ✗Reached = a node under a test path has a resolved edge into the changed symbol. It undercounts anything called indirectly — through a CLI, a spawned process or a dynamic import — so read a low ratio as “look here”, never as a coverage gate.
23 test suites also reference this code31 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.
Open the interactive graph → — click an area to see its dependent symbols at file:line. |
Issue: Until its hooks were trusted in
/hooks, Codex never heard how to save a learning. Asked to save one, it edited a teammate's learning file by hand. In Claude Desktop worktree sessions, editing a file never brought its learnings, and neither app was counted as its own host.Why: AGENTS.md only covered code search, and
trail notewrote to~/.trail(which Codex's sandbox can't write) before the repo. Desktop's hooks get the main checkout as the project, so a worktree file's path never matched a learning.agent_hosthad no value for either app, and hook events from Codex saidcli.Fix: AGENTS.md gets a Learnings part. A repo learning saves even when
~/.trailcan't be written. Touch learnings take the file's path in its own checkout. A hook puts all its events, and the trail commands it starts, down to the payload's host, now includingcodexandclaude-desktop.Moves: active users by host, PostHog Postgres (Metabase db 11,
posthog_event_full_view), distinct installs over the last 7 days with arepo_seen,query,note_savedorlearnings_committedevent,cli_name = 'trail', byagent_host. On 2026-10-29: claude-code 1,157 · cli 677 · mcp 262 · claude-desktop and codex 0 (the values don't exist before this PR).What works where (checked with real sessions on 2026-10-30)
agent_hostclaude-code→claude-desktopcli→codextrail init)trail ask)Codex: five real sessions
Codex 0.162 (the CLI inside ChatGPT.app, which the app runs as its app-server), default model,
workspace-writesandbox, each run in its own home outside/tmpso the sandbox can't write it. "Before" is trail 0.26.0 as installed; "after" is this branch. The repo had one committed learning (money stays in integer cents). Prompt: addapplyDiscountwith a test; "half-cents always round down".trail asktrail asktrail note: turned away for naming no file, then saved inside the sandbox--dangerously-bypass-hook-trust)codex(hook_ms ×3, prompt-hookask, stop-hookcheck,repo_seen,learnings_committed); in D they saidcliCodex's shell sets
CODEX_THREAD_ID,CODEX_SESSION_ID,CODEX_SANDBOX(seen), sodetectHostreads those. But a trail command Codex runs itself can't write the event queue under~/.graft, so those send nothing either way.Claude Desktop: this session
The transcript and trail's state files show SessionStart, UserPromptSubmit, PostToolUse, PostToolUseFailure, PreToolUse on Bash and Stop all ran; the trail skill and MCP server loaded. PreToolUse on Edit ran but never found a learning: in a worktree session
CLAUDE_PROJECT_DIRis the main checkout, solearningsOnTouchsaw.claude/worktrees/<name>/src/...(same cause #738 fixed for overlap warnings).Changes
src/hosts/instructions.ts: under trail, the AGENTS.md block (also GEMINI.md, Copilot) ends with### Learnings: where they are, read them viatrail ask, save withtrail note, commit them, runtrail check. Graft's text is unchanged.src/notes/notes.ts:writeNotefalls back torepoPlacewhenensureRepoHomethrows and the learning goes in the repo.--personalstill needs~/.trail.src/claude/hooks.ts:learningsOnTouchtakes the file's path relative tocheckoutRoot(dirname(file)); learnings and session state still come from the project dir, so nothing is shown twice. The hook setsTRAIL_AGENT_HOSTfrom the payload's host.src/telemetry/track.ts,contract.ts,TELEMETRY.md:agent_hostaddsclaude-desktop(CLAUDE_CODE_ENTRYPOINT === 'claude-desktop') andcodex(Codex's shell variables, orTRAIL_AGENT_HOSTfrom a hook). Every env value is only compared against fixed names; none travels.Tests
TRAIL_AGENT_HOST, a Codexlearnings_committedcarryingcodex, the trail AGENTS.md text,writeNotewith an unwritable home, and a learning reaching an edit in a linked worktree while the project dir is the main checkout (fails without the fix).origin/mainhere (they depend on a realtrailon this machine's PATH).tsc --noEmitclean.trail check
Two flags, both word matches:
TELEMETRY.md:40against "Claude ran with the real HOME…" (Oct 27, about tests loading the real~/.claude/settings.json), andsrc/claude/hooks.ts:177against thereplaces:-holds-ids learning (Oct 22): that line has.replace(and the words "file" and "name", and touches no learning field.Follow-ups
.trail/learnings/(trail-cloud).checkoutRootimport tohooks.ts; Init's always-follow offer says what the rule does #724, Ask once whether a reused learning helped #727, Stamp telemetry events with the time they're sent #728 editTELEMETRY.md/contract.ts/track.tsin other hunks.🤖 Generated with Claude Code