diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2f7b784707..aab6d93f5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## [0.13.4.1] - 2026-03-29 — Sidebar Agent Action Expansion
+
+The Chrome sidebar agent can now write files, enabling full IDE assistance directly from the side panel.
+
+### Fixed
+
+- **Sidebar Agent Tool Restrictions.** Added `Write` to the sidebar agent's allowed tools, fixing a bug where it couldn't operate on local files.
+- **Empty State UX.** Prevented the agent output container from hanging silently when no textual response is produced; it now displays a clear "Claude finished but produced no output" message.
+
## [0.13.4.0] - 2026-03-29 — Sidebar Defense
The Chrome sidebar now defends against prompt injection attacks. Three layers: XML-framed prompts with trust boundaries, a command allowlist that restricts bash to browse commands only, and Opus as the default model (harder to manipulate).
diff --git a/VERSION b/VERSION
index 3bfa77a455..c1333dd6e6 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.13.4.0
+0.13.4.1
diff --git a/browse/src/server.ts b/browse/src/server.ts
index f3f8d68dd8..05684f661e 100644
--- a/browse/src/server.ts
+++ b/browse/src/server.ts
@@ -430,7 +430,7 @@ function spawnClaude(userMessage: string, extensionUrl?: string | null): void {
const prompt = `${systemPrompt}\n\n\n${escapedMessage}\n`;
const args = ['-p', prompt, '--model', 'opus', '--output-format', 'stream-json', '--verbose',
- '--allowedTools', 'Bash,Read,Glob,Grep'];
+ '--allowedTools', 'Bash,Read,Write,Glob,Grep'];
if (sidebarSession?.claudeSessionId) {
args.push('--resume', sidebarSession.claudeSessionId);
}
diff --git a/browse/src/sidebar-agent.ts b/browse/src/sidebar-agent.ts
index db56022114..6d8c185a96 100644
--- a/browse/src/sidebar-agent.ts
+++ b/browse/src/sidebar-agent.ts
@@ -162,7 +162,7 @@ async function askClaude(queueEntry: any): Promise {
// Use args from queue entry (server sets --model, --allowedTools, prompt framing).
// Fall back to defaults only if queue entry has no args (backward compat).
let claudeArgs = args || ['-p', prompt, '--output-format', 'stream-json', '--verbose',
- '--allowedTools', 'Bash,Read,Glob,Grep'];
+ '--allowedTools', 'Bash,Read,Write,Glob,Grep'];
// Validate cwd exists — queue may reference a stale worktree
let effectiveCwd = cwd || process.cwd();
diff --git a/browse/test/sidebar-security.test.ts b/browse/test/sidebar-security.test.ts
index b953f5b770..2e0617524f 100644
--- a/browse/test/sidebar-security.test.ts
+++ b/browse/test/sidebar-security.test.ts
@@ -115,6 +115,6 @@ describe('Sidebar prompt injection defense', () => {
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'");
+ expect(AGENT_SRC).toContain("'--allowedTools', 'Bash,Read,Write,Glob,Grep'");
});
});
diff --git a/extension/sidepanel.css b/extension/sidepanel.css
index 855589616e..db46ca4bdf 100644
--- a/extension/sidepanel.css
+++ b/extension/sidepanel.css
@@ -305,6 +305,12 @@ body::after {
font-size: 12px;
font-family: var(--font-mono);
}
+.agent-empty {
+ color: var(--text-label);
+ font-style: italic;
+ font-size: 11px;
+ padding: 4px 0;
+}
/* Thinking dots animation */
.agent-thinking {
diff --git a/extension/sidepanel.js b/extension/sidepanel.js
index 2ee3da6b3b..e95f3b8a7e 100644
--- a/extension/sidepanel.js
+++ b/extension/sidepanel.js
@@ -157,6 +157,13 @@ function handleAgentEvent(entry) {
// Remove thinking indicator
const thinking = document.getElementById('agent-thinking');
if (thinking) thinking.remove();
+ // If agent finished with no text output, show a "no output" message
+ if (agentContainer && !agentTextEl) {
+ const empty = document.createElement('div');
+ empty.className = 'agent-empty';
+ empty.textContent = 'Claude finished but produced no output.';
+ agentContainer.appendChild(empty);
+ }
// Add timestamp
if (agentContainer) {
const ts = document.createElement('span');
diff --git a/package.json b/package.json
index 55f7a9fbbe..d994803fcf 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "gstack",
- "version": "0.13.3.0",
+ "version": "0.13.4.1",
"description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.",
"license": "MIT",
"type": "module",