list: nest spawned lanes, and publish where each lane's chat lives - #93
Merged
Conversation
This was referenced Aug 29, 2026
…re its chat is Two facts a consumer of the listing could not get before. `chat` is the checkout whose conversation `scruff <name>` opens: the lane's own path when it has a chat, the parent's when it doesn't. That is the honest test for "this lane has no pane of its own", and it is the one a picker must filter on. `parent` cannot answer it — a lane opened with ⌘↵ from inside another lane's pane is parented to that lane exactly as a `scruff child` is, and it has a window, a panel and a chat. An empty value means undetermined and must be read as "show it". The table nests instead of dropping. A spawned lane carries its own branch and its own PR, in another repo, and closing the parent's pane does not reap it — this listing is the only place that branch surfaces once the pane is gone. So the answer to "it is noise" is where the row sits, not whether it exists. chatHome now answers a plain lane (parent == its own main checkout) before the cross-repo compare, which spent two git invocations proving what the parent pointer already said. The listing asks this of every lane. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T9Lb6mUXWEudUcs2E1B9X
…y it Follow-ups from the pre-PR assurance pass, all on the field this change exists for. `chat` is no longer `chatHome`'s answer. resume must always name a directory, so for a client whose transcripts scruff cannot probe it falls back to the parent — right when the next step is exec-ing a picker, and a lie when published: every codex or opencode lane opened from inside another pane would have answered "no chat of my own" and vanished from any picker that filtered on it, window and agent and all. jsonChat publishes the answer only where agentProbeable says one exists, and "" everywhere else. That is the value both docs already promised and nothing could produce. The table's legend claimed a nested lane "has no pane of its own", which is false for exactly the case above. It now says what parentage actually means. `chat` reaches all five SDKs, optional in the four that can express it so an older CLI still decodes — nil and "" are the same "could not tell". ai/SKILL.md gains the field and the rule, since an agent on a machine with no checkout reads only that. docs/reference.md's `parent` row said `scruff child` was the only thing that sets it; a lane opened inside a pane sets it too, and that is the whole reason `parent` cannot answer this question. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011T9Lb6mUXWEudUcs2E1B9X
JulienMartel
force-pushed
the
worktree-omit-child-lanes
branch
from
August 29, 2026 14:18
fe831a7 to
d61ef36
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two things, both about lanes that were spawned from another lane's pane.
scruff --jsongainschat— the checkout whose conversationscruff <name>opens. Equal topathwhen the lane holds its own chat, the parent's path when it doesn't, and""when scruff genuinely cannot tell. It reaches all five SDKs andai/SKILL.md.└ <name>under the lane that spawned it, with the marker explained once beneath the table.Why
A picker wants to hide lanes with no pane of their own — a
scruff childcheckout has no window, no panel and no transcript, so "opening" one starts a client where no conversation lives.parentcannot answer that: a lane opened with ⌘↵ from inside another lane's pane records the same parentage ascruff childdoes (new.go:192andcreate.go:86both write the spawning cwd), and that one is a full lane.chatis the honest test, and it is measured rather than inferred.chatis deliberately notchatHome's answer. resume must always name a directory, so for codex/opencode/pi it falls back to the parent — a good guess when the next step is exec-ing a picker, and a lie when published: every such lane would read "no chat of my own" and disappear from a picker filtering on it.jsonChatpublishes an answer only for a client scruff can actually probe, and""otherwise, which every consumer must read as show it.The listing nests rather than filters for the opposite reason: a spawned lane carries its own branch and its own PR, in another repo, and closing the parent's pane does not reap it. Once that pane is gone this listing is the only place the branch surfaces. Hiding it everywhere at once is how work goes missing.
Also:
chatHomenow answers a plain lane (parent == its own main checkout) before the cross-repo compare, which spent tworev-parsecalls proving what the parent pointer already said. The listing asks this of every lane.Verify
All five SDK suites run green locally (bun, pytest, go test, cargo test, swift test).
Watch out
""means undetermined, never "no chat". A consumer that reads it as falsy hides every lane on a machine that doesn't run Claude. Pinned bylist --json: chat is EMPTY, not a guess….chatis derived per call and flips from the parent's path to the lane's own the first time an agent leaves a conversation in that checkout.watchwill emit onechangedevent for that — a real change in the lane, not noise, and noted in SPEC §2.2.occupied_byis still absent from all five SDKLanetypes. Pre-existing, deliberately left alone here.🤖 Generated with Claude Code
https://claude.ai/code/session_011T9Lb6mUXWEudUcs2E1B9X