Skip to content

Commit 73997fc

Browse files
jeroptripleyoung
authored andcommitted
feat(cli): update approval mode cycle order (google-gemini#19254)
1 parent f1a8664 commit 73997fc

File tree

6 files changed

+50
-37
lines changed

6 files changed

+50
-37
lines changed

docs/cli/plan-mode.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ Other ways to start in Plan Mode:
6161
You can enter Plan Mode in three ways:
6262

6363
1. **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes
64-
(`Default` -> `Plan` -> `Auto-Edit`).
64+
(`Default` -> `Auto-Edit` -> `Plan`).
6565
2. **Command:** Type `/plan` in the input box.
6666
3. **Natural Language:** Ask the agent to "start a plan for...". The agent will
6767
then call the [`enter_plan_mode`] tool to switch modes.

packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ describe('ApprovalModeIndicator', () => {
1414
const { lastFrame } = render(
1515
<ApprovalModeIndicator approvalMode={ApprovalMode.AUTO_EDIT} />,
1616
);
17-
const output = lastFrame();
18-
expect(output).toContain('auto-accept edits');
19-
expect(output).toContain('shift+tab to manual');
17+
expect(lastFrame()).toMatchSnapshot();
2018
});
2119

2220
it('renders correctly for AUTO_EDIT mode with plan enabled', () => {
@@ -26,35 +24,28 @@ describe('ApprovalModeIndicator', () => {
2624
isPlanEnabled={true}
2725
/>,
2826
);
29-
const output = lastFrame();
30-
expect(output).toContain('auto-accept edits');
31-
expect(output).toContain('shift+tab to manual');
27+
expect(lastFrame()).toMatchSnapshot();
3228
});
3329

3430
it('renders correctly for PLAN mode', () => {
3531
const { lastFrame } = render(
3632
<ApprovalModeIndicator approvalMode={ApprovalMode.PLAN} />,
3733
);
38-
const output = lastFrame();
39-
expect(output).toContain('plan');
40-
expect(output).toContain('shift+tab to accept edits');
34+
expect(lastFrame()).toMatchSnapshot();
4135
});
4236

4337
it('renders correctly for YOLO mode', () => {
4438
const { lastFrame } = render(
4539
<ApprovalModeIndicator approvalMode={ApprovalMode.YOLO} />,
4640
);
47-
const output = lastFrame();
48-
expect(output).toContain('YOLO');
49-
expect(output).toContain('ctrl+y');
41+
expect(lastFrame()).toMatchSnapshot();
5042
});
5143

5244
it('renders correctly for DEFAULT mode', () => {
5345
const { lastFrame } = render(
5446
<ApprovalModeIndicator approvalMode={ApprovalMode.DEFAULT} />,
5547
);
56-
const output = lastFrame();
57-
expect(output).toContain('shift+tab to accept edits');
48+
expect(lastFrame()).toMatchSnapshot();
5849
});
5950

6051
it('renders correctly for DEFAULT mode with plan enabled', () => {
@@ -64,7 +55,6 @@ describe('ApprovalModeIndicator', () => {
6455
isPlanEnabled={true}
6556
/>,
6657
);
67-
const output = lastFrame();
68-
expect(output).toContain('shift+tab to plan');
58+
expect(lastFrame()).toMatchSnapshot();
6959
});
7060
});

packages/cli/src/ui/components/ApprovalModeIndicator.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ interface ApprovalModeIndicatorProps {
1414
isPlanEnabled?: boolean;
1515
}
1616

17+
export const APPROVAL_MODE_TEXT = {
18+
AUTO_EDIT: 'auto-accept edits',
19+
PLAN: 'plan',
20+
YOLO: 'YOLO',
21+
HINT_SWITCH_TO_PLAN_MODE: 'shift+tab to plan',
22+
HINT_SWITCH_TO_MANUAL_MODE: 'shift+tab to manual',
23+
HINT_SWITCH_TO_AUTO_EDIT_MODE: 'shift+tab to accept edits',
24+
HINT_SWITCH_TO_YOLO_MODE: 'ctrl+y',
25+
};
26+
1727
export const ApprovalModeIndicator: React.FC<ApprovalModeIndicatorProps> = ({
1828
approvalMode,
1929
isPlanEnabled,
@@ -25,26 +35,26 @@ export const ApprovalModeIndicator: React.FC<ApprovalModeIndicatorProps> = ({
2535
switch (approvalMode) {
2636
case ApprovalMode.AUTO_EDIT:
2737
textColor = theme.status.warning;
28-
textContent = 'auto-accept edits';
29-
subText = 'shift+tab to manual';
38+
textContent = APPROVAL_MODE_TEXT.AUTO_EDIT;
39+
subText = isPlanEnabled
40+
? APPROVAL_MODE_TEXT.HINT_SWITCH_TO_PLAN_MODE
41+
: APPROVAL_MODE_TEXT.HINT_SWITCH_TO_MANUAL_MODE;
3042
break;
3143
case ApprovalMode.PLAN:
3244
textColor = theme.status.success;
33-
textContent = 'plan';
34-
subText = 'shift+tab to accept edits';
45+
textContent = APPROVAL_MODE_TEXT.PLAN;
46+
subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_MANUAL_MODE;
3547
break;
3648
case ApprovalMode.YOLO:
3749
textColor = theme.status.error;
38-
textContent = 'YOLO';
39-
subText = 'ctrl+y';
50+
textContent = APPROVAL_MODE_TEXT.YOLO;
51+
subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_YOLO_MODE;
4052
break;
4153
case ApprovalMode.DEFAULT:
4254
default:
4355
textColor = theme.text.accent;
4456
textContent = '';
45-
subText = isPlanEnabled
46-
? 'shift+tab to plan'
47-
: 'shift+tab to accept edits';
57+
subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_AUTO_EDIT_MODE;
4858
break;
4959
}
5060

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`ApprovalModeIndicator > renders correctly for AUTO_EDIT mode 1`] = `"auto-accept edits shift+tab to manual"`;
4+
5+
exports[`ApprovalModeIndicator > renders correctly for AUTO_EDIT mode with plan enabled 1`] = `"auto-accept edits shift+tab to plan"`;
6+
7+
exports[`ApprovalModeIndicator > renders correctly for DEFAULT mode 1`] = `"shift+tab to accept edits"`;
8+
9+
exports[`ApprovalModeIndicator > renders correctly for DEFAULT mode with plan enabled 1`] = `"shift+tab to accept edits"`;
10+
11+
exports[`ApprovalModeIndicator > renders correctly for PLAN mode 1`] = `"plan shift+tab to manual"`;
12+
13+
exports[`ApprovalModeIndicator > renders correctly for YOLO mode 1`] = `"YOLO ctrl+y"`;

packages/cli/src/ui/hooks/useApprovalModeIndicator.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ describe('useApprovalModeIndicator', () => {
202202
);
203203
expect(result.current).toBe(ApprovalMode.YOLO);
204204

205-
// Shift+Tab cycles back to DEFAULT (since PLAN is disabled by default in mock)
205+
// Shift+Tab cycles back to AUTO_EDIT (from YOLO)
206206
act(() => {
207207
capturedUseKeypressHandler({
208208
name: 'tab',
@@ -236,7 +236,7 @@ describe('useApprovalModeIndicator', () => {
236236
expect(result.current).toBe(ApprovalMode.AUTO_EDIT);
237237
});
238238

239-
it('should cycle through DEFAULT -> PLAN -> AUTO_EDIT -> DEFAULT when plan is enabled', () => {
239+
it('should cycle through DEFAULT -> AUTO_EDIT -> PLAN -> DEFAULT when plan is enabled', () => {
240240
mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
241241
mockConfigInstance.isPlanEnabled.mockReturnValue(true);
242242
renderHook(() =>
@@ -246,23 +246,23 @@ describe('useApprovalModeIndicator', () => {
246246
}),
247247
);
248248

249-
// DEFAULT -> PLAN
249+
// DEFAULT -> AUTO_EDIT
250250
act(() => {
251251
capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
252252
});
253253
expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
254-
ApprovalMode.PLAN,
254+
ApprovalMode.AUTO_EDIT,
255255
);
256256

257-
// PLAN -> AUTO_EDIT
257+
// AUTO_EDIT -> PLAN
258258
act(() => {
259259
capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
260260
});
261261
expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith(
262-
ApprovalMode.AUTO_EDIT,
262+
ApprovalMode.PLAN,
263263
);
264264

265-
// AUTO_EDIT -> DEFAULT
265+
// PLAN -> DEFAULT
266266
act(() => {
267267
capturedUseKeypressHandler({ name: 'tab', shift: true } as Key);
268268
});

packages/cli/src/ui/hooks/useApprovalModeIndicator.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ export function useApprovalModeIndicator({
7272
const currentMode = config.getApprovalMode();
7373
switch (currentMode) {
7474
case ApprovalMode.DEFAULT:
75+
nextApprovalMode = ApprovalMode.AUTO_EDIT;
76+
break;
77+
case ApprovalMode.AUTO_EDIT:
7578
nextApprovalMode = config.isPlanEnabled()
7679
? ApprovalMode.PLAN
77-
: ApprovalMode.AUTO_EDIT;
80+
: ApprovalMode.DEFAULT;
7881
break;
7982
case ApprovalMode.PLAN:
80-
nextApprovalMode = ApprovalMode.AUTO_EDIT;
81-
break;
82-
case ApprovalMode.AUTO_EDIT:
8383
nextApprovalMode = ApprovalMode.DEFAULT;
8484
break;
8585
case ApprovalMode.YOLO:

0 commit comments

Comments
 (0)