feat(jetbrains): move sessions to a worktree from the worktree editor - #13756
Conversation
On the base checkout's worktree editor tab (not a linked worktree), add a "Move to Worktree" entry as the first item in the session list's row menu, followed by a separator before Rename/Delete. Sessions in that tab also get the same New Worktree / Move to Worktree toolbar shown above the prompt in the tool window, with its header summarizing the uncommitted local changes a move would carry (the tab's own header already shows the branch and its PR). The dock is aligned to the same readable width as the prompt so it does not run the full editor width. WorktreeSessionEditorManager resolves once, via git worktree list, whether its directory is the repo's main working tree before the first session opens, and gates showsBranchDock/supportsNewWorktree/ supportsMoveToWorktree on that. A new project-level AgentManagerHost service bridges the editor to the Agent Manager's move/new-worktree flows, which otherwise only exist inside the tool window panel; it queues a request and activates the tool window when nothing is bound yet (e.g. a restored tab before the tool window has been created).
…he dock The base tab's dock carried a changes summary directly above the chat, duplicating reporting that belongs in the tab's own header. Drop that row entirely -- an editor-tab dock is now the action strip alone -- and put the counts where every other worktree tab shows them. The header was empty for the base checkout because dirty() excluded the main working tree, so include it: unlike stats(), which compares a worktree against the base branch and therefore has nothing to say about the checkout that branch lives on, the uncommitted comparison is local to each working tree. Unmanaged worktrees stay out of both.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (7 files)
Previous Review Summary (commit fefb512)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit fefb512)Status: 2 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (22 files)
Reviewed by grok-4.6 · Input: 77.3K · Output: 12.6K · Cached: 348.2K Review guidance: REVIEW.md from base branch |
…dings Three defects the review caught, each with a test that fails without its fix: AgentManagerHost cleared its callbacks unconditionally when a bound tool window was disposed. A plugin reload creates the replacement before disposing the old window, so the stale disposer fired last and took the live callbacks down with it. Track which bind owns them and clear only when the disposer still does. The base lookup's answer lands on the EDT after its coroutine has already finished, so a second start() -- the migration path calls one, and a tab shown twice can too -- launched a second lookup and opened the first session twice. Guard the whole gap with a resolving flag, and skip the EDT callback entirely once the editor is disposed, so a lookup that lands late cannot open sessions into a dead tab. The row menu hid Move to Worktree only for a RUNNING session, while the chat dock hides it for anything SessionState.isBusy() covers -- a session stopped on a question or a permission is as mid-turn as a running one. SessionActivityKind.busy() now states that rule where the enum can keep it exhaustive, and both surfaces read it.
|
Review feedback addressed in a1a6d4c. Both inline threads are resolved with replies; both automated findings are fixed too.
Each of the four has a test that I confirmed fails when its fix is reverted:
One incidental find while fixing the first item: the old unconditional clear was also what kept this project service clean between test methods on the reused light project.
|
Issue
Fixes #
Context
The Agent Manager's worktree editor tab for the base checkout (the main working tree, not a linked
worktree) only showed a plain session list. Moving a session into a new worktree, or starting a new
worktree, required switching to the Agent Manager tool window panel — those flows had no way to reach
the editor tab. That tab's header was also blank for the base checkout, so its uncommitted changes —
exactly what a move carries — were reported nowhere.
Implementation
WorktreeSessionEditorManagerresolves once, viagit worktree list, whether its directory is therepo's main working tree before the first session opens, and gates
showsBranchDock/supportsNewWorktree/supportsMoveToWorktreeon that. A linked worktree's own tabkeeps today's plain session view.
AgentManagerHostservice bridges the editor tab to the Agent Manager'smove/new-worktree flows, which otherwise only exist inside the tool window panel
(
AgentManagerPanel/WorktreeController). It queues a request and activates the tool window whennothing is bound yet — e.g. a tab restored before the tool window has been created.
MoveWorktreeSessionAction) as itsfirst item, followed by a separator, then the existing Rename/Delete. It hides while the session is
running, matching the chat dock's rule.
BranchDock) shownabove the prompt in the tool window, aligned to the prompt's readable width so it does not run the
full editor width. In an editor tab that dock is the action strip alone: the branch, its PR, and its
counts are the tab header's job, so
BranchDockgained aheaderflag that drops its PR row withoutletting a PR suppress the action row underneath it.
dirty()now includes the repo's main working tree, which is what makes the base tab's header reportits uncommitted counts. Unlike
stats(), which compares a worktree against the base branch and sohas nothing to say about the checkout that branch lives on, the uncommitted comparison is local to
each working tree. Unmanaged worktrees stay excluded from both.
surfaceparameter throughWorktreeController.move/AgentManagerPanel.moveso the"Continue in Worktree" telemetry event can tell the row menu, the dock, and the sidebar chat dock
apart.
Screenshots / Video
How to Test
Manual/local verification
./gradlew typecheckand./gradlew testfrompackages/kilo-jetbrains/— both pass (agent-run).Reviewer test steps
Rename/Delete.
N files +x -y) in the same place a linked worktree tab shows its own, and that clicking them opens the localdiff.
Move to Worktree strip appears above the prompt at the prompt's width — and that it carries only
those actions, with no changes summary of its own.
move into a new worktree.
toolbar above the prompt appear — unchanged behavior.
and the queued move runs).
Blocked checks and substitute verification
./gradlew runIdeSplitMode/./gradlew runIde(manual sandbox verification, reviewer test stepsabove) could not be run in this non-interactive environment. Substitute verification (agent-run):
./gradlew typecheckand./gradlew testfrompackages/kilo-jetbrains/, plus new unit/UI testsexercising the real Swing component tree, real action classes, and real git repositories
(
WorktreeSessionEditorManagerTest,WorktreeSessionEditorPanelTest,AgentManagerHostTest,BranchDockTest,SessionUiLayoutTest,WorktreeControllerTest,HistorySessionActionsTest,KiloWorktreeRpcApiImplTest,BranchLocalDiffTest).Checklist
Get in Touch