Skip to content

feat(agent-manager): support multiple side-panel terminals - #12633

Merged
marius-kilocode merged 5 commits into
mainfrom
implement-multiple-terminal-tabs
Jul 29, 2026
Merged

feat(agent-manager): support multiple side-panel terminals#12633
marius-kilocode merged 5 commits into
mainfrom
implement-multiple-terminal-tabs

Conversation

@marius-kilocode

Copy link
Copy Markdown
Collaborator

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 TerminalTabChrome component): 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.

Agent Manager side panel with multiple terminal tabs

Terminal tab strip in the side panel header

Side terminal tab with close button

Closes #12597

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
marius-kilocode enabled auto-merge (squash) July 29, 2026 08:36
…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
Comment thread packages/kilo-vscode/webview-ui/agent-manager/terminal/SideTerminalPanel.tsx Outdated
Comment thread packages/kilo-vscode/webview-ui/agent-manager/terminal/state.ts
Comment thread packages/kilo-vscode/webview-ui/agent-manager/terminal/SideTerminalPanel.tsx Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 2
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/terminal/SideTerminalPanel.tsx 105 "+" add button sits inside the scrollable tab strip (can scroll out of view) and non-tab elements are nested inside role="tablist"

SUGGESTION

File Line Issue
packages/kilo-vscode/webview-ui/agent-manager/terminal/state.ts 580 closeSide mutates state (removes the terminal record) before validating placement === "side"
packages/kilo-vscode/webview-ui/agent-manager/terminal/SideTerminalPanel.tsx 58 SortableSideTab duplicates the existing SortableTabContainer from TabDnd.tsx
Files Reviewed (36 files)
  • .changeset/multi-side-terminals.md
  • bun.lock
  • packages/kilo-vscode/src/agent-manager/terminal-manager.ts
  • packages/kilo-vscode/src/agent-manager/terminal-routing.ts
  • packages/kilo-vscode/tests/unit/agent-manager-terminal-routing.test.ts
  • packages/kilo-vscode/tests/unit/agent-manager-terminal-side.test.ts
  • packages/kilo-vscode/tests/unit/agent-manager-terminal-state.test.ts
  • packages/kilo-vscode/tests/visual-regression.spec.mts
  • packages/kilo-vscode/tests/visual-regression.spec.ts
  • packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/agent-manager.css
  • packages/kilo-vscode/webview-ui/agent-manager/i18n/*.ts (20 locale files)
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/SideTerminalPanel.tsx - 2 issues
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/SortableTerminalTab.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/TerminalTab.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/render.tsx
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/side.ts
  • packages/kilo-vscode/webview-ui/agent-manager/terminal/state.ts - 1 issue
  • packages/kilo-vscode/webview-ui/src/stories/agent-manager.stories.tsx

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 main

@marius-kilocode
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.
@marius-kilocode
marius-kilocode enabled auto-merge (squash) July 29, 2026 08:59
@marius-kilocode
marius-kilocode merged commit 23039c0 into main Jul 29, 2026
30 checks passed
@marius-kilocode
marius-kilocode deleted the implement-multiple-terminal-tabs branch July 29, 2026 09:06
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent Manager: support multiple terminals in the side panel

2 participants