Repository navigation
Conversation
…te skeleton (trailhq#433) A workspace parent's graft/ holds only workspace.json; the graphs live in each child's own graft/. Three readers at the parent assumed a graph of its own. The statusline fell from a zeroed, dirty cache (what the hooks write on the first edit) to a wiring.json the parent never has, and said "not built" right after a successful build. The Stop-hook sync rebuilt correctly and then read the parent's wiring to fill the counts — null, so it left dirty set forever and the cache at all zeros. And `skeleton` was the one query command not federated, so it answered "no wiring graph" for a repo just built. computeWorkspaceStats sums each built child's wiring.json, read at <child>/graft/ with no override, exactly as the federated commands do. It stays off loadWorkspaceGraphs on purpose: the statusline is a pure read on the render path and that module pulls the whole ask engine in with it. resolveStats merges the sum over the zeroed cache so the live dirty state survives; runSync uses the same sum when there is no parent wiring, so the cache gets real counts and dirty clears. The single-repo path is unchanged. federateSkeleton routes `<child>/path` to that child directly, the shape every federated pointer is printed in, and looks a bare path or basename up in every child, which must land in exactly one. Wired into the CLI and the MCP graft_file_api tool like the other federated commands.
…is not At a workspace parent the bar sums the built children (trailhq#433), so a child that has not been built yet drops out of the counts with no hint. Show `workspace K/N repos built` (amber) before the counts when K < N, and nothing extra when every child is built or in a plain repo. The count is read on every render rather than taken from the sum: once the Stop-hook sync writes real counts into the parent's cache, the statusline reads that cache and no longer sums the children, and a child can still be unbuilt then. It only stats each child's wiring.json.
🌱 graft blast radius4 areas changed → 1 area can be affected. 1 dependent symbol, depth 2. flowchart TB
A0(("MCP Server<br/>1 symbol"))
classDef reached fill:#D9EDF3,stroke:#3AA7C9,stroke-width:1.5px,color:#0E313C;
class A0 reached;
Who knows this code — 2 people across 5 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 1 dependent symbol, grouped by areaMCP Server — 1 symbol in 1 file
Test signal per changed area — 1 ✓ · 2 ✗ · 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.
5 test suites also reference this code5 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. |
Depends on #445 — stacked on its head; only the last commit (0eb27fe) is new. I'll rebase onto main once #445 merges.
Follow-up to #445, as suggested by @shhdwi on #476: the
workspace 1/2 repos builtlabel, on top of #445's workspace stats.What
At a workspace parent, #445 sums the children that have a graph, so a child that hasn't been built yet drops out of the counts without any sign. When some listed children are unbuilt, the bar now says so:
When every child is built, and in a plain repo, the line is the same as before.
How
src/claude/stats.ts:workspaceCoverage(dir)returns{ built, total }, or null whendirisn't a workspace parent. A child counts as built if its<child>/graft/.graph/wiring.jsonexists. It only checks that the file exists and doesn't parse it, since this runs on every render.computeWorkspaceStatsnow uses the same two small helpers (workspaceChildren,childWiringPath), with no change in behavior.src/claude/statusline.ts:main()callsworkspaceCoverageon every render, not just whenresolveStatsfalls through to the sum. After the Stop-hook sync writes real counts into the parent's cache,resolveStatsreturns that cache and stops summing, but a child can still be unbuilt at that point.src/claude/format.ts:renderStatuslinetakes an optionalctx.workspace. The amber segment is added only whenbuilt < total.Tests
test/claude-format.test.ts: the label shows for 1/2. It doesn't show for 2/2 or for a plain repo.test/claude-statusline.test.ts:workspaceCoveragegives 1/2 and 2/2, and null for a plain repo. A spawnedmain()at a workspace parent showsworkspace 1/2 repos built, both before and after a sync-style cache is written.format.tsmakes both new rendering tests fail. Reverting only themain()wiring makes the spawned test fail. Gating the label on an empty cache makes the "after the sync" assertion fail.tsc --noEmitis clean. The fullnpm testrun gives the same failure set before and after this change on my Windows machine. That set is 110 failures, environmental: most trace to tree-sitter-kotlin having no native build here (no MSVC). The statusline and format suites pass in full. I haven't run the full suite on Linux.This change was written with an AI coding agent and reviewed by me.