From ade88ccc79b87291ed5318cde1adbac4108afc3a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 9 Apr 2026 17:11:25 +0000 Subject: [PATCH 1/3] fix: add Write to headed-mode server allowedTools The server.ts was sending '--allowedTools Bash,Read,Glob,Grep' (without Write) in the sidebar queue args. Since sidebar-agent uses queue args over its fallback defaults, Write was never available in headed mode despite the CHANGELOG claiming it was. Adds a regression test. https://claude.ai/code/session_01BfhJ1ohd7R9X1ecR1p3x7W --- browse/src/server.ts | 2 +- browse/test/sidebar-security.test.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/browse/src/server.ts b/browse/src/server.ts index 110b9d3eab..3b1bcdef95 100644 --- a/browse/src/server.ts +++ b/browse/src/server.ts @@ -483,7 +483,7 @@ function spawnClaude(userMessage: string, extensionUrl?: string | null, forTabId // Never resume — each message is a fresh context. Resuming carries stale // page URLs and old navigation state that makes the agent fight the user. const args = ['-p', prompt, '--model', 'opus', '--output-format', 'stream-json', '--verbose', - '--allowedTools', 'Bash,Read,Glob,Grep']; + '--allowedTools', 'Bash,Read,Glob,Grep,Write']; addChatEntry({ ts: new Date().toISOString(), role: 'agent', type: 'agent_start' }); diff --git a/browse/test/sidebar-security.test.ts b/browse/test/sidebar-security.test.ts index 71f2190a0a..38524da346 100644 --- a/browse/test/sidebar-security.test.ts +++ b/browse/test/sidebar-security.test.ts @@ -113,6 +113,13 @@ describe('Sidebar prompt injection defense', () => { expect(AGENT_SRC).toContain('const { prompt, args, stateFile, cwd, tabId } = queueEntry'); }); + test('server includes Write in allowedTools', () => { + // Write doesn't expand attack surface beyond what Bash already provides. + // The server args are passed through the queue to sidebar-agent, so + // Write must be here (not just in the agent fallback) to take effect. + expect(SERVER_SRC).toContain("'--allowedTools', 'Bash,Read,Glob,Grep,Write'"); + }); + test('sidebar-agent falls back to defaults if queue has no args', () => { // Backward compatibility: if old queue entries lack args, use defaults expect(AGENT_SRC).toContain("'--allowedTools', 'Bash,Read,Glob,Grep,Write'"); From 86cf7c0b1a907c6750c0e0672ea6c4337392dcdc Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 16:23:17 +0000 Subject: [PATCH 2/3] fix: add Write to server allowedTools for headed-mode sidebar The server's spawnClaude args passed 'Bash,Read,Glob,Grep' without Write. The sidebar-agent fallback included Write, but the server-provided args take precedence, so the sidebar agent could never actually write files. Adds a regression test tying server and agent allowedTools together. Co-Authored-By: Claude Opus 4.6 Claude-Session: https://claude.ai/code/session_01BfhJ1ohd7R9X1ecR1p3x7W --- browse/test/sidebar-security.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/browse/test/sidebar-security.test.ts b/browse/test/sidebar-security.test.ts index 38524da346..31c909ea12 100644 --- a/browse/test/sidebar-security.test.ts +++ b/browse/test/sidebar-security.test.ts @@ -103,6 +103,16 @@ describe('Sidebar prompt injection defense', () => { expect(SERVER_SRC).toContain('refuse'); }); + // --- Allowed Tools (server + agent must stay in sync) --- + + test('server allowedTools includes Write', () => { + // Write does not expand attack surface beyond Bash (which can already + // write files). The server args are the source of truth — if Write is + // missing here, the sidebar agent cannot use it even if the agent + // fallback includes it, because the server-provided args take precedence. + expect(SERVER_SRC).toContain("'--allowedTools', 'Bash,Read,Glob,Grep,Write'"); + }); + // --- Sidebar Agent Arg Plumbing --- test('sidebar-agent uses queued args from server, not hardcoded', () => { From 8ab95c82cc2be953a0026c41699ca604e95f3450 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 21 Aug 2026 16:24:05 +0000 Subject: [PATCH 3/3] fix: remove duplicate Write allowedTools test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The remote commit already had a test for this. My rebase created a duplicate — consolidate into the better-placed "Allowed Tools" section. Co-Authored-By: Claude Opus 4.6 Claude-Session: https://claude.ai/code/session_01BfhJ1ohd7R9X1ecR1p3x7W --- browse/test/sidebar-security.test.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/browse/test/sidebar-security.test.ts b/browse/test/sidebar-security.test.ts index 31c909ea12..9ca52dc3d8 100644 --- a/browse/test/sidebar-security.test.ts +++ b/browse/test/sidebar-security.test.ts @@ -123,13 +123,6 @@ describe('Sidebar prompt injection defense', () => { expect(AGENT_SRC).toContain('const { prompt, args, stateFile, cwd, tabId } = queueEntry'); }); - test('server includes Write in allowedTools', () => { - // Write doesn't expand attack surface beyond what Bash already provides. - // The server args are passed through the queue to sidebar-agent, so - // Write must be here (not just in the agent fallback) to take effect. - expect(SERVER_SRC).toContain("'--allowedTools', 'Bash,Read,Glob,Grep,Write'"); - }); - test('sidebar-agent falls back to defaults if queue has no args', () => { // Backward compatibility: if old queue entries lack args, use defaults expect(AGENT_SRC).toContain("'--allowedTools', 'Bash,Read,Glob,Grep,Write'");