From d5eb08ed425bf71b0f7147744237b707d6abd02c Mon Sep 17 00:00:00 2001 From: Hibryda Date: Fri, 6 Mar 2026 23:33:51 +0100 Subject: [PATCH] feat(v2): add permission mode passthrough and fix agent stop-on-close - Add permission_mode field to AgentQueryOptions (Rust, sidecar, bridge) flowing from controller through sidecar to SDK; defaults to bypassPermissions, supports default mode - Fix AgentPane onDestroy bug: remove stopAgent() from onDestroy (fires on layout remounts), move stop-on-close to TilingGrid onClose handler - Bundle SDK into sidecar via esbuild (remove --external flag) --- v2/bterminal-core/src/sidecar.rs | 2 ++ v2/package.json | 2 +- v2/sidecar/agent-runner-deno.ts | 7 ++++--- v2/sidecar/agent-runner.ts | 7 ++++--- v2/src/lib/adapters/agent-bridge.ts | 1 + v2/src/lib/components/Agent/AgentPane.svelte | 9 +++------ v2/src/lib/components/Layout/TilingGrid.svelte | 12 +++++++++++- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/v2/bterminal-core/src/sidecar.rs b/v2/bterminal-core/src/sidecar.rs index 6716030..006ad65 100644 --- a/v2/bterminal-core/src/sidecar.rs +++ b/v2/bterminal-core/src/sidecar.rs @@ -18,6 +18,7 @@ pub struct AgentQueryOptions { pub max_turns: Option, pub max_budget_usd: Option, pub resume_session_id: Option, + pub permission_mode: Option, } /// Directories to search for sidecar scripts. @@ -168,6 +169,7 @@ impl SidecarManager { "maxTurns": options.max_turns, "maxBudgetUsd": options.max_budget_usd, "resumeSessionId": options.resume_session_id, + "permissionMode": options.permission_mode, }); self.send_message(&msg) diff --git a/v2/package.json b/v2/package.json index b873f3d..d9812e8 100644 --- a/v2/package.json +++ b/v2/package.json @@ -12,7 +12,7 @@ "tauri:dev": "cargo tauri dev", "tauri:build": "cargo tauri build", "test": "vitest run", - "build:sidecar": "esbuild sidecar/agent-runner.ts --bundle --platform=node --format=esm --outfile=sidecar/dist/agent-runner.mjs --external:@anthropic-ai/claude-agent-sdk" + "build:sidecar": "esbuild sidecar/agent-runner.ts --bundle --platform=node --format=esm --outfile=sidecar/dist/agent-runner.mjs" }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "^6.2.1", diff --git a/v2/sidecar/agent-runner-deno.ts b/v2/sidecar/agent-runner-deno.ts index 3a4b736..15f9542 100644 --- a/v2/sidecar/agent-runner-deno.ts +++ b/v2/sidecar/agent-runner-deno.ts @@ -27,6 +27,7 @@ interface QueryMessage { maxTurns?: number; maxBudgetUsd?: number; resumeSessionId?: string; + permissionMode?: string; } interface StopMessage { @@ -51,7 +52,7 @@ function handleMessage(msg: Record) { } async function handleQuery(msg: QueryMessage) { - const { sessionId, prompt, cwd, maxTurns, maxBudgetUsd, resumeSessionId } = msg; + const { sessionId, prompt, cwd, maxTurns, maxBudgetUsd, resumeSessionId, permissionMode } = msg; if (sessions.has(sessionId)) { send({ type: "error", sessionId, message: "Session already running" }); @@ -84,8 +85,8 @@ async function handleQuery(msg: QueryMessage) { "Bash", "Read", "Write", "Edit", "Glob", "Grep", "WebSearch", "WebFetch", "TodoWrite", "NotebookEdit", ], - permissionMode: "bypassPermissions", - allowDangerouslySkipPermissions: true, + permissionMode: (permissionMode ?? "bypassPermissions") as "bypassPermissions" | "default", + allowDangerouslySkipPermissions: (permissionMode ?? "bypassPermissions") === "bypassPermissions", }, }); diff --git a/v2/sidecar/agent-runner.ts b/v2/sidecar/agent-runner.ts index 632b3c4..9589396 100644 --- a/v2/sidecar/agent-runner.ts +++ b/v2/sidecar/agent-runner.ts @@ -36,6 +36,7 @@ interface QueryMessage { maxTurns?: number; maxBudgetUsd?: number; resumeSessionId?: string; + permissionMode?: string; } interface StopMessage { @@ -60,7 +61,7 @@ function handleMessage(msg: Record) { } async function handleQuery(msg: QueryMessage) { - const { sessionId, prompt, cwd, maxTurns, maxBudgetUsd, resumeSessionId } = msg; + const { sessionId, prompt, cwd, maxTurns, maxBudgetUsd, resumeSessionId, permissionMode } = msg; if (sessions.has(sessionId)) { send({ type: 'error', sessionId, message: 'Session already running' }); @@ -93,8 +94,8 @@ async function handleQuery(msg: QueryMessage) { 'Bash', 'Read', 'Write', 'Edit', 'Glob', 'Grep', 'WebSearch', 'WebFetch', 'TodoWrite', 'NotebookEdit', ], - permissionMode: 'bypassPermissions', - allowDangerouslySkipPermissions: true, + permissionMode: (permissionMode ?? 'bypassPermissions') as 'bypassPermissions' | 'default', + allowDangerouslySkipPermissions: (permissionMode ?? 'bypassPermissions') === 'bypassPermissions', }, }); diff --git a/v2/src/lib/adapters/agent-bridge.ts b/v2/src/lib/adapters/agent-bridge.ts index c261bef..c317579 100644 --- a/v2/src/lib/adapters/agent-bridge.ts +++ b/v2/src/lib/adapters/agent-bridge.ts @@ -11,6 +11,7 @@ export interface AgentQueryOptions { max_turns?: number; max_budget_usd?: number; resume_session_id?: string; + permission_mode?: string; remote_machine_id?: string; } diff --git a/v2/src/lib/components/Agent/AgentPane.svelte b/v2/src/lib/components/Agent/AgentPane.svelte index 2c6d733..7e15322 100644 --- a/v2/src/lib/components/Agent/AgentPane.svelte +++ b/v2/src/lib/components/Agent/AgentPane.svelte @@ -1,5 +1,5 @@