Skip to content

fix(trail): shared hook reads single-quoted learning titles - #626

Open
anirudhkumar-nanonets wants to merge 1 commit into
mainfrom
fix/trail-hook-single-quote-titles
Open

anirudhkumar-nanonets wants to merge 1 commit into
mainfrom
fix/trail-hook-single-quote-titles

Conversation

@anirudhkumar-nanonets

Copy link
Copy Markdown
Collaborator

Moves: none of the project's metrics directly. It keeps the learnings list clean for a teammate without trail in a repo that runs Prettier, which is what NanoNets/assign#3372 rolls out. learnings_committed is the closest metric (PostHog query in daily/project.md). I didn't check its value, because this session has no Metabase access.

Why

Without trail installed, the shared hook lists .trail/learnings/ by reading each file's title: line. It stripped only double quotes. trail writes titles with JSON's double quotes, but a repo with Prettier's singleQuote: true (assign) rewrites them to single quotes. The list then showed - 'assign: one PR into dev…' with the quotes left in. NanoWarden flagged it on NanoNets/assign#3372.

What changes

  • src/claude/shim-template.ts: field() reads a single-quoted value (and its '' escape) and a double-quoted one (through JSON.parse, matching how scalar() in src/notes/notes.ts writes it). Bare values are unchanged.
  • test/claude-shim-resolve.test.ts: one test with a single-quoted title, a double-quoted title with an escaped ", and a bare one.

A repo's committed .trail/hook.cjs picks this up on the next trail init.

How I checked

  • The new test fails without the fix and passes with it.
  • tsc passes. npm test: 1441 of 1445 pass here. The 3 failures (graft-to-trail move tests in graft-to-trail, hosts-trail and upkeep-hooks) fail the same way on clean origin/main on this machine, so they come from the local setup, not this change.

🤖 Generated with Claude Code

@trailhq-graft

trailhq-graft Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

🌱 graft blast radius

1 area changed → 3 areas can be affected. 10 dependent symbols, depth 2.
Tag: @shhdwi — 4 of 4 areas

flowchart TB
  A0(("Host Integration<br/>6 symbols"))
  A1(("CLI Entry Point<br/>2 symbols"))
  A2(("Claude Setup<br/>2 symbols"))
  classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
  class A0,A1,A2 reached;
Loading
Can be affected Symbols Nearest hop Reached from
Host Integration 6 src/hosts/claude-global.ts:L1-L218 claude-global.ts — imports, depth 1 Shim Template
CLI Entry Point 2 src/cli.ts:L1-L2380 cli.ts — imports, depth 2 Shim Template
Claude Setup 2 src/claude/init.ts:L1-L273 init.ts — imports, depth 1 Shim Template
Who knows this code — 1 person across 4 areas
Area Who knows it
Shim Template · changed @shhdwi — 3 commits, last 2d ago
Host Integration · affected @shhdwi — 10 commits, last 2d ago
CLI Entry Point · affected @shhdwi — 26 commits, last yesterday
Claude Setup · affected @shhdwi — 12 commits, last 2d ago

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 @ has no GitHub handle in its commit email — tag them by hand, or add a .mailmap entry. A suggestion from history, not a CODEOWNERS rule.

All 10 dependent symbols, grouped by area

Host Integration — 6 symbols in 6 files

  • src/hosts/claude-global.ts:L1-L218 — claude-global.ts (imports, depth 1)
    30: import { hooksShim } from '../claude/shim-template.js';
  • src/hosts/codex-hooks.ts:L1-L90 — codex-hooks.ts (imports, depth 1)
    8: import { hooksShim } from '../claude/shim-template.js';
  • src/hosts/cursor-hooks.ts:L1-L115 — cursor-hooks.ts (imports, depth 1)
    27: import { hooksShim } from '../claude/shim-template.js';
  • src/hosts/init.ts:L1-L120 — init.ts (imports, depth 1)
    17: import { rememberInstall } from '../claude/shim-template.js';
  • src/hosts/plan.ts:L1-L101 — plan.ts (imports, depth 2)
  • src/hosts/retract.ts:L1-L545 — retract.ts (imports, depth 2)

CLI Entry Point — 2 symbols in 2 files

  • src/cli.ts:L1-L2380 — cli.ts (imports, depth 2)
  • src/upkeep-run.ts:L1-L123 — upkeep-run.ts (imports, depth 2)

Claude Setup — 2 symbols in 2 files

  • src/claude/init.ts:L1-L273 — init.ts (imports, depth 1)
    7: import { statuslineShim, hooksShim, rememberInstall } from './shim-template.js';
  • src/claude/hooks.ts:L1-L740 — hooks.ts (imports, depth 2)
Test signal per changed area — 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.

  • – Shim Template — 1 test file changed here: test/claude-shim-resolve.test.ts
13 test suites also reference this code

13 symbols, kept out of the diagram and the table so they cannot crowd out the areas a reviewer has to look at.

  • test/claude-hook-layers.test.ts
  • test/claude-init.test.ts
  • test/claude-shim-template.test.ts
  • test/graft-to-trail.test.ts
  • test/hosts-antigravity.test.ts
  • test/hosts-claude-global.test.ts
  • test/hosts-codex-hooks.test.ts
  • test/hosts-cursor-hooks.test.ts
  • test/hosts-init.test.ts
  • test/hosts-plan.test.ts
  • test/hosts-retract.test.ts
  • test/hosts-trail.test.ts
  • test/trail-init-layout.test.ts

graft blast · origin/main...HEAD · depth 2 · 2 changed files

Open the interactive graph → — click an area to see its dependent symbols at file:line.

github-actions Bot added a commit that referenced this pull request Oct 16, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant