Skip to content
This repository was archived by the owner on May 20, 2026. It is now read-only.

Commit 998fef0

Browse files
authored
AutoApprove edits in CLI when using autoapprove mode (#4373)
* AutoApprove edits in CLI when using autoapprove mode * Fix tests * Add more tests * UpdatesFixes
1 parent 1cff7a0 commit 998fef0

2 files changed

Lines changed: 39 additions & 6 deletions

File tree

src/extension/chatSessions/copilotcli/node/copilotcliSession.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
371371
confirmationType: 'basic' as const,
372372
};
373373

374-
let approved = false;
374+
let approved = true;
375375
try {
376376
const result = await this._toolsService.invokeTool(ToolName.CoreConfirmationTool, {
377377
input: params,
@@ -380,12 +380,15 @@ export class CopilotCLISession extends DisposableStore implements ICopilotCLISes
380380

381381
const firstResultPart = result.content.at(0);
382382
approved = firstResultPart instanceof LanguageModelTextPart && firstResultPart.value === 'yes';
383+
const autoApproveEdits = approved && this._permissionLevel === 'autoApprove' ? true : undefined;
384+
if (approved) {
385+
this._sdkSession.respondToExitPlanMode(event.data.requestId, { approved, selectedAction: 'exit_only', autoApproveEdits });
386+
return;
387+
}
383388
} catch (error) {
384389
this.logService.error(error, '[ConfirmationTool] Error showing confirmation tool for exit plan mode');
385-
approved = false;
386390
}
387-
388-
this._sdkSession.respondToExitPlanMode(event.data.requestId, { approved, selectedAction: 'exit_only' });
391+
this._sdkSession.respondToExitPlanMode(event.data.requestId, { approved: false });
389392

390393
})));
391394
disposables.add(toDisposable(this._sdkSession.on('user_input.requested', async (event) => {

src/extension/chatSessions/copilotcli/node/test/copilotcliSession.spec.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,36 @@ describe('CopilotCLISession', () => {
11851185
expect(toolsService.invokeToolCalls[0].input).toMatchObject({ message: summary });
11861186
});
11871187

1188+
it('sets autoApproveEdits when user confirms with autoApprove permission level', async () => {
1189+
const result = { value: undefined as unknown };
1190+
setupSendWithExitPlanMode({ summary: 'Here is the plan', actions: ['exit_only'] }, result);
1191+
toolsService.setConfirmationResult('yes');
1192+
const session = await createSession();
1193+
session.setPermissionLevel('autoApprove');
1194+
const stream = new MockChatResponseStream();
1195+
session.attachStream(stream);
1196+
const mockToken = {} as ChatParticipantToolToken;
1197+
1198+
await session.handleRequest({ id: '', toolInvocationToken: mockToken }, { prompt: 'Plan' }, [], undefined, authInfo, CancellationToken.None);
1199+
1200+
expect(result.value).toEqual({ approved: true, selectedAction: 'exit_only', autoApproveEdits: true });
1201+
});
1202+
1203+
it('does not set autoApproveEdits when user rejects with autoApprove permission level', async () => {
1204+
const result = { value: undefined as unknown };
1205+
setupSendWithExitPlanMode({ summary: 'Here is the plan', actions: ['exit_only'] }, result);
1206+
toolsService.setConfirmationResult('no');
1207+
const session = await createSession();
1208+
session.setPermissionLevel('autoApprove');
1209+
const stream = new MockChatResponseStream();
1210+
session.attachStream(stream);
1211+
const mockToken = {} as ChatParticipantToolToken;
1212+
1213+
await session.handleRequest({ id: '', toolInvocationToken: mockToken }, { prompt: 'Plan' }, [], undefined, authInfo, CancellationToken.None);
1214+
1215+
expect(result.value).toEqual({ approved: false });
1216+
});
1217+
11881218
it('denies when user rejects via confirmation tool in non-autopilot mode', async () => {
11891219
const result = { value: undefined as unknown };
11901220
setupSendWithExitPlanMode({ summary: 'Here is the plan', actions: ['exit_only'] }, result);
@@ -1196,7 +1226,7 @@ describe('CopilotCLISession', () => {
11961226

11971227
await session.handleRequest({ id: '', toolInvocationToken: mockToken }, { prompt: 'Plan' }, [], undefined, authInfo, CancellationToken.None);
11981228

1199-
expect(result.value).toEqual({ approved: false, selectedAction: 'exit_only' });
1229+
expect(result.value).toEqual({ approved: false });
12001230
});
12011231

12021232
it('denies when confirmation tool throws in non-autopilot mode', async () => {
@@ -1210,7 +1240,7 @@ describe('CopilotCLISession', () => {
12101240

12111241
await session.handleRequest({ id: '', toolInvocationToken: mockToken }, { prompt: 'Plan' }, [], undefined, authInfo, CancellationToken.None);
12121242

1213-
expect(result.value).toEqual({ approved: false, selectedAction: 'exit_only' });
1243+
expect(result.value).toEqual({ approved: false });
12141244
});
12151245
});
12161246
});

0 commit comments

Comments
 (0)