From 63388074a7c8621ff0627423fabf29c13377c050 Mon Sep 17 00:00:00 2001 From: Charles Packer Date: Fri, 26 Dec 2025 12:29:07 -0800 Subject: [PATCH] fix: fix plan mode on non-default toolsets (#398) Co-authored-by: Letta --- src/cli/App.tsx | 4 ++-- src/permissions/mode.ts | 27 +++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index f66521b..0c10930 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -206,7 +206,7 @@ function getPlanModeReminder(): string { Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received. ## Plan File Info: -${planFilePath ? `No plan file exists yet. You should create your plan at ${planFilePath} using the Write tool.` : "No plan file path assigned."} +${planFilePath ? `No plan file exists yet. You should create your plan at ${planFilePath} using a write tool (e.g. Write, ApplyPatch, etc. depending on your toolset).` : "No plan file path assigned."} You should build your plan incrementally by writing to or editing this file. NOTE that this is the only file you are allowed to edit - other than this you are only allowed to take READ-ONLY actions. @@ -5002,7 +5002,7 @@ DO NOT respond to these messages or otherwise consider them in your response unl handlePlanKeepPlanning( `You must write your plan to the plan file before exiting plan mode.\n` + `Plan file path: ${planFilePath || "not set"}\n` + - `Use the Write tool to create your plan, then call ExitPlanMode again.`, + `Use a write tool (e.g. Write, ApplyPatch, etc.) to create your plan, then call ExitPlanMode again.`, ); } }, [pendingApprovals, approvalResults.length, handlePlanKeepPlanning]); diff --git a/src/permissions/mode.ts b/src/permissions/mode.ts index 0160c00..2d3fff2 100644 --- a/src/permissions/mode.ts +++ b/src/permissions/mode.ts @@ -151,14 +151,18 @@ class PermissionModeManager { "ReadManyFiles", ]; const writeTools = [ - // Anthropic toolset + // Anthropic toolset (PascalCase only) "Write", "Edit", "MultiEdit", - "NotebookEdit", - // Codex toolset + // Codex toolset (snake_case and PascalCase) "apply_patch", "ApplyPatch", + // Gemini toolset (snake_case and PascalCase) + "write_file_gemini", + "WriteFileGemini", + "replace", + "Replace", ]; if (allowedInPlan.includes(toolName)) { @@ -168,9 +172,24 @@ class PermissionModeManager { // Special case: allow writes to the plan file only if (writeTools.includes(toolName)) { const planFilePath = this.getPlanFilePath(); - const targetPath = + let targetPath = (toolArgs?.file_path as string) || (toolArgs?.path as string); + // ApplyPatch/apply_patch: extract file path from patch input + if ( + (toolName === "ApplyPatch" || toolName === "apply_patch") && + toolArgs?.input + ) { + const input = toolArgs.input as string; + // Extract path from "*** Add File: path", "*** Update File: path", or "*** Delete File: path" + const match = input.match( + /\*\*\* (?:Add|Update|Delete) File:\s*(.+)/, + ); + if (match?.[1]) { + targetPath = match[1].trim(); + } + } + if (planFilePath && targetPath && targetPath === planFilePath) { return "allow"; }