From 463b0b68228b177aad73e26d821f3f70a7e96dda Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Mar 2026 20:04:28 +0000 Subject: [PATCH 1/2] fix: allow curl/wget with stderr redirects in plan mode bash allowlist The `>` redirect detection in isSafeCommand() was falsely blocking common curl patterns like `curl ... 2>/dev/null` and `curl ... 2>&1 | head`. This prevented agents from fetching web content (e.g. via jina.ai or markdown.new) during planning mode. Fix: strip safe fd redirects (2>/dev/null, 2>&1, &>/dev/null) from the command before checking against destructive patterns, while still blocking actual file redirects like `> output.txt`. https://claude.ai/code/session_01Jk1P5aZPERSzrmA9urfb4B --- apps/pi-extension/utils.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/pi-extension/utils.ts b/apps/pi-extension/utils.ts index eb570b4c..eee546c0 100644 --- a/apps/pi-extension/utils.ts +++ b/apps/pi-extension/utils.ts @@ -46,7 +46,15 @@ const SAFE_PATTERNS = [ ]; export function isSafeCommand(command: string): boolean { - const isDestructive = DESTRUCTIVE_PATTERNS.some((p) => p.test(command)); + // Strip safe fd redirects before checking destructive patterns. + // This prevents common patterns like `curl ... 2>/dev/null` or + // `curl ... 2>&1 | head` from being falsely blocked by the `>` rule. + const normalized = command + .replace(/\s*\d*>\s*\/dev\/null/g, "") // N>/dev/null (any fd to /dev/null) + .replace(/\s*\d*>&\d+/g, "") // N>&M (fd merges, e.g. 2>&1) + .replace(/\s*&>\s*\/dev\/null/g, ""); // &>/dev/null (bash shorthand) + + const isDestructive = DESTRUCTIVE_PATTERNS.some((p) => p.test(normalized)); const isSafe = SAFE_PATTERNS.some((p) => p.test(command)); return !isDestructive && isSafe; } From 56bcc49256b2d0fd428346afc4d3303cace409ea Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 3 Mar 2026 21:28:29 +0000 Subject: [PATCH 2/2] fix: explicitly allow web content fetching in planning mode prompt The planning phase system prompt says "bash (read-only commands only)" which causes models to self-censor and not attempt curl/wget for web content fetching (e.g. jina.ai, markdown.new). Update the prompt to explicitly mention curl/wget is allowed, and mention web fetching in the explore step instructions. https://claude.ai/code/session_01Jk1P5aZPERSzrmA9urfb4B --- apps/pi-extension/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/pi-extension/index.ts b/apps/pi-extension/index.ts index c14892cd..1afb4cf8 100644 --- a/apps/pi-extension/index.ts +++ b/apps/pi-extension/index.ts @@ -444,7 +444,7 @@ export default function plannotator(pi: ExtensionAPI): void { content: `[PLANNOTATOR - PLANNING PHASE] You are in plan mode. You MUST NOT make any changes to the codebase — no edits, no commits, no installs, no destructive commands. The ONLY file you may write to or edit is the plan file: ${planFilePath}. -Available tools: read, bash (read-only commands only), grep, find, ls, write (${planFilePath} only), edit (${planFilePath} only), exit_plan_mode +Available tools: read, bash (read-only commands only — curl/wget for web fetching is allowed), grep, find, ls, write (${planFilePath} only), edit (${planFilePath} only), exit_plan_mode ## Iterative Planning Workflow @@ -454,7 +454,7 @@ You are pair-planning with the user. Explore the code to build context, then wri Repeat this cycle until the plan is complete: -1. **Explore** — Use read, grep, find, ls, and bash to understand the codebase. Actively search for existing functions, utilities, and patterns that can be reused — avoid proposing new code when suitable implementations already exist. +1. **Explore** — Use read, grep, find, ls, and bash to understand the codebase. You can also use bash with curl/wget to fetch web content (e.g. documentation, APIs). Actively search for existing functions, utilities, and patterns that can be reused — avoid proposing new code when suitable implementations already exist. 2. **Update the plan file** — After each discovery, immediately capture what you learned in ${planFilePath}. Don't wait until the end. Use write for the initial draft, then edit for all subsequent updates. 3. **Ask the user** — When you hit an ambiguity or decision you can't resolve from code alone, ask. Then go back to step 1.