Repository navigation
Trail-code 0.22.0: publish as @trailhq/trail-code, keep @nanonets/graft updating - #595
Conversation
…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.
…ch 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.
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.
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.
…o 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.
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".
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.
…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.
…ace 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).
…r 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.
🌱 graft blast radius5 areas changed → 8 areas can be affected. 17 dependent symbols, depth 2. flowchart TB
A0(("Pull Request Review<br/>5 symbols"))
A1(("Ask Formatting<br/>2 symbols"))
A2(("Graph Building<br/>2 symbols"))
A3(("Editor Integration<br/>2 symbols"))
A4(("Claude Initialization<br/>2 symbols"))
AX(("3 smaller areas<br/>4 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 — 4 people across 13 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 17 dependent symbols, grouped by areaPull Request Review — 5 symbols in 5 files
Ask Formatting — 2 symbols in 1 file
Graph Building — 2 symbols in 2 files
Editor Integration — 2 symbols in 2 files
Claude Initialization — 2 symbols in 2 files
MCP Server — 2 symbols in 1 file
Graph Engine — 1 symbol in 1 file
Telemetry Tracking — 1 symbol in 1 file
Test signal per changed area — 3 ✓ · 1 ⚠ · 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.
67 test suites also reference this code73 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. |
graft becomes Trail-code in 0.22.0. One build ships as two npm packages:
@trailhq/trail-code: thetrailcommand (new)@nanonets/graft: thegraftcommand, unchanged, and it keeps getting every releaseNothing about graft is removed or deprecated. npm skips deprecated versions, so deprecating graft would quietly stop updates for everyone on it.
How a graft user ends up on trail
npm i -g @nanonets/graft@latestand get 0.22.0.graft upgradeadds trail. A person typinggraftsees the same tip once a day.graft upgradeinstalls@trailhq/trail-codenext to graft..mcp.jsonswitch to the trail names, and the past-session read starts in the background.npx -y @nanonets/graftandnpx -y @trailhq/trail-codeboth pick up 0.22.0.What else changed
initregisters hooks in the repo and in~/.claude, and Claude Code ran both, so learnings arrived twice per prompt. The repo copy now stands down when the~/.claudecopy covers the same event and can find trail.@trailhq/trail-code, then@nanonets/graft. On a trail-only machine,trailwarns in a repo whose older graft hooks can't reach it and says to runtrail initthere.graftbinary, so a hint sayinggraft askcost the agent a failed tool call. The tokens-saved tally also counts "trail saved"..cursor/rules/trail.mdc), atrail:startblock that replaces graft's in shared files likeAGENTS.md, and atrailMCP server. The session-start move to trail moves them too, and their hooks speak trail. Under graft the output is byte-identical.github.com/trailhq/Trail-Code, and the README is the Trail-code one, with every claim checked against the code (two audits, ~250 claims).Tested
graft upgrade, then the repo moving to trail at the next session start.[trail]tags, nograftcommands suggested.trail init --all-agentsin a fresh repo writes no graft-named file; a repo wired bygraft init --all-agentsmoves fully at session start.After this merges: publish
@trailhq/trail-codefirst, then@nanonets/graft, both 0.22.0.🤖 Generated with Claude Code