Skip to content

Commit 678215f

Browse files
authored
fix(agent): make Auto Mode auto-approve edits and shell commands (#2970)
1 parent 9f76c9b commit 678215f

4 files changed

Lines changed: 56 additions & 3 deletions

File tree

packages/agent/src/adapters/claude/permissions/permission-handlers.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,50 @@ describe("canUseTool MCP approval enforcement", () => {
345345
);
346346
});
347347
});
348+
349+
describe("canUseTool auto mode hands-off approval", () => {
350+
beforeEach(() => {
351+
clearMcpToolMetadataCache();
352+
});
353+
354+
// Auto mode advertises hands-off approval; it must not prompt for the write
355+
// and shell tools that drive every real task.
356+
it.each(["Bash", "BashOutput", "KillShell", "Edit", "Write", "NotebookEdit"])(
357+
"auto-allows %s in auto mode without prompting",
358+
async (toolName) => {
359+
const context = createContext(toolName, {
360+
session: {
361+
permissionMode: "auto",
362+
settingsManager: {
363+
getRepoRoot: vi.fn().mockReturnValue("/repo"),
364+
},
365+
},
366+
});
367+
368+
const result = await canUseTool(context);
369+
370+
expect(result.behavior).toBe("allow");
371+
expect(context.client.requestPermission).not.toHaveBeenCalled();
372+
},
373+
);
374+
375+
// Guard against the fix leaking into default mode, where these tools should
376+
// still go through the manual permission prompt.
377+
it.each(["Bash", "Edit", "Write"])(
378+
"still prompts for %s in default mode",
379+
async (toolName) => {
380+
const context = createContext(toolName, {
381+
session: {
382+
permissionMode: "default",
383+
settingsManager: {
384+
getRepoRoot: vi.fn().mockReturnValue("/repo"),
385+
},
386+
},
387+
});
388+
389+
await canUseTool(context);
390+
391+
expect(context.client.requestPermission).toHaveBeenCalled();
392+
},
393+
);
394+
});

packages/agent/src/adapters/claude/tools.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ const BASE_ALLOWED_TOOLS = [
4343
];
4444

4545
const AUTO_ALLOWED_TOOLS: Record<string, Set<string>> = {
46-
auto: new Set(BASE_ALLOWED_TOOLS),
46+
// Auto mode is hands-off: it auto-approves file edits and shell commands on
47+
// top of the base read/search/web/agent tools. Without WRITE_TOOLS and
48+
// BASH_TOOLS here, Edit/Write/Bash fall through to a manual prompt on every
49+
// call, which contradicts what the mode advertises. MCP tools are still gated
50+
// separately (do_not_use is denied, needs_approval still prompts) in
51+
// canUseTool, so auto stays narrower than bypassPermissions.
52+
auto: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS, ...BASH_TOOLS]),
4753
default: new Set(BASE_ALLOWED_TOOLS),
4854
acceptEdits: new Set([...BASE_ALLOWED_TOOLS, ...WRITE_TOOLS]),
4955
plan: new Set(BASE_ALLOWED_TOOLS),

packages/agent/src/execution-mode.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ if (ALLOW_BYPASS) {
3535
{
3636
id: "auto",
3737
name: "Auto Mode",
38-
description: "Use a model classifier to approve/deny permission prompts",
38+
description: "Auto-approve file edits and shell commands",
3939
},
4040
);
4141
}

packages/core/src/sessions/executionModes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const availableModes: ModeInfo[] = [
3030
{
3131
id: "auto",
3232
name: "Auto Mode",
33-
description: "Use a model classifier to approve/deny permission prompts",
33+
description: "Auto-approve file edits and shell commands",
3434
},
3535
];
3636

0 commit comments

Comments
 (0)