Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/sync-inspector-width.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"kilo-code": patch
---

Persist the Agent Manager inspector width and share it between the terminal and diff viewer.
Persist the Agent Manager inspector width, share it between the terminal and diff viewer, and keep resizing responsive.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import { clampPanelWidth, maxPanelWidth, minPanelWidth } from "../../webview-ui/

const css = readFileSync(resolve(import.meta.dir, "../../webview-ui/agent-manager/agent-manager.css"), "utf8")
const app = readFileSync(resolve(import.meta.dir, "../../webview-ui/agent-manager/AgentManagerApp.tsx"), "utf8")
const terminal = readFileSync(
resolve(import.meta.dir, "../../webview-ui/agent-manager/terminal/TerminalTab.tsx"),
"utf8",
)

test("xterm owns the padding used by FitAddon", () => {
const host = css.match(/\.am-terminal-host\s*\{([^}]*)\}/)?.[1]
Expand All @@ -23,6 +27,18 @@ test("uses one persisted width for the diff and terminal inspector", () => {
expect(app).not.toContain("terminalWidth")
})

test("limits inspector layout updates during resize", () => {
expect(app).toContain("SIDE_RESIZE_INTERVAL_MS = 32")
expect(app).toContain("time - sideResizeTime < SIDE_RESIZE_INTERVAL_MS")
})

test("does not refit hidden terminal buffers during resize", () => {
const callback = terminal.match(/const ro = new ResizeObserver\(\(\) => \{([\s\S]*?)\n \}\)/)?.[1]
expect(callback).toBeDefined()
expect(callback).toContain("if (!props.active) return")
expect(callback!.indexOf("if (!props.active) return")).toBeLessThan(callback!.indexOf("fit.fit()"))
})

test("clamps the restored inspector width to the shared layout bounds", () => {
expect(clampPanelWidth(undefined, 1200)).toBe(600)
expect(clampPanelWidth(500, 1200)).toBe(500)
Expand Down
12 changes: 10 additions & 2 deletions packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ type SidePanel = "diff" | "pr" | "terminal" | null
const isMac = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.userAgent)
// Fallback keybindings before extension sends resolved ones
const MAX_JUMP_INDEX = 9
const SIDE_RESIZE_INTERVAL_MS = 32

const defaultBindings: Record<string, string> = {
previousSession: isMac ? "⌘⌥↑" : "Ctrl+Alt+↑",
Expand Down Expand Up @@ -308,6 +309,7 @@ const AgentManagerContent: Component = () => {
let pendingSidebarWidth: number | undefined
let sideRaf: number | undefined
let pendingSideWidth: number | undefined
let sideResizeTime = 0

const [history, setHistory] = createSignal(false)
const [sidePanel, setSidePanel] = createSignal<SidePanel>(null)
Expand All @@ -323,10 +325,16 @@ const AgentManagerContent: Component = () => {
const resizeSide = (width: number) => {
pendingSideWidth = clampPanelWidth(width, window.innerWidth)
if (sideRaf !== undefined) return
sideRaf = requestAnimationFrame(() => {
const flush = (time: number) => {
if (time - sideResizeTime < SIDE_RESIZE_INTERVAL_MS) {
sideRaf = requestAnimationFrame(flush)
return
}
sideRaf = undefined
sideResizeTime = time
setPanelWidth(pendingSideWidth!)
})
}
sideRaf = requestAnimationFrame(flush)
}
const showSideTerminal = () => {
setHistory(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,9 @@ export const TerminalTab: Component<Props> = (props) => {
open(url)
}

// Resize: fit on any host size change and forward new cols/rows to
// the backend PTY. Debounced because a user drag can fire dozens of
// resize events per second.
// Resize the visible terminal and forward new cols/rows to the backend
// PTY. Hidden terminals refit when activated, avoiding scrollback reflow
// for every mounted terminal during an inspector drag.
let resizeTimer: ReturnType<typeof setTimeout> | undefined
let lastCols = term.cols
let lastRows = term.rows
Expand All @@ -395,6 +395,7 @@ export const TerminalTab: Component<Props> = (props) => {
})
}
const ro = new ResizeObserver(() => {
if (!props.active) return
try {
fit.fit()
} catch (err) {
Expand Down
Loading