diff --git a/docs/cli/plan-mode.md b/docs/cli/plan-mode.md index 1e88560f7ad..2cf01ae3547 100644 --- a/docs/cli/plan-mode.md +++ b/docs/cli/plan-mode.md @@ -61,7 +61,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...". The agent will then call the [`enter_plan_mode`] tool to switch modes. diff --git a/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx b/packages/cli/src/ui/components/ApprovalModeIndicator.test.tsx index d16925cb4b6..972aa586a06 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 6b1b1cfa53c..ef5ae2caadb 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 00000000000..839d72764cd --- /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 0b61023b18d..bdd99be61dd 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,23 +246,23 @@ describe('useApprovalModeIndicator', () => { }), ); - // DEFAULT -> PLAN + // DEFAULT -> AUTO_EDIT act(() => { capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); }); expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith( - ApprovalMode.PLAN, + ApprovalMode.AUTO_EDIT, ); - // PLAN -> AUTO_EDIT + // AUTO_EDIT -> PLAN act(() => { capturedUseKeypressHandler({ name: 'tab', shift: true } as Key); }); expect(mockConfigInstance.setApprovalMode).toHaveBeenCalledWith( - ApprovalMode.AUTO_EDIT, + ApprovalMode.PLAN, ); - // AUTO_EDIT -> DEFAULT + // 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 b48ce923386..d12afb12064 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 = ApprovalMode.AUTO_EDIT; + break; + case ApprovalMode.AUTO_EDIT: nextApprovalMode = config.isPlanEnabled() ? ApprovalMode.PLAN - : ApprovalMode.AUTO_EDIT; + : ApprovalMode.DEFAULT; break; case ApprovalMode.PLAN: - nextApprovalMode = ApprovalMode.AUTO_EDIT; - break; - case ApprovalMode.AUTO_EDIT: nextApprovalMode = ApprovalMode.DEFAULT; break; case ApprovalMode.YOLO: