Public: anyone can read this; the crew can change it.

small: The fork tree names how each fork follows its upstream in one word #11440

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Each fork in the family tree on a fork's `/forks` page now shows one word for how it follows its parent: `follows`, `proposes` or `severed`. A severed fork says `severed` rather than showing nothing. The tree root has no word, since it follows nothing.

shipped production is serving it deploy abf00b0

opened this

Each fork in the family tree on a fork's /forks page now shows one word for how it follows its parent: follows, proposes or severed. A severed fork says severed rather than showing nothing. The tree root has no word, since it follows nothing.

  • Words: FOLLOW_WORD in src/actions/follow_words.ts maps take-updates to follows, tell-me to proposes and dont-follow to severed. It sits beside followModeWords. src/spawn/follow_words.ts only knows the two chain modes, so it has no dont-follow to build on.
  • Data: lineageOf in src/core/following.ts reads every fork's stored mode in a single forkFollowModes query after the tree is built, and LineageNode gains an optional mode. A fork that never chose gets the default, proposes. There is no query per node.
  • Page: lineageCard in src/web/pages/following.ts renders the word as an outline badge next to the existing relation badge.
  • Test: the new case in test/forks-lineage-timing.test.ts sets modes on a 32-fork tree and checks the node modes and the three words in the card markup. It also checks the whole tree costs no more queries than a single leaf's view of it, and a lone leaf stays at four or fewer. It fails without the change. The related fork-tree web and timing tests, tsc --noEmit, design-lint and the gate all pass.
  • Left out: the terminal's fork tree (src/tui/screens/fork_tree.ts), the MCP fork_tree tool and the studio card still use their own words (offers, dont-follow, off). I left them alone to keep this small, but they could read FOLLOW_WORD as a follow-up.
  • No change: tree_cache.ts is about cached file listings and has nothing to do with the fork tree.
  • Push: the pre-push hook required a commit saying how to try the change, so there is an empty "Try:" commit on the branch.

To try it: open /<owner>/<fork>/forks on a fork with descendants and read the badge beside each node.

🤖 Generated with Claude Code

Closes #11421

commented

Each fork in the family tree on a fork's /forks page now shows one word for how it follows its parent: follows, proposes or severed. A severed fork says severed rather than showing nothing. The tree root has no word, since it follows nothing.

  • Words: FOLLOW_WORD in src/actions/follow_words.ts maps take-updates to follows, tell-me to proposes and dont-follow to severed. It sits beside followModeWords. src/spawn/follow_words.ts only knows the two chain modes, so it has no dont-follow to build on.
  • Data: lineageOf in src/core/following.ts reads every fork's stored mode in a single forkFollowModes query after the tree is built, and LineageNode gains an optional mode. A fork that never chose gets the default, proposes. There is no query per node.
  • Page: lineageCard in src/web/pages/following.ts renders the word as an outline badge next to the existing relation badge.
  • Test: the new case in test/forks-lineage-timing.test.ts sets modes on a 32-fork tree and checks the node modes and the three words in the card markup. It also checks the whole tree costs no more queries than a single leaf's view of it, and a lone leaf stays at four or fewer. It fails without the change. The related fork-tree web and timing tests, tsc --noEmit, design-lint and the gate all pass.
  • Left out: the terminal's fork tree (src/tui/screens/fork_tree.ts), the MCP fork_tree tool and the studio card still use their own words (offers, dont-follow, off). I left them alone to keep this small, but they could read FOLLOW_WORD as a follow-up.
  • No change: tree_cache.ts is about cached file listings and has nothing to do with the fork tree.
  • Push: the pre-push hook required a commit saying how to try the change, so there is an empty "Try:" commit on the branch.

To try it: open /<owner>/<fork>/forks on a fork with descendants and read the badge beside each node.

🤖 Generated with Claude Code

Changes requested — before the latest push

The web tree works and is cheap (one forkFollowModes query, test pins it). Two things block it. First: the terminal door is left out. The fork tree screen src/tui/screens/fork_tree.ts, the MCP fork_tree tool and the studio card still use other words (offers/dont-follow/off), so the page and the terminal now disagree about the same fork. Make them read FOLLOW_WORD from the same source, with a test on the terminal screen. Second: docs/features/fork-tree.md does not mention the word; add a line there. Also the direction is pipeline first; this is a small feature, so keep it to this and nothing more.

commented

The fork tree now says the same word, from FOLLOW_WORD in src/actions/follow_words.ts, on the web, in the terminal, in the MCP tool and on the studio card. Type check, the design lint and the fork-tree reader and web tests pass. The studio card change has no test of its own: it is covered only by the 50 tests that passed on the first run. I did not re-run those 50 after fixing the terminal test, and the repo's gate script (bun scripts/gate.ts) printed nothing, so I can't confirm it passed.

  • Terminal: src/tui/screens/fork_tree.ts prints follows, proposes or severed beside each node, and nothing for the root. test/fork-tree-reader.test.ts pins * bob/app proposes and * dan/app follows, and checks that offers no longer appears.
  • MCP fork_tree: each node gains a word field, empty for the root. I kept follow (take-updates, offers, dont-follow, autonomous) unchanged so existing clients don't break. The reader test pins word on three nodes.
  • Studio card: it shows word, and falls back to its old labels only if an older server omits it.
  • Web page: the word is now muted text in the row (src/web/pages/following.ts) instead of a second outline badge, so it sits beside the relation badge without adding noise.
  • Docs: docs/features/fork-tree.md names the three words and the new word field.

I left out anything beyond this: no change to the stored modes, and no renaming of follow.

commented

I merged main into the branch and pushed it. The type check and the three fork-tree test files pass, as do the 86 tests in the merge-touched files that passed before my fixture fix, but I did not run the whole suite. Of the checks I ran, bun scripts/design-lint.ts is clean. I did not run the gate script (bun scripts/gate.ts).

Two files conflicted, and in both I kept what each side added:

  • src/tui/screens/fork_tree.ts: a row now shows (you) for the viewer's own forks, which came from main, followed by the FOLLOW_WORD word (follows, proposes or severed) from this branch.
  • src/web/pages/following.ts: the you badge from main stays. The follow word stays as muted text beside it, not a second outline badge, as Juniper asked.

One fix came with the merge. A fixture in test/fork-tree-links.test.ts built tree nodes without the new word field. That broke the type check and printed undefined in the terminal output, so I gave those nodes word: "".

commented

The failing check was test/mcp-forks-card.test.ts. It still expected the studio card to say "offers updates" for a fork that proposes. The card now says proposes, the shared FOLLOW_WORD word this pull introduced, so I changed that expectation to proposes. The old test was out of date, not the code.

After the change that file passes (4 of 4) and bun x tsc --noEmit is clean. I have pushed it. I did not re-run any other tests.

I also searched the tests for other places that pin the old follow words ("offers updates", "takes updates", "follows on its own"). test/flows-lines.test.ts and test/family-heartbeat.test.ts contain them, but I did not open them. The check reported only the one failure, so I assume they cover a different code path.

Approved

Earlier asks are met: the word is muted text, not a second badge; the terminal, MCP tool and studio card now read FOLLOW_WORD; the severed fork says severed; the mode read is one query, pinned by the timing test; the stale card test was the test that was wrong. Docs are in docs/features/fork-tree.md, not README. Next two things: (1) Non-blocking: wrap the long lines in docs/features/fork-tree.md. (2) Non-blocking: the studio card keeps a fallback to the old labels for older servers; drop it once none remain.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs