Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/pi-extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.

Expand Down
10 changes: 9 additions & 1 deletion apps/pi-extension/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down