From 2813d8fe50b7b34f4514040cb0a97d7480e59707 Mon Sep 17 00:00:00 2001 From: Nick McNamara Date: Wed, 18 Mar 2026 20:30:27 -0700 Subject: [PATCH 1/3] feat(cli): conditionally exclude ask_user tool in ACP mode This prevents IDEs like IntelliJ from intercepting the ask_user tool call and presenting confusing allow/reject permission dialogs to the user, forcing the model to fallback to plain text conversational queries instead. --- packages/cli/src/config/config.test.ts | 12 ++++++++++++ packages/cli/src/config/config.ts | 7 +++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index a94d1f0a285..a92425cda2d 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -2225,6 +2225,18 @@ describe('loadCliConfig tool exclusions', () => { expect(config.getExcludeTools()).toContain('ask_user'); }); + it('should exclude ask_user in interactive mode when --acp is provided', async () => { + process.stdin.isTTY = true; + process.argv = ['node', 'script.js', '--acp']; + const argv = await parseArguments(createTestMergedSettings()); + const config = await loadCliConfig( + createTestMergedSettings(), + 'test-session', + argv, + ); + expect(config.getExcludeTools()).toContain('ask_user'); + }); + it('should not exclude shell tool in non-interactive mode when --allowed-tools="ShellTool" is set', async () => { process.stdin.isTTY = false; process.argv = [ diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 777950c0caa..7db4f09703f 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -648,12 +648,16 @@ export async function loadCliConfig( const allowedTools = argv.allowedTools || settings.tools?.allowed || []; + const isAcpMode = !!argv.acp || !!argv.experimentalAcp; + // In non-interactive mode, exclude tools that require a prompt. const extraExcludes: string[] = []; - if (!interactive) { + if (!interactive || isAcpMode) { // The Policy Engine natively handles headless safety by translating ASK_USER // decisions to DENY. However, we explicitly block ask_user here to guarantee // it can never be allowed via a high-priority policy rule when no human is present. + // We also exclude it in ACP mode as IDEs intercept tool calls and ask for permission, + // breaking conversational flows. extraExcludes.push(ASK_USER_TOOL_NAME); } @@ -737,7 +741,6 @@ export async function loadCliConfig( } } - const isAcpMode = !!argv.acp || !!argv.experimentalAcp; let clientName: string | undefined = undefined; if (isAcpMode) { const ide = detectIdeFromEnv(); From 7003f153fa66ea65651d2562eb6e512fab0a0360 Mon Sep 17 00:00:00 2001 From: Sri Pasumarthi Date: Thu, 19 Mar 2026 15:22:47 -0700 Subject: [PATCH 2/3] Add another test case for --experimental-acp as well --- packages/cli/src/config/config.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index a92425cda2d..c046f0c0e75 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -2237,6 +2237,18 @@ describe('loadCliConfig tool exclusions', () => { expect(config.getExcludeTools()).toContain('ask_user'); }); + it('should exclude ask_user in interactive mode when --experimental-acp is provided', async () => { + process.stdin.isTTY = true; + process.argv = ['node', 'script.js', '--experimental-acp']; + const argv = await parseArguments(createTestMergedSettings()); + const config = await loadCliConfig( + createTestMergedSettings(), + 'test-session', + argv, + ); + expect(config.getExcludeTools()).toContain('ask_user'); + }); + it('should not exclude shell tool in non-interactive mode when --allowed-tools="ShellTool" is set', async () => { process.stdin.isTTY = false; process.argv = [ From 114f566edc781a9a48d419bc9fd11c32620fd1f3 Mon Sep 17 00:00:00 2001 From: Sri Pasumarthi Date: Thu, 19 Mar 2026 22:53:02 -0700 Subject: [PATCH 3/3] fix bad merge --- packages/cli/src/config/config.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 4ac432f6c29..fdcd18c086e 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -774,7 +774,6 @@ export async function loadCliConfig( } } - const isAcpMode = !!argv.acp || !!argv.experimentalAcp; let clientName: string | undefined = undefined; if (isAcpMode) { const ide = detectIdeFromEnv();