Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c44a95f
feat(cli): respect /editor preference in Ctrl+X external editor
dreamWB May 19, 2026
524c52b
fix(cli): address review feedback on external editor feature
dreamWB May 19, 2026
d26265c
test(cli): add missing vi.mock for usePreferredEditor and useWorktree…
dreamWB May 19, 2026
e532708
fix(cli): address review feedback on env-var fallback and spawnSync t…
dreamWB May 19, 2026
cdf7fb9
fix(cli): propagate preferredEditor to TextInput component
dreamWB May 19, 2026
2732e41
fix(cli): document why simple double-quoting is safe for shell args
dreamWB May 19, 2026
e4d5486
fix(cli): handle signal-killed editor and defer undo snapshot
dreamWB May 19, 2026
8094231
fix(cli): restore private tmpdir, skip undo on unchanged content
dreamWB May 19, 2026
3733059
fix(cli): use path.join in external editor tests for Windows compat
dreamWB May 19, 2026
ba6c20c
fix(cli): quote editorCmd in shell mode, wrap setRawMode, improve log…
dreamWB May 19, 2026
8e791db
refactor(core): remove unused isTerminal from ExternalEditorCommand
dreamWB May 19, 2026
bb4444b
docs(cli): update stale JSDoc on openInExternalEditor
dreamWB May 19, 2026
9059913
fix(cli): address review round 3 — temp dir leak, mkdtemp safety, Tex…
dreamWB May 19, 2026
0bdb55d
test(cli): add undo-after-successful-edit test for external editor
dreamWB May 20, 2026
e1b2d55
fix(cli): opts.editor priority, filePath in error log, warn on invali…
dreamWB May 20, 2026
bef3734
fix(cli): address sandbox gap and Windows env-var safety in external …
dreamWB May 20, 2026
468acc2
fix(cli): address wenshao review — unsafe-char guard, debug logs, tes…
dreamWB May 20, 2026
c9b2b2e
fix(cli): expand unsafe-char guard, remove stale comment, add tests
dreamWB May 20, 2026
a051743
fix(cli): remove explicit type annotation on mock.calls.findIndex cal…
dreamWB May 20, 2026
1e2ae54
fix(cli): replace unlinkSync+rmdirSync with recursive rmSync for temp…
dreamWB May 20, 2026
d7e35de
test(cli): add % and ! unsafe-char coverage and error-path raw mode test
dreamWB May 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/cli/src/ui/AppContainer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ vi.mock('./hooks/useIdeTrustListener.js');
vi.mock('./hooks/useMessageQueue.js');
vi.mock('./hooks/useAutoAcceptIndicator.js');
vi.mock('./hooks/useGitBranchName.js');
vi.mock('./hooks/usePreferredEditor.js');
vi.mock('./hooks/useWorktreeSession.js');
vi.mock('./hooks/useProviderUpdates.js', () => ({
useProviderUpdates: vi.fn(() => ({
providerUpdateRequest: undefined,
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/ui/AppContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import { useThemeCommand } from './hooks/useThemeCommand.js';
import { useFeedbackDialog } from './hooks/useFeedbackDialog.js';
import { useAuthCommand } from './auth/useAuth.js';
import { useEditorSettings } from './hooks/useEditorSettings.js';
import { usePreferredEditor } from './hooks/usePreferredEditor.js';
import { useSettingsCommand } from './hooks/useSettingsCommand.js';
import { useModelCommand } from './hooks/useModelCommand.js';
import { useManageModelsCommand } from './hooks/useManageModelsCommand.js';
Expand Down Expand Up @@ -779,13 +780,16 @@ export const AppContainer = (props: AppContainerProps) => {
}
}, []);

const preferredEditor = usePreferredEditor();

const buffer = useTextBuffer({
initialText: '',
viewport: { height: 10, width: inputWidth },
stdin,
setRawMode,
isValidPath,
shellModeActive,
preferredEditor,
});

useEffect(() => {
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/ui/components/agent-view/AgentComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { QueuedMessageDisplay } from '../QueuedMessageDisplay.js';
import { AgentFooter } from './AgentFooter.js';
import { keyMatchers, Command } from '../../keyMatchers.js';
import { theme } from '../../semantic-colors.js';
import { usePreferredEditor } from '../../hooks/usePreferredEditor.js';
import { t } from '../../../i18n/index.js';

// ─── Types ──────────────────────────────────────────────────
Expand All @@ -65,6 +66,7 @@ export const AgentComposer: React.FC<AgentComposerProps> = ({ agentId }) => {
const interactiveAgent = agent?.interactiveAgent;

const config = useConfig();
const preferredEditor = usePreferredEditor();
const { columns: terminalWidth } = useTerminalSize();
const { inputWidth } = calculatePromptWidths(terminalWidth);
const { stdin, setRawMode } = useStdin();
Expand Down Expand Up @@ -127,6 +129,7 @@ export const AgentComposer: React.FC<AgentComposerProps> = ({ agentId }) => {
stdin,
setRawMode,
isValidPath,
preferredEditor,
});

// Sync agent buffer text to context so AgentTabBar can guard tab switching
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/src/ui/components/shared/TextInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ vi.mock('../../hooks/useKeypress.js', () => ({
useKeypress: vi.fn(),
}));

vi.mock('../../hooks/usePreferredEditor.js');

vi.mock('../../semantic-colors.js', () => ({
theme: {
text: { accent: 'cyan' },
Expand Down
10 changes: 8 additions & 2 deletions packages/cli/src/ui/components/shared/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
* SPDX-License-Identifier: Apache-2.0
*/

// no hooks needed beyond keypress handled inside
import { Box, Text } from 'ink';
import { Box, Text, useStdin } from 'ink';
Comment thread
dreamWB marked this conversation as resolved.
Comment thread
dreamWB marked this conversation as resolved.
import chalk from 'chalk';
import stringWidth from 'string-width';
import { useTextBuffer } from './text-buffer.js';
import { usePreferredEditor } from '../../hooks/usePreferredEditor.js';
import { useKeypress } from '../../hooks/useKeypress.js';
import { keyMatchers, Command } from '../../keyMatchers.js';
import { cpSlice, cpLen } from '../../utils/textUtils.js';
Expand Down Expand Up @@ -76,12 +76,18 @@ export function TextInput({
onChangeRef.current?.(text);
}, []);

const preferredEditor = usePreferredEditor();
const { stdin, setRawMode } = useStdin();

const buffer = useTextBuffer({
initialText: value || '',
initialCursorOffset,
viewport: { height, width: inputWidth },
stdin,
setRawMode,
isValidPath: () => false,
onChange: stableOnChange,
preferredEditor,
});
Comment thread
dreamWB marked this conversation as resolved.

const handleSubmit = () => {
Expand Down
Loading
Loading