feat(agent-manager): support multiple side-panel terminals - #12633
Merged
Conversation
Add a terminal tab strip to the side panel header so a context can own several side terminals: click to switch, drag to reorder, X to close a single terminal, + to open another one. The strip reuses the top tab bar's TerminalTabChrome and solid-dnd stack (with a width-pinned DragOverlay so drags track the cursor without offset). Terminal numbers fill gaps left by closed terminals, and tabs pick up live titles from OSC escape codes so the shell or running program names its own tab. Closes #12597
marius-kilocode
enabled auto-merge (squash)
July 29, 2026 08:36
chrarnoldus
approved these changes
Jul 29, 2026
…rminal-tabs # Conflicts: # packages/kilo-vscode/tests/unit/agent-manager-terminal-routing.test.ts # packages/kilo-vscode/tests/unit/agent-manager-terminal-side.test.ts
Contributor
Code Review SummaryStatus: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (36 files)
Fix these issues in Kilo Cloud Reviewed by claude-sonnet-5 · Input: 62 · Output: 19K · Cached: 2.2M Review guidance: REVIEW.md from base branch |
marius-kilocode
disabled auto-merge
July 29, 2026 08:50
Split the strip into a scrollable tab list and a fixed add-button area (mirroring .am-tab-list-wrap / .am-tab-add-wrap) so the + action never scrolls away, and scope role=tablist to the tab list so axe aria-required-children passes on the empty strip. Validate closeSide targets a live side terminal before mutating state, so a stray non-side id can no longer drop a record while leaking its backend PTY. Give SortableTabContainer a class prop and reuse it for side tabs instead of a duplicated sortable wrapper.
…' into implement-multiple-terminal-tabs
marius-kilocode
enabled auto-merge (squash)
July 29, 2026 08:59
This was referenced Jul 29, 2026
This was referenced Jul 31, 2026
t7tran
pushed a commit
to t7tran/kilocode
that referenced
this pull request
Aug 14, 2026
…12633) * feat(agent-manager): support multiple side-panel terminals Add a terminal tab strip to the side panel header so a context can own several side terminals: click to switch, drag to reorder, X to close a single terminal, + to open another one. The strip reuses the top tab bar's TerminalTabChrome and solid-dnd stack (with a width-pinned DragOverlay so drags track the cursor without offset). Terminal numbers fill gaps left by closed terminals, and tabs pick up live titles from OSC escape codes so the shell or running program names its own tab. Closes Kilo-Org#12597 * fix(agent-manager): address side terminal strip review findings Split the strip into a scrollable tab list and a fixed add-button area (mirroring .am-tab-list-wrap / .am-tab-add-wrap) so the + action never scrolls away, and scope role=tablist to the tab list so axe aria-required-children passes on the empty strip. Validate closeSide targets a live side terminal before mutating state, so a stray non-side id can no longer drop a record while leaking its backend PTY. Give SortableTabContainer a class prop and reuse it for side tabs instead of a duplicated sortable wrapper.
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.
The Agent Manager side panel could host exactly one embedded terminal per context (#12597). Running a dev server next to a log tail or a build watch meant leaving the panel for the VS Code terminal, and the panel's only terminal action was a single kill button that hid the whole panel.
This makes the side panel a multi-terminal surface. The panel header is now a tab strip that renders the same terminal tab chrome as the top tab bar (extracted into a shared
TerminalTabChromecomponent): click to switch, X to close a single terminal, middle-click works too, and a + action adds another terminal. Closing a terminal no longer hides the panel; the last close lands on the empty state. Cmd+W with a focused side terminal kills exactly that terminal instead of the whole panel.Tabs are drag-sortable via the same solid-dnd stack as the top tab bar, including a cursor-following drag overlay. The overlay is pinned to the dragged tab's measured width: solid-dnd's overlay container only enforces min-width, so long shell-set titles would overflow the narrow tab and shift the overlay's visual center off the cursor.
Terminal naming got two upgrades. New terminals receive the lowest free "Terminal N" per context (gap-filling, reservation-aware for concurrent creates and panel recreation), and tabs pick up live titles from OSC escape codes (xterm's onTitleChange), so the shell, a dev server, or vim names its own tab. Titles live in a separate signal map so OSC updates never remount xterm instances.
State stays per context (LOCAL or worktree) and all terminals stay mounted and streaming when switching worktrees or hiding the panel; terminals remain intentionally ephemeral across webview reloads.
Closes #12597