diff --git a/docs/cli/plan-mode.md b/docs/cli/plan-mode.md index 8d28994aac..8c0781e3ac 100644 --- a/docs/cli/plan-mode.md +++ b/docs/cli/plan-mode.md @@ -59,7 +59,7 @@ Other ways to start in Plan Mode: You can enter Plan Mode in three ways: 1. **Keyboard Shortcut:** Press `Shift+Tab` to cycle through approval modes - (`Default` -> `Plan` -> `Auto-Edit`). + (`Default` -> `Auto-Edit` -> `Plan`). 2. **Command:** Type `/plan` in the input box. 3. **Natural Language:** Ask the agent to "start a plan for...". diff --git a/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx b/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx index d16925cb4b..972aa586a0 100644 --- a/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx +++ b/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx @@ -14,9 +14,7 @@ describe('ApprovalModeIndicator', () => { const { lastFrame } = render( , ); - const output = lastFrame(); - expect(output).toContain('auto-accept edits'); - expect(output).toContain('shift+tab to manual'); + expect(lastFrame()).toMatchSnapshot(); }); it('renders correctly for AUTO_EDIT mode with plan enabled', () => { @@ -26,35 +24,28 @@ describe('ApprovalModeIndicator', () => { isPlanEnabled={true} />, ); - const output = lastFrame(); - expect(output).toContain('auto-accept edits'); - expect(output).toContain('shift+tab to manual'); + expect(lastFrame()).toMatchSnapshot(); }); it('renders correctly for PLAN mode', () => { const { lastFrame } = render( , ); - const output = lastFrame(); - expect(output).toContain('plan'); - expect(output).toContain('shift+tab to accept edits'); + expect(lastFrame()).toMatchSnapshot(); }); it('renders correctly for YOLO mode', () => { const { lastFrame } = render( , ); - const output = lastFrame(); - expect(output).toContain('YOLO'); - expect(output).toContain('ctrl+y'); + expect(lastFrame()).toMatchSnapshot(); }); it('renders correctly for DEFAULT mode', () => { const { lastFrame } = render( , ); - const output = lastFrame(); - expect(output).toContain('shift+tab to accept edits'); + expect(lastFrame()).toMatchSnapshot(); }); it('renders correctly for DEFAULT mode with plan enabled', () => { @@ -64,7 +55,6 @@ describe('ApprovalModeIndicator', () => { isPlanEnabled={true} />, ); - const output = lastFrame(); - expect(output).toContain('shift+tab to plan'); + expect(lastFrame()).toMatchSnapshot(); }); }); diff --git a/packages/cli/src/ui/components/ApprovalModeIndicator.tsx b/packages/cli/src/ui/components/ApprovalModeIndicator.tsx index 6b1b1cfa53..ef5ae2caad 100644 --- a/packages/cli/src/ui/components/ApprovalModeIndicator.tsx +++ b/packages/cli/src/ui/components/ApprovalModeIndicator.tsx @@ -14,6 +14,16 @@ interface ApprovalModeIndicatorProps { isPlanEnabled?: boolean; } +export const APPROVAL_MODE_TEXT = { + AUTO_EDIT: 'auto-accept edits', + PLAN: 'plan', + YOLO: 'YOLO', + HINT_SWITCH_TO_PLAN_MODE: 'shift+tab to plan', + HINT_SWITCH_TO_MANUAL_MODE: 'shift+tab to manual', + HINT_SWITCH_TO_AUTO_EDIT_MODE: 'shift+tab to accept edits', + HINT_SWITCH_TO_YOLO_MODE: 'ctrl+y', +}; + export const ApprovalModeIndicator: React.FC = ({ approvalMode, isPlanEnabled, @@ -25,26 +35,26 @@ export const ApprovalModeIndicator: React.FC = ({ switch (approvalMode) { case ApprovalMode.AUTO_EDIT: textColor = theme.status.warning; - textContent = 'auto-accept edits'; - subText = 'shift+tab to manual'; + textContent = APPROVAL_MODE_TEXT.AUTO_EDIT; + subText = isPlanEnabled + ? APPROVAL_MODE_TEXT.HINT_SWITCH_TO_PLAN_MODE + : APPROVAL_MODE_TEXT.HINT_SWITCH_TO_MANUAL_MODE; break; case ApprovalMode.PLAN: textColor = theme.status.success; - textContent = 'plan'; - subText = 'shift+tab to accept edits'; + textContent = APPROVAL_MODE_TEXT.PLAN; + subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_MANUAL_MODE; break; case ApprovalMode.YOLO: textColor = theme.status.error; - textContent = 'YOLO'; - subText = 'ctrl+y'; + textContent = APPROVAL_MODE_TEXT.YOLO; + subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_YOLO_MODE; break; case ApprovalMode.DEFAULT: default: textColor = theme.text.accent; textContent = ''; - subText = isPlanEnabled - ? 'shift+tab to plan' - : 'shift+tab to accept edits'; + subText = APPROVAL_MODE_TEXT.HINT_SWITCH_TO_AUTO_EDIT_MODE; break; } diff --git a/packages/cli/src/ui/components/__snapshots__/ApprovalModeIndicator.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/ApprovalModeIndicator.test.tsx.snap new file mode 100644 index 0000000000..839d72764c --- /dev/null +++ b/packages/cli/src/ui/components/__snapshots__/ApprovalModeIndicator.test.tsx.snap @@ -0,0 +1,13 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`ApprovalModeIndicator > renders correctly for AUTO_EDIT mode 1`] = `"auto-accept edits shift+tab to manual"`; + +exports[`ApprovalModeIndicator > renders correctly for AUTO_EDIT mode with plan enabled 1`] = `"auto-accept edits shift+tab to plan"`; + +exports[`ApprovalModeIndicator > renders correctly for DEFAULT mode 1`] = `"shift+tab to accept edits"`; + +exports[`ApprovalModeIndicator > renders correctly for DEFAULT mode with plan enabled 1`] = `"shift+tab to accept edits"`; + +exports[`ApprovalModeIndicator > renders correctly for PLAN mode 1`] = `"plan shift+tab to manual"`; + +exports[`ApprovalModeIndicator > renders correctly for YOLO mode 1`] = `"YOLO ctrl+y"`; diff --git a/packages/cli/src/ui/hooks/useApprovalModeIndicator.test.ts b/packages/cli/src/ui/hooks/useApprovalModeIndicator.test.ts index 0b61023b18..bdd99be61d 100644 --- a/packages/cli/src/ui/hooks/useApprovalModeIndicator.test.ts +++ b/packages/cli/src/ui/hooks/useApprovalModeIndicator.test.ts @@ -202,7 +202,7 @@ describe('useApprovalModeIndicator', () => { ); expect(result.current).toBe(ApprovalMode.YOLO); - // Shift+Tab cycles back to DEFAULT (since PLAN is disabled by default in mock) + // Shift+Tab cycles back to AUTO_EDIT (from YOLO) act(() => { capturedUseKeypressHandler({ name: 'tab', @@ -236,7 +236,7 @@ describe('useApprovalModeIndicator', () => { expect(result.current).toBe(ApprovalMode.AUTO_EDIT); }); - it('should cycle through DEFAULT -> PLAN -> AUTO_EDIT -> DEFAULT when plan is enabled', () => { + it('should cycle through DEFAULT -> AUTO_EDIT -> PLAN -> DEFAULT when plan is enabled', () => { mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT); mockConfigInstance.isPlanEnabled.mockReturnValue(true); renderHook(() => @@ -246,15 +246,7 @@ describe('useApprovalModeIndicator', () => { }), ); - // DEFAULT -> PLAN - act(() => { - capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); - }); - expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith( - ApprovalMode.PLAN, - ); - - // PLAN -> AUTO_EDIT + // DEFAULT -> AUTO_EDIT act(() => { capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); }); @@ -262,7 +254,15 @@ describe('useApprovalModeIndicator', () => { ApprovalMode.AUTO_EDIT, ); - // AUTO_EDIT -> DEFAULT + // AUTO_EDIT -> PLAN + act(() => { + capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); + }); + expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith( + ApprovalMode.PLAN, + ); + + // PLAN -> DEFAULT act(() => { capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); }); diff --git a/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts b/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts index b48ce92338..d12afb1206 100644 --- a/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts +++ b/packages/cli/src/ui/hooks/useApprovalModeIndicator.ts @@ -72,14 +72,14 @@ export function useApprovalModeIndicator({ const currentMode = config.getApprovalMode(); switch (currentMode) { case ApprovalMode.DEFAULT: - nextApprovalMode = config.isPlanEnabled() - ? ApprovalMode.PLAN - : ApprovalMode.AUTO_EDIT; - break; - case ApprovalMode.PLAN: nextApprovalMode = ApprovalMode.AUTO_EDIT; break; case ApprovalMode.AUTO_EDIT: + nextApprovalMode = config.isPlanEnabled() + ? ApprovalMode.PLAN + : ApprovalMode.DEFAULT; + break; + case ApprovalMode.PLAN: nextApprovalMode = ApprovalMode.DEFAULT; break; case ApprovalMode.YOLO: