(changes): list the worktrees of a session's subagents in its Changes panel (#303) - #398
Conversation
Refs #303. A subagent working in a worktree of its own has its path in its meta.json sidecar. The target resolver now accepts sub:<parent>:<agent> for the read-only status and diff IPCs only, validates both parts before any disk access, reports a removed worktree, and shares the parent's target when the agent records none. The panel is not wired to it yet.
|
Reviewing |
|
Adversarial review at |
… panel Closes #303. The parent session's panel now shows, after its own rows, one group per subagent working in a worktree of its own, headed by the agent's name and branch. Rows open as read-only diffs through the sub: id; edit, save, locate and watch still refuse it. A UNC worktree path in a sidecar is refused, and a missing or unparsable sidecar is a distinct reason instead of the parent's rows.
|
Reviewing |
|
Re-review at |
Refs #303. The cap of 8 now counts groups that have changes, and the panel says how many it left out. Sidecars are read asynchronously, a few at a time, and cached; git status runs three at a time over the 24 newest worktrees. A subagent worktree must share the session's git common dir before git reads it (listing, status and diff). An extended-length drive path is normalised instead of refused as UNC.
|
Reviewing |
|
Re-review at |
…re the caches Refs #303. A subagent worktree is listed and read only when its .git file names a directory under the session repository's worktrees directory, read on every pass; the parent's common dir, removed worktrees and sidecar answers are cached with a lifetime instead of for good. Git runs in a subagent worktree with core.fsmonitor off. The scan bound counts scanned candidates, the ones not scanned are included in the omitted note, and 'newest' is by parsed time.
|
Re-review at |
# Conflicts: # CHANGELOG.md # main.js
Closes #303.
What changed
A session's Changes panel now also lists the changes in the worktrees its subagents work in. For each subagent whose sidecar (
agent-<id>.meta.json) records aworktreePathdistinct from the session's own directory, the list shows a header (the agent's description, else its type, else its id, then its branch) followed by that worktree's changed files. Rows open as read-only diffs through the existinggit-changes-diffpath.Main side:
resolveGitChangesTargetacceptssub:<parent>:<agent>only with{allowSubagent: true};git-changes-statusandgit-changes-diffopt in, so edit, save, locate, watch, the panel shell and the terminal path links keep refusing it. Both id parts are validated before any dependency runs...segments, not start with two separators (UNC); an extended-length drive path is normalised, and exist. A removed worktree isreason: 'worktree-removed'.reason: 'no-worktree-recorded'; the parent's rows are never shown as the agent's. A sidecar that records noworktreePathmeans the agent shares the parent's directory.listSubagentWorktrees(async, local parents only): sidecars read asynchronously, 8 at a time, and cached per path; only worktrees that exist, differ from the parent's cwd (case-insensitive on Windows) and are linked worktrees of the parent's repository (their.gitfile, read every pass, names a directory under the parent's<common dir>/worktrees/) are kept; answers are cached with lifetimes (5 min for a recorded worktree, 30 s for removed ones and the parent's common dir, 10 s for an unreadable sidecar); the 24 newest are scanned and the rest counted.collectSubagentChangesrunsstatus()3 at a time and keeps the groups with files: the cap of 8 applies to those, and the rest are counted (+N more subagent worktrees not shown). The result issubagentsandsubagentsOmittedon the status reply, computed on the refresh the panel already does; no new watcher.git-changes-statusandgit-changes-diffapply the same repository test to asub:target, so git never runs in a worktree of another repository, and every git run in a subagent worktree uses-c core.fsmonitor=false.Renderer (
public/file-panel.js): group header and rows; a subagent row's click skips the editable content pair and diffs through thesub:id; selection and untracked counts match on(subSessionId, path). Each group is capped at 100 rows.Divergence from the issue: the issue prefers a selectable subagent with its own panel over a grouped parent panel and says not to do both. The grouped parent panel was chosen on review; the
sub:resolution is shared by both shapes. Subagents with a removed worktree are omitted from the list rather than shown with an error. The parent's own cwd keeps accepting a UNC path (not changed here).Tests
test/git-changes-target.test.js: shape validation, refusal before any disk access, worktree resolution, shared cwd, removed worktree, unsafe and UNC paths, missing sidecar reason, listing (labels, filtering, bound), collecting.test/git-changes-file.test.js: only status and diff opt in; status handler wiring.test/dom-file-panel-changes.test.js(jsdom): no group when none, group header and rows apart from parent rows, summary with an empty own directory, read-only diff through the sub id with no editor or watch, selection and counts not leaking onto the parent's same-path row, diff error shown.CI
The failure of
test (20, ubuntu-latest)on 1f6222d (run 36907042297) isnpm error HTTPError: Response code 500during dependency install, before any test ran; no test change addresses it.Not verified
No live run against a real worktree-isolated subagent or in the running app; behaviour is covered with injected dependencies and jsdom. The recorded
worktreePathis trusted like the session's own recorded cwd.