Repository navigation
feat: trail init learns from past Claude sessions, and signing in waits - #585
Conversation
… folds and publishes them
…orrects or sets a rule
… team and trail check
…RL moves only the pages
…ces via trail-cloud
…in waits behind TRAIL_CLOUD
…on starts with it
🌱 graft blast radius5 areas changed → 12 areas can be affected. 84 dependent symbols, depth 2. flowchart TB
A0(("Brain Sync<br/>25 symbols"))
A1(("Dependency Graph<br/>18 symbols"))
A2(("Impact Analysis<br/>10 symbols"))
A3(("Build And Review<br/>8 symbols"))
A4(("Telemetry<br/>6 symbols"))
AX(("7 smaller areas<br/>17 symbols"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0,A1,A2,A3,A4 reached;
classDef tail fill:#EEF2F3,stroke:#9AA4A9,stroke-width:1px,color:#3A4247;
class AX tail;
Who knows this code — 6 people across 17 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 84 dependent symbols, grouped by areaBrain Sync — 25 symbols in 12 files
Dependency Graph — 18 symbols in 10 files
Impact Analysis — 10 symbols in 7 files
Build And Review — 8 symbols in 7 files
…23 further symbols not listed. Test signal per changed area — 4 ✓ · 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.
81 test suites also reference this code87 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. |
…r not, and remind about uncommitted learnings
…and graft upgrade brings it
…il tests passing there
…ft updating (#595) * chore(package): point repository, homepage and bugs at trailhq/Trail-Code The repo was renamed. npm provenance checks the repository URL against the GitHub repo that runs the publish, case included, so a release from Actions needs the exact name. * fix(trail): tell someone typing trail when a graft-era repo can't reach it graft 0.21 and older committed hook shims that look for @nanonets/graft alone, and registered a bare `graft mcp` server. On a machine with trail and no graft, those hooks run and do nothing and the server never starts, so the session start that moves a repo to trail never happens. trail init in the repo moves it, as does a session under the hooks trail init writes to ~/.claude. For someone who has done neither, trail now prints one line in such a repo saying to run trail init there. Only for a person at a terminal; agents, pipes, CI and graft never see it. * chore: publish trail as @trailhq/trail-code The package takes the product's name; the command stays `trail` and @nanonets/graft is unchanged. Hook shims also still find @trailhq/trail, the name builds from source had before anything was published. * fix(hooks): answer each Claude Code event once, not from both copies init registers the hooks in the repo and in ~/.claude, and Claude Code runs both, so every prompt got its learnings twice and the ask to save one came twice. The repo's copy now stands down for an event the ~/.claude copy answers, when that copy can find trail. Cursor and Codex shims never do. * feat(hooks): on graft without trail, the agent tells the person how to get it A person typing graft already sees that graft is now trail. Most people only meet graft through their agent, which was told nothing. Once a week, in a repo graft set up, the session start now asks the agent to say in one line that `graft upgrade` adds trail and graft keeps working. * release: 0.22.0 * fix: hints and footers name trail's commands under trail A trail-only install has no graft binary, so a hint that told the agent to run graft ask, or a blast header tagged [graft], cost a failed tool call. The saved-tokens tally now also counts "trail saved". * docs: the Trail-code README, up to date with trail init's first read Rewrites the README around Trail-code's two parts: the graft map and learnings. Adds the how-it-works diagram and drops the old graft assets; TELEMETRY, SECURITY, CREDITS and docs/github-app.md use the new name. Matches what main does since #585: trail init reads past sessions once, corrections are saved as learnings, skills and the workspace commands are out of help and marked soon, and the save lines read "saved for your team". Says how a repo graft set up moves to trail. * docs(readme): the package is @trailhq/trail-code; claims match what ships * docs(readme): benchmark, languages, build and CLI claims match the code * fix(hosts): wire other agents under trail's names when the repo uses trail trail init wrote graft-branded files for every agent but Claude Code: AGENTS.md "## Graft", .cursor/rules/graft.mdc and the rest told the agent to run graft ask/grep/callers, which a machine with only @trailhq/trail-code doesn't have, and their MCP entries pulled npx -y @nanonets/graft. The other agents now follow the repo's name the way Claude Code's wiring does (hostWiringName, read from the repo, so a teammate on graft never flips it back). Under trail: - instruction text is graft's in trail's spelling (trailSpelling, shared with the Claude skill: graft check -> trail build --check) - owned files carry the name (.cursor/rules/trail.mdc, .adal/skills/trail/SKILL.md, .cursor/hooks/trail-hooks.cjs, ~/.gemini/skills/trail/SKILL.md) and graft's copy goes - shared files get a <!-- trail:start --> block that replaces a graft-era block in place, never beside it - MCP servers are `trail` (trail mcp / npx -y @trailhq/trail-code mcp) and graft's entry is dropped; a graft repo leaves a machine-wide trail server alone rather than add graft's beside it The session-start move to trail (upkeep toTrail) now moves these hosts too, upkeep finds them under either name, and uninstall removes either name, Cursor's hooks included. Under graft the output is unchanged. * fix(cloud): queue workspace activity only while connected, for workspace repos Every trail ask/check that showed a learning appended the search text, files and names to ~/.trail/outbox.jsonl even with no workspace connected, and connecting sent all of it, for every repo, including repos the person never picked. recordActivity now writes only while this machine is connected and only for a repo in the workspace, so nothing is queued with cloud features off. Connecting empties the outbox first, and a send drops anything from before the connection or for a repo outside the workspace (what an older trail queued). * fix(hooks): Cursor's and Codex's hooks speak trail in a repo wired for it Their hooks run the same entry as Claude's, but the name check only looked at .claude, so a repo with only Cursor or Codex on trail got graft's words. * fix(init): the dry run lists a shared AGENTS.md once * docs(readme): agent wiring outside the repo, as trail init writes it * test: the handover check clears CI, where the line stays quiet by design --------- Co-authored-by: Shrish Dwivedi <shrish@nanonets.com>
Changes from the Oct 13 review of the trail demo. Stacked on #558.
Moves:
learnings_committed, the number of clones whose committed learnings went up in the last 7 days. The PostHog query is indaily/project.md. Its value today is 0, because the event ships in this PR.What changes
trail initlearns from past sessions, with no questions asked. It reads the person's own messages in the repo's past Claude Code sessions (the checkout and its worktrees). It leaves out tool output, reminders, pasted text and headless runs. Then it asks the person's own Claude Code, headless on Sonnet 5.5, what they told Claude in more than one session. A finding is kept only if the quotes it cites really are in two or more sessions, and secrets are scrubbed. Findings are saved as learnings: the team's in.trail/learnings/, the person's own in~/.trail. This runs once per repo per machine, while the rest of init runs. On assign it read 92 sessions and saved 5 learnings, and init took 40 s.Standing learnings. Those learnings are rules for every session, not knowledge about one task, so the session-start hook lists them up front. In a new session on assign, Claude opened with "Before I build, here's what I understood" and planned a branch against
dev, both from the learnings.One kind of learning, worded by who it's for. Learnings now read "saved for your team" or "saved just for you".
trail learnandtrail skillsstill run but are out of help and the skill. Corrections are saved as learnings too.Closing lines, from Shrish's copy. After a team learning, the reply ends with "🌱 Rishabh, Anay and 56 others work in this repo. Commit what you learned and give their agents a 39k-token head start", or "📝 Committed · …" once it is committed. The skill has Claude check
git statusfirst. The names are recent authors of the same files. Team learnings left uncommitted get a once-a-day reminder at session start. The reuse credit adds minutes saved.Front matter is YAML only. gray-matter evaluated
---jsfront matter, and learnings come from teammates' pushed branches. Fixed here and on feat: trail, with learnings in .trail/, a local check, and workspaces #558.Signing in waits. The sign-in link at the end of a reply, and
login,logoutandworkspace, are off unlessTRAIL_CLOUD=1is set, or the machine is already connected.One MCP server. On a machine where graft's MCP server is installed globally,
trail initleaves it alone, so repos still wired as graft keep it. It turns graft off for that folder only, in Claude Code's per-folder setting, so a trail repo lists one server. A machine without graft getstrailglobally.graft users move to trail.
graft upgradeinstallstrailtoo (once@trailhq/trailis on npm), then runstrail initin the repo it was run from, with that repo's agents and flags.trailis on the machine. That session's refresh rewires it as trail, Claude tells the user once, and the past-session read runs in the background.GRAFT_NO_TRAIL_SWITCH=1keeps a machine on graft.graft upgradeinstead of a barenpm i -g.trailserver that runsgraft mcp. It's removed once they installtrail.Events.
learnings_committed: at session start, when more learnings are committed on HEAD than at the last session in that clone.cold_start: the result of the first-run read.Both are in
TELEMETRY.md. No messages or titles are sent.Tests
trail-cold-start, which includes atrail initend-to-end test with a stand-inclaudeon PATH, andtrail-learnings-committed.graft upgrade→trail initstep can't run end to end until@trailhq/trailis published.