diff --git a/packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts b/packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts index a9177fc2486..eed32f282b9 100644 --- a/packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts +++ b/packages/kilo-vscode/src/agent-manager/AgentManagerProvider.ts @@ -176,6 +176,14 @@ export class AgentManagerProvider implements vscode.Disposable { this.terminalManager.showTerminal(msg.sessionId, this.state) return null } + if (type === "agentManager.showLocalTerminal") { + this.terminalManager.showLocalTerminal() + return null + } + if (type === "agentManager.showExistingLocalTerminal") { + this.terminalManager.showExistingLocal() + return null + } if (type === "agentManager.requestRepoInfo") { void this.sendRepoInfo() return null diff --git a/packages/kilo-vscode/src/agent-manager/SessionTerminalManager.ts b/packages/kilo-vscode/src/agent-manager/SessionTerminalManager.ts index 029d04b7b04..ea8f67a82a7 100644 --- a/packages/kilo-vscode/src/agent-manager/SessionTerminalManager.ts +++ b/packages/kilo-vscode/src/agent-manager/SessionTerminalManager.ts @@ -53,6 +53,32 @@ export class SessionTerminalManager { this.showOrCreate(sessionId, cwd, name) } + /** + * Show (or create) a terminal for the local workspace (no session required). + * Used when the user triggers a terminal in local mode without an active session. + */ + private static readonly LOCAL_KEY = "__local__" + + showLocalTerminal(): void { + if (this.showExisting(SessionTerminalManager.LOCAL_KEY, false)) return + + const cwd = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath + if (!cwd) { + this.log("showLocalTerminal: no workspace folder open") + vscode.window.showWarningMessage("Open a folder to use the local terminal") + return + } + + this.showOrCreate(SessionTerminalManager.LOCAL_KEY, cwd, "Agent: local") + } + + /** + * Show the existing local terminal if one was previously created (used on context switch). + */ + showExistingLocal(): boolean { + return this.showExisting(SessionTerminalManager.LOCAL_KEY) + } + /** * Show the terminal for a session if it already exists (used when switching sessions). * Returns true if the terminal was shown, false if no terminal exists for the session. diff --git a/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts b/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts index 4835e88adb9..6996f868220 100644 --- a/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts +++ b/packages/kilo-vscode/tests/unit/agent-manager-arch.test.ts @@ -158,6 +158,8 @@ describe("Agent Manager Provider — onMessage routing", () => { "agentManager.closeSession", "agentManager.configureSetupScript", "agentManager.showTerminal", + "agentManager.showLocalTerminal", + "agentManager.showExistingLocalTerminal", "agentManager.requestRepoInfo", "agentManager.requestState", "agentManager.setTabOrder", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx index 002fd935ce7..e222b646249 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx @@ -579,9 +579,11 @@ const AgentManagerContent: Component = () => { } else if (fallback && isPending(fallback.id)) { setActivePendingId(fallback.id) session.clearCurrentSession() + vscode.postMessage({ type: "agentManager.showExistingLocalTerminal" }) } else { setActivePendingId(undefined) session.clearCurrentSession() + vscode.postMessage({ type: "agentManager.showExistingLocalTerminal" }) } } @@ -612,6 +614,7 @@ const AgentManagerContent: Component = () => { else if (msg.action === "showTerminal") { const id = session.currentSessionID() if (id) vscode.postMessage({ type: "agentManager.showTerminal", sessionId: id }) + else if (selection() === LOCAL) vscode.postMessage({ type: "agentManager.showLocalTerminal" }) } else if (msg.action === "toggleDiff") { setDiffOpen((prev) => !prev) } else if (msg.action === "newTab") handleNewTabForCurrentSelection() @@ -1713,6 +1716,7 @@ const AgentManagerContent: Component = () => { onClick={() => { const id = session.currentSessionID() if (id) vscode.postMessage({ type: "agentManager.showTerminal", sessionId: id }) + else if (selection() === LOCAL) vscode.postMessage({ type: "agentManager.showLocalTerminal" }) }} /> diff --git a/packages/kilo-vscode/webview-ui/src/types/messages.ts b/packages/kilo-vscode/webview-ui/src/types/messages.ts index d7658473769..668d3755a2d 100644 --- a/packages/kilo-vscode/webview-ui/src/types/messages.ts +++ b/packages/kilo-vscode/webview-ui/src/types/messages.ts @@ -1112,6 +1112,16 @@ export interface ShowTerminalRequest { sessionId: string } +// Show terminal for the local workspace (when no session is active) +export interface ShowLocalTerminalRequest { + type: "agentManager.showLocalTerminal" +} + +// Show existing local terminal when switching to local context (no-op if none exists) +export interface ShowExistingLocalTerminalRequest { + type: "agentManager.showExistingLocalTerminal" +} + /** * Maximum number of parallel worktree versions for multi-version mode. * Keep in sync with MAX_MULTI_VERSIONS in src/agent-manager/constants.ts. @@ -1264,6 +1274,8 @@ export type WebviewMessage = | RequestStateMessage | ConfigureSetupScriptRequest | ShowTerminalRequest + | ShowLocalTerminalRequest + | ShowExistingLocalTerminalRequest | CreateMultiVersionRequest | SetTabOrderRequest | SetSessionsCollapsedRequest