diff --git a/docs/cli/plan-mode.md b/docs/cli/plan-mode.md index 03dd92967f..51f0078206 100644 --- a/docs/cli/plan-mode.md +++ b/docs/cli/plan-mode.md @@ -109,8 +109,9 @@ structure, and consultation level are proportional to the task's complexity: - **Iterate:** Provide feedback to refine the plan. - **Refine manually:** Press **Ctrl + X** to open the plan file in your [preferred external editor]. This allows you to manually refine the plan - steps before approval. The CLI will automatically refresh and show the - updated plan after you save and close the editor. + steps before approval. If you make any changes and save the file, the CLI + will automatically send the updated plan back to the agent for review and + iteration. For more complex or specialized planning tasks, you can [customize the planning workflow with skills](#customizing-planning-with-skills). diff --git a/packages/cli/src/ui/components/ExitPlanModeDialog.test.tsx b/packages/cli/src/ui/components/ExitPlanModeDialog.test.tsx index d691caba1a..2bf1f723a6 100644 --- a/packages/cli/src/ui/components/ExitPlanModeDialog.test.tsx +++ b/packages/cli/src/ui/components/ExitPlanModeDialog.test.tsx @@ -11,7 +11,6 @@ import { waitFor } from '../../test-utils/async.js'; import { ExitPlanModeDialog } from './ExitPlanModeDialog.js'; import { useKeypress } from '../hooks/useKeypress.js'; import { keyMatchers, Command } from '../keyMatchers.js'; -import { openFileInEditor } from '../utils/editorUtils.js'; import { ApprovalMode, validatePlanContent, @@ -41,10 +40,6 @@ vi.mock('node:fs', async (importOriginal) => { ...actual, existsSync: vi.fn(), realpathSync: vi.fn((p) => p), - promises: { - ...actual.promises, - readFile: vi.fn(), - }, }; }); @@ -546,7 +541,7 @@ Implement a comprehensive authentication system with multiple providers. expect(onFeedback).not.toHaveBeenCalled(); }); - it('opens plan in external editor when Ctrl+X is pressed', async () => { + it('automatically submits feedback when Ctrl+X is used to edit the plan', async () => { const { stdin, lastFrame } = renderDialog({ useAlternateBuffer }); await act(async () => { @@ -557,27 +552,16 @@ Implement a comprehensive authentication system with multiple providers. expect(lastFrame()).toContain('Add user authentication'); }); - // Reset the mock to track the second call during refresh - vi.mocked(processSingleFileContent).mockClear(); - // Press Ctrl+X await act(async () => { writeKey(stdin, '\x18'); // Ctrl+X }); await waitFor(() => { - expect(openFileInEditor).toHaveBeenCalledWith( - mockPlanFullPath, - expect.anything(), - expect.anything(), - undefined, + expect(onFeedback).toHaveBeenCalledWith( + 'I have edited the plan or annotated it with feedback. Review the edited plan, update if necessary, and present it again for approval.', ); }); - - // Verify that content is refreshed (processSingleFileContent called again) - await waitFor(() => { - expect(processSingleFileContent).toHaveBeenCalled(); - }); }); }, ); diff --git a/packages/cli/src/ui/components/ExitPlanModeDialog.tsx b/packages/cli/src/ui/components/ExitPlanModeDialog.tsx index 6a5da1c299..39e1b8a155 100644 --- a/packages/cli/src/ui/components/ExitPlanModeDialog.tsx +++ b/packages/cli/src/ui/components/ExitPlanModeDialog.tsx @@ -156,11 +156,15 @@ export const ExitPlanModeDialog: React.FC = ({ const handleOpenEditor = useCallback(async () => { try { await openFileInEditor(planPath, stdin, setRawMode, getPreferredEditor()); + + onFeedback( + 'I have edited the plan or annotated it with feedback. Review the edited plan, update if necessary, and present it again for approval.', + ); refresh(); } catch (err) { debugLogger.error('Failed to open plan in editor:', err); } - }, [planPath, stdin, setRawMode, getPreferredEditor, refresh]); + }, [planPath, stdin, setRawMode, getPreferredEditor, refresh, onFeedback]); useKeypress( (key) => {