remove /quit-confirm slash command

This commit is contained in:
tanzhenxin
2025-12-04 16:21:32 +08:00
parent 6729980b47
commit 5b2f3e285c
17 changed files with 12 additions and 233 deletions

View File

@@ -145,16 +145,6 @@ Slash commands provide meta-level control over the CLI itself.
- **`nodesc`** or **`nodescriptions`**: - **`nodesc`** or **`nodescriptions`**:
- **Description:** Hide tool descriptions, showing only the tool names. - **Description:** Hide tool descriptions, showing only the tool names.
- **`/quit-confirm`**
- **Description:** Show a confirmation dialog before exiting Qwen Code, allowing you to choose how to handle your current session.
- **Usage:** `/quit-confirm`
- **Features:**
- **Quit immediately:** Exit without saving anything (equivalent to `/quit`)
- **Generate summary and quit:** Create a project summary using `/summary` before exiting
- **Save conversation and quit:** Save the current conversation with an auto-generated tag before exiting
- **Keyboard shortcut:** Press **Ctrl+C** twice to trigger the quit confirmation dialog
- **Note:** This command is automatically triggered when you press Ctrl+C once, providing a safety mechanism to prevent accidental exits.
- **`/quit`** (or **`/exit`**) - **`/quit`** (or **`/exit`**)
- **Description:** Exit Qwen Code immediately without any confirmation dialog. - **Description:** Exit Qwen Code immediately without any confirmation dialog.

View File

@@ -671,4 +671,4 @@ Note: When usage statistics are enabled, events are sent to an Alibaba Cloud RUM
- **Category:** UI - **Category:** UI
- **Requires Restart:** No - **Requires Restart:** No
- **Example:** `"enableWelcomeBack": false` - **Example:** `"enableWelcomeBack": false`
- **Details:** When enabled, Qwen Code will automatically detect if you're returning to a project with a previously generated project summary (`.qwen/PROJECT_SUMMARY.md`) and show a dialog allowing you to continue your previous conversation or start fresh. This feature integrates with the `/summary` command and quit confirmation dialog. See the [Welcome Back documentation](./welcome-back.md) for more details. - **Details:** When enabled, Qwen Code will automatically detect if you're returning to a project with a previously generated project summary (`.qwen/PROJECT_SUMMARY.md`) and show a dialog allowing you to continue your previous conversation or start fresh. This feature integrates with the `/summary` command. See the [Welcome Back documentation](./welcome-back.md) for more details.

View File

@@ -81,14 +81,6 @@ The Welcome Back feature works seamlessly with the `/summary` command:
2. **Automatic Detection:** Next time you start Qwen Code in this project, Welcome Back will detect the summary 2. **Automatic Detection:** Next time you start Qwen Code in this project, Welcome Back will detect the summary
3. **Resume Work:** Choose to continue and the summary will be loaded as context 3. **Resume Work:** Choose to continue and the summary will be loaded as context
### Quit Confirmation
When exiting with `/quit-confirm` and choosing "Generate summary and quit":
1. A project summary is automatically created
2. Next session will trigger the Welcome Back dialog
3. You can seamlessly continue your work
## File Structure ## File Structure
The Welcome Back feature creates and uses: The Welcome Back feature creates and uses:

View File

@@ -110,7 +110,6 @@ export default {
'open full Qwen Code documentation in your browser', 'open full Qwen Code documentation in your browser',
'Configuration not available.': 'Configuration not available.', 'Configuration not available.': 'Configuration not available.',
'change the auth method': 'change the auth method', 'change the auth method': 'change the auth method',
'Show quit confirmation dialog': 'Show quit confirmation dialog',
'Copy the last result or code snippet to clipboard': 'Copy the last result or code snippet to clipboard':
'Copy the last result or code snippet to clipboard', 'Copy the last result or code snippet to clipboard',
@@ -690,18 +689,6 @@ export default {
'A custom command wants to run the following shell commands:': 'A custom command wants to run the following shell commands:':
'A custom command wants to run the following shell commands:', 'A custom command wants to run the following shell commands:',
// ============================================================================
// Dialogs - Quit Confirmation
// ============================================================================
'What would you like to do before exiting?':
'What would you like to do before exiting?',
'Quit immediately (/quit)': 'Quit immediately (/quit)',
'Generate summary and quit (/summary)':
'Generate summary and quit (/summary)',
'Save conversation and quit (/chat save)':
'Save conversation and quit (/chat save)',
'Cancel (stay in application)': 'Cancel (stay in application)',
// ============================================================================ // ============================================================================
// Dialogs - Pro Quota // Dialogs - Pro Quota
// ============================================================================ // ============================================================================

View File

@@ -108,7 +108,6 @@ export default {
'在浏览器中打开完整的 Qwen Code 文档', '在浏览器中打开完整的 Qwen Code 文档',
'Configuration not available.': '配置不可用', 'Configuration not available.': '配置不可用',
'change the auth method': '更改认证方法', 'change the auth method': '更改认证方法',
'Show quit confirmation dialog': '显示退出确认对话框',
'Copy the last result or code snippet to clipboard': 'Copy the last result or code snippet to clipboard':
'将最后的结果或代码片段复制到剪贴板', '将最后的结果或代码片段复制到剪贴板',
@@ -655,15 +654,6 @@ export default {
'A custom command wants to run the following shell commands:': 'A custom command wants to run the following shell commands:':
'自定义命令想要运行以下 shell 命令:', '自定义命令想要运行以下 shell 命令:',
// ============================================================================
// Dialogs - Quit Confirmation
// ============================================================================
'What would you like to do before exiting?': '退出前您想要做什么?',
'Quit immediately (/quit)': '立即退出 (/quit)',
'Generate summary and quit (/summary)': '生成摘要并退出 (/summary)',
'Save conversation and quit (/chat save)': '保存对话并退出 (/chat save)',
'Cancel (stay in application)': '取消(留在应用程序中)',
// ============================================================================ // ============================================================================
// Dialogs - Pro Quota // Dialogs - Pro Quota
// ============================================================================ // ============================================================================

View File

@@ -71,7 +71,6 @@ vi.mock('../ui/commands/modelCommand.js', () => ({
})); }));
vi.mock('../ui/commands/quitCommand.js', () => ({ vi.mock('../ui/commands/quitCommand.js', () => ({
quitCommand: {}, quitCommand: {},
quitConfirmCommand: {},
})); }));
vi.mock('../ui/commands/statsCommand.js', () => ({ statsCommand: {} })); vi.mock('../ui/commands/statsCommand.js', () => ({ statsCommand: {} }));
vi.mock('../ui/commands/themeCommand.js', () => ({ themeCommand: {} })); vi.mock('../ui/commands/themeCommand.js', () => ({ themeCommand: {} }));

View File

@@ -28,7 +28,7 @@ import { mcpCommand } from '../ui/commands/mcpCommand.js';
import { memoryCommand } from '../ui/commands/memoryCommand.js'; import { memoryCommand } from '../ui/commands/memoryCommand.js';
import { modelCommand } from '../ui/commands/modelCommand.js'; import { modelCommand } from '../ui/commands/modelCommand.js';
import { permissionsCommand } from '../ui/commands/permissionsCommand.js'; import { permissionsCommand } from '../ui/commands/permissionsCommand.js';
import { quitCommand, quitConfirmCommand } from '../ui/commands/quitCommand.js'; import { quitCommand } from '../ui/commands/quitCommand.js';
import { restoreCommand } from '../ui/commands/restoreCommand.js'; import { restoreCommand } from '../ui/commands/restoreCommand.js';
import { settingsCommand } from '../ui/commands/settingsCommand.js'; import { settingsCommand } from '../ui/commands/settingsCommand.js';
import { statsCommand } from '../ui/commands/statsCommand.js'; import { statsCommand } from '../ui/commands/statsCommand.js';
@@ -77,7 +77,6 @@ export class BuiltinCommandLoader implements ICommandLoader {
modelCommand, modelCommand,
...(this.config?.getFolderTrust() ? [permissionsCommand] : []), ...(this.config?.getFolderTrust() ? [permissionsCommand] : []),
quitCommand, quitCommand,
quitConfirmCommand,
restoreCommand(this.config), restoreCommand(this.config),
statsCommand, statsCommand,
summaryCommand, summaryCommand,

View File

@@ -89,7 +89,6 @@ import { useSessionStats } from './contexts/SessionContext.js';
import { useGitBranchName } from './hooks/useGitBranchName.js'; import { useGitBranchName } from './hooks/useGitBranchName.js';
import { useExtensionUpdates } from './hooks/useExtensionUpdates.js'; import { useExtensionUpdates } from './hooks/useExtensionUpdates.js';
import { ShellFocusContext } from './contexts/ShellFocusContext.js'; import { ShellFocusContext } from './contexts/ShellFocusContext.js';
import { useQuitConfirmation } from './hooks/useQuitConfirmation.js';
import { t } from '../i18n/index.js'; import { t } from '../i18n/index.js';
import { useWelcomeBack } from './hooks/useWelcomeBack.js'; import { useWelcomeBack } from './hooks/useWelcomeBack.js';
import { useDialogClose } from './hooks/useDialogClose.js'; import { useDialogClose } from './hooks/useDialogClose.js';
@@ -446,8 +445,6 @@ export const AppContainer = (props: AppContainerProps) => {
const { toggleVimEnabled } = useVimMode(); const { toggleVimEnabled } = useVimMode();
const { showQuitConfirmation } = useQuitConfirmation();
const { const {
isSubagentCreateDialogOpen, isSubagentCreateDialogOpen,
openSubagentCreateDialog, openSubagentCreateDialog,
@@ -493,7 +490,6 @@ export const AppContainer = (props: AppContainerProps) => {
addConfirmUpdateExtensionRequest, addConfirmUpdateExtensionRequest,
openSubagentCreateDialog, openSubagentCreateDialog,
openAgentsManagerDialog, openAgentsManagerDialog,
_showQuitConfirmation: showQuitConfirmation,
}), }),
[ [
openAuthDialog, openAuthDialog,
@@ -507,7 +503,6 @@ export const AppContainer = (props: AppContainerProps) => {
openPermissionsDialog, openPermissionsDialog,
openApprovalModeDialog, openApprovalModeDialog,
addConfirmUpdateExtensionRequest, addConfirmUpdateExtensionRequest,
showQuitConfirmation,
openSubagentCreateDialog, openSubagentCreateDialog,
openAgentsManagerDialog, openAgentsManagerDialog,
], ],
@@ -520,7 +515,6 @@ export const AppContainer = (props: AppContainerProps) => {
commandContext, commandContext,
shellConfirmationRequest, shellConfirmationRequest,
confirmationRequest, confirmationRequest,
quitConfirmationRequest,
} = useSlashCommandProcessor( } = useSlashCommandProcessor(
config, config,
settings, settings,
@@ -969,7 +963,6 @@ export const AppContainer = (props: AppContainerProps) => {
isFolderTrustDialogOpen, isFolderTrustDialogOpen,
showWelcomeBackDialog, showWelcomeBackDialog,
handleWelcomeBackClose, handleWelcomeBackClose,
quitConfirmationRequest,
}); });
const handleExit = useCallback( const handleExit = useCallback(
@@ -983,25 +976,18 @@ export const AppContainer = (props: AppContainerProps) => {
if (timerRef.current) { if (timerRef.current) {
clearTimeout(timerRef.current); clearTimeout(timerRef.current);
} }
// Exit directly without showing confirmation dialog // Exit directly
handleSlashCommand('/quit'); handleSlashCommand('/quit');
return; return;
} }
// First press: Prioritize cleanup tasks // First press: Prioritize cleanup tasks
// Special case: If quit-confirm dialog is open, Ctrl+C means "quit immediately"
if (quitConfirmationRequest) {
handleSlashCommand('/quit');
return;
}
// 1. Close other dialogs (highest priority) // 1. Close other dialogs (highest priority)
/** /**
* For AuthDialog it is required to complete the authentication process, * For AuthDialog it is required to complete the authentication process,
* otherwise user cannot proceed to the next step. * otherwise user cannot proceed to the next step.
* So a quit on AuthDialog should go with normal two press quit * So a quit on AuthDialog should go with normal two press quit.
* and without quit-confirm dialog.
*/ */
if (isAuthDialogOpen) { if (isAuthDialogOpen) {
setPressedOnce(true); setPressedOnce(true);
@@ -1022,14 +1008,17 @@ export const AppContainer = (props: AppContainerProps) => {
return; // Request cancelled, end processing return; // Request cancelled, end processing
} }
// 3. Clear input buffer (if has content) // 4. Clear input buffer (if has content)
if (buffer.text.length > 0) { if (buffer.text.length > 0) {
buffer.setText(''); buffer.setText('');
return; // Input cleared, end processing return; // Input cleared, end processing
} }
// All cleanup tasks completed, show quit confirmation dialog // All cleanup tasks completed, set flag for double-press to quit
handleSlashCommand('/quit-confirm'); setPressedOnce(true);
timerRef.current = setTimeout(() => {
setPressedOnce(false);
}, CTRL_EXIT_PROMPT_DURATION_MS);
}, },
[ [
isAuthDialogOpen, isAuthDialogOpen,
@@ -1037,7 +1026,6 @@ export const AppContainer = (props: AppContainerProps) => {
closeAnyOpenDialog, closeAnyOpenDialog,
streamingState, streamingState,
cancelOngoingRequest, cancelOngoingRequest,
quitConfirmationRequest,
buffer, buffer,
], ],
); );
@@ -1054,8 +1042,8 @@ export const AppContainer = (props: AppContainerProps) => {
return; return;
} }
// On first press: set flag, start timer, and call handleExit for cleanup/quit-confirm // On first press: set flag, start timer, and call handleExit for cleanup
// On second press (within 500ms): handleExit sees flag and does fast quit // On second press (within timeout): handleExit sees flag and does fast quit
if (!ctrlCPressedOnce) { if (!ctrlCPressedOnce) {
setCtrlCPressedOnce(true); setCtrlCPressedOnce(true);
ctrlCTimerRef.current = setTimeout(() => { ctrlCTimerRef.current = setTimeout(() => {
@@ -1196,7 +1184,6 @@ export const AppContainer = (props: AppContainerProps) => {
!!confirmationRequest || !!confirmationRequest ||
confirmUpdateExtensionRequests.length > 0 || confirmUpdateExtensionRequests.length > 0 ||
!!loopDetectionConfirmationRequest || !!loopDetectionConfirmationRequest ||
!!quitConfirmationRequest ||
isThemeDialogOpen || isThemeDialogOpen ||
isSettingsDialogOpen || isSettingsDialogOpen ||
isModelDialogOpen || isModelDialogOpen ||
@@ -1245,7 +1232,6 @@ export const AppContainer = (props: AppContainerProps) => {
confirmationRequest, confirmationRequest,
confirmUpdateExtensionRequests, confirmUpdateExtensionRequests,
loopDetectionConfirmationRequest, loopDetectionConfirmationRequest,
quitConfirmationRequest,
geminiMdFileCount, geminiMdFileCount,
streamingState, streamingState,
initError, initError,
@@ -1337,7 +1323,6 @@ export const AppContainer = (props: AppContainerProps) => {
confirmationRequest, confirmationRequest,
confirmUpdateExtensionRequests, confirmUpdateExtensionRequests,
loopDetectionConfirmationRequest, loopDetectionConfirmationRequest,
quitConfirmationRequest,
geminiMdFileCount, geminiMdFileCount,
streamingState, streamingState,
initError, initError,

View File

@@ -8,35 +8,6 @@ import { formatDuration } from '../utils/formatters.js';
import { CommandKind, type SlashCommand } from './types.js'; import { CommandKind, type SlashCommand } from './types.js';
import { t } from '../../i18n/index.js'; import { t } from '../../i18n/index.js';
export const quitConfirmCommand: SlashCommand = {
name: 'quit-confirm',
get description() {
return t('Show quit confirmation dialog');
},
kind: CommandKind.BUILT_IN,
action: (context) => {
const now = Date.now();
const { sessionStartTime } = context.session.stats;
const wallDuration = now - sessionStartTime.getTime();
return {
type: 'quit_confirmation',
messages: [
{
type: 'user',
text: `/quit-confirm`,
id: now - 1,
},
{
type: 'quit_confirmation',
duration: formatDuration(wallDuration),
id: now,
},
],
};
},
};
export const quitCommand: SlashCommand = { export const quitCommand: SlashCommand = {
name: 'quit', name: 'quit',
altNames: ['exit'], altNames: ['exit'],

View File

@@ -100,12 +100,6 @@ export interface QuitActionReturn {
messages: HistoryItem[]; messages: HistoryItem[];
} }
/** The return type for a command action that requests quit confirmation. */
export interface QuitConfirmationActionReturn {
type: 'quit_confirmation';
messages: HistoryItem[];
}
/** /**
* The return type for a command action that results in a simple message * The return type for a command action that results in a simple message
* being displayed to the user. * being displayed to the user.
@@ -182,7 +176,6 @@ export type SlashCommandActionReturn =
| ToolActionReturn | ToolActionReturn
| MessageActionReturn | MessageActionReturn
| QuitActionReturn | QuitActionReturn
| QuitConfirmationActionReturn
| OpenDialogActionReturn | OpenDialogActionReturn
| LoadHistoryActionReturn | LoadHistoryActionReturn
| SubmitPromptActionReturn | SubmitPromptActionReturn

View File

@@ -36,10 +36,6 @@ import { WelcomeBackDialog } from './WelcomeBackDialog.js';
import { ModelSwitchDialog } from './ModelSwitchDialog.js'; import { ModelSwitchDialog } from './ModelSwitchDialog.js';
import { AgentCreationWizard } from './subagents/create/AgentCreationWizard.js'; import { AgentCreationWizard } from './subagents/create/AgentCreationWizard.js';
import { AgentsManagerDialog } from './subagents/manage/AgentsManagerDialog.js'; import { AgentsManagerDialog } from './subagents/manage/AgentsManagerDialog.js';
import {
QuitConfirmationDialog,
QuitChoice,
} from './QuitConfirmationDialog.js';
interface DialogManagerProps { interface DialogManagerProps {
addItem: UseHistoryManagerReturn['addItem']; addItem: UseHistoryManagerReturn['addItem'];
@@ -127,24 +123,6 @@ export const DialogManager = ({
/> />
); );
} }
if (uiState.quitConfirmationRequest) {
return (
<QuitConfirmationDialog
onSelect={(choice: QuitChoice) => {
if (choice === QuitChoice.CANCEL) {
uiState.quitConfirmationRequest?.onConfirm(false, 'cancel');
} else if (choice === QuitChoice.QUIT) {
uiState.quitConfirmationRequest?.onConfirm(true, 'quit');
} else if (choice === QuitChoice.SUMMARY_AND_QUIT) {
uiState.quitConfirmationRequest?.onConfirm(
true,
'summary_and_quit',
);
}
}}
/>
);
}
if (uiState.confirmationRequest) { if (uiState.confirmationRequest) {
return ( return (
<ConsentPrompt <ConsentPrompt

View File

@@ -108,9 +108,6 @@ const HistoryItemDisplayComponent: React.FC<HistoryItemDisplayProps> = ({
{itemForDisplay.type === 'quit' && ( {itemForDisplay.type === 'quit' && (
<SessionSummaryDisplay duration={itemForDisplay.duration} /> <SessionSummaryDisplay duration={itemForDisplay.duration} />
)} )}
{itemForDisplay.type === 'quit_confirmation' && (
<SessionSummaryDisplay duration={itemForDisplay.duration} />
)}
{itemForDisplay.type === 'tool_group' && ( {itemForDisplay.type === 'tool_group' && (
<ToolGroupMessage <ToolGroupMessage
toolCalls={itemForDisplay.tools} toolCalls={itemForDisplay.tools}

View File

@@ -12,7 +12,6 @@ import type {
ShellConfirmationRequest, ShellConfirmationRequest,
ConfirmationRequest, ConfirmationRequest,
LoopDetectionConfirmationRequest, LoopDetectionConfirmationRequest,
QuitConfirmationRequest,
HistoryItemWithoutId, HistoryItemWithoutId,
StreamingState, StreamingState,
} from '../types.js'; } from '../types.js';
@@ -69,7 +68,6 @@ export interface UIState {
confirmationRequest: ConfirmationRequest | null; confirmationRequest: ConfirmationRequest | null;
confirmUpdateExtensionRequests: ConfirmationRequest[]; confirmUpdateExtensionRequests: ConfirmationRequest[];
loopDetectionConfirmationRequest: LoopDetectionConfirmationRequest | null; loopDetectionConfirmationRequest: LoopDetectionConfirmationRequest | null;
quitConfirmationRequest: QuitConfirmationRequest | null;
geminiMdFileCount: number; geminiMdFileCount: number;
streamingState: StreamingState; streamingState: StreamingState;
initError: string | null; initError: string | null;

View File

@@ -918,7 +918,6 @@ describe('useSlashCommandProcessor', () => {
vi.fn(), // toggleVimEnabled vi.fn(), // toggleVimEnabled
vi.fn(), // setIsProcessing vi.fn(), // setIsProcessing
vi.fn(), // setGeminiMdFileCount vi.fn(), // setGeminiMdFileCount
vi.fn(), // _showQuitConfirmation
), ),
); );

View File

@@ -18,7 +18,6 @@ import {
IdeClient, IdeClient,
} from '@qwen-code/qwen-code-core'; } from '@qwen-code/qwen-code-core';
import { useSessionStats } from '../contexts/SessionContext.js'; import { useSessionStats } from '../contexts/SessionContext.js';
import { formatDuration } from '../utils/formatters.js';
import type { import type {
Message, Message,
HistoryItemWithoutId, HistoryItemWithoutId,
@@ -53,7 +52,6 @@ function serializeHistoryItemForRecording(
const SLASH_COMMANDS_SKIP_RECORDING = new Set([ const SLASH_COMMANDS_SKIP_RECORDING = new Set([
'quit', 'quit',
'quit-confirm',
'exit', 'exit',
'clear', 'clear',
'reset', 'reset',
@@ -75,7 +73,6 @@ interface SlashCommandProcessorActions {
addConfirmUpdateExtensionRequest: (request: ConfirmationRequest) => void; addConfirmUpdateExtensionRequest: (request: ConfirmationRequest) => void;
openSubagentCreateDialog: () => void; openSubagentCreateDialog: () => void;
openAgentsManagerDialog: () => void; openAgentsManagerDialog: () => void;
_showQuitConfirmation: () => void;
} }
/** /**
@@ -115,10 +112,6 @@ export const useSlashCommandProcessor = (
prompt: React.ReactNode; prompt: React.ReactNode;
onConfirm: (confirmed: boolean) => void; onConfirm: (confirmed: boolean) => void;
}>(null); }>(null);
const [quitConfirmationRequest, setQuitConfirmationRequest] =
useState<null | {
onConfirm: (shouldQuit: boolean, action?: string) => void;
}>(null);
const [sessionShellAllowlist, setSessionShellAllowlist] = useState( const [sessionShellAllowlist, setSessionShellAllowlist] = useState(
new Set<string>(), new Set<string>(),
@@ -174,11 +167,6 @@ export const useSlashCommandProcessor = (
type: 'quit', type: 'quit',
duration: message.duration, duration: message.duration,
}; };
} else if (message.type === MessageType.QUIT_CONFIRMATION) {
historyItemContent = {
type: 'quit_confirmation',
duration: message.duration,
};
} else if (message.type === MessageType.COMPRESSION) { } else if (message.type === MessageType.COMPRESSION) {
historyItemContent = { historyItemContent = {
type: 'compression', type: 'compression',
@@ -449,66 +437,6 @@ export const useSlashCommandProcessor = (
}); });
return { type: 'handled' }; return { type: 'handled' };
} }
case 'quit_confirmation':
// Show quit confirmation dialog instead of immediately quitting
setQuitConfirmationRequest({
onConfirm: (shouldQuit: boolean, action?: string) => {
setQuitConfirmationRequest(null);
if (!shouldQuit) {
// User cancelled the quit operation - do nothing
return;
}
if (shouldQuit) {
if (action === 'summary_and_quit') {
// Generate summary and then quit
handleSlashCommand('/summary')
.then(() => {
// Wait for user to see the summary result
setTimeout(() => {
handleSlashCommand('/quit');
}, 1200);
})
.catch((error) => {
// If summary fails, still quit but show error
addItemWithRecording(
{
type: 'error',
text: `Failed to generate summary before quit: ${
error instanceof Error
? error.message
: String(error)
}`,
},
Date.now(),
);
// Give user time to see the error message
setTimeout(() => {
handleSlashCommand('/quit');
}, 1000);
});
} else {
// Just quit immediately - trigger the actual quit action
const now = Date.now();
const { sessionStartTime } = sessionStats;
const wallDuration = now - sessionStartTime.getTime();
actions.quit([
{
type: 'user',
text: `/quit`,
id: now - 1,
},
{
type: 'quit',
duration: formatDuration(wallDuration),
id: now,
},
]);
}
}
},
});
return { type: 'handled' };
case 'quit': case 'quit':
actions.quit(result.messages); actions.quit(result.messages);
@@ -692,7 +620,6 @@ export const useSlashCommandProcessor = (
setSessionShellAllowlist, setSessionShellAllowlist,
setIsProcessing, setIsProcessing,
setConfirmationRequest, setConfirmationRequest,
sessionStats,
], ],
); );
@@ -703,6 +630,5 @@ export const useSlashCommandProcessor = (
commandContext, commandContext,
shellConfirmationRequest, shellConfirmationRequest,
confirmationRequest, confirmationRequest,
quitConfirmationRequest,
}; };
}; };

View File

@@ -44,11 +44,6 @@ export interface DialogCloseOptions {
// Welcome back dialog // Welcome back dialog
showWelcomeBackDialog: boolean; showWelcomeBackDialog: boolean;
handleWelcomeBackClose: () => void; handleWelcomeBackClose: () => void;
// Quit confirmation dialog
quitConfirmationRequest: {
onConfirm: (shouldQuit: boolean, action?: string) => void;
} | null;
} }
/** /**
@@ -96,9 +91,6 @@ export function useDialogClose(options: DialogCloseOptions) {
return true; return true;
} }
// Note: quitConfirmationRequest is NOT handled here anymore
// It's handled specially in handleExit - ctrl+c in quit-confirm should exit immediately
// No dialog was open // No dialog was open
return false; return false;
}, [options]); }, [options]);

View File

@@ -161,11 +161,6 @@ export type HistoryItemQuit = HistoryItemBase & {
duration: string; duration: string;
}; };
export type HistoryItemQuitConfirmation = HistoryItemBase & {
type: 'quit_confirmation';
duration: string;
};
export type HistoryItemToolGroup = HistoryItemBase & { export type HistoryItemToolGroup = HistoryItemBase & {
type: 'tool_group'; type: 'tool_group';
tools: IndividualToolCallDisplay[]; tools: IndividualToolCallDisplay[];
@@ -256,7 +251,6 @@ export type HistoryItemWithoutId =
| HistoryItemModelStats | HistoryItemModelStats
| HistoryItemToolStats | HistoryItemToolStats
| HistoryItemQuit | HistoryItemQuit
| HistoryItemQuitConfirmation
| HistoryItemCompression | HistoryItemCompression
| HistoryItemSummary | HistoryItemSummary
| HistoryItemCompression | HistoryItemCompression
@@ -278,7 +272,6 @@ export enum MessageType {
MODEL_STATS = 'model_stats', MODEL_STATS = 'model_stats',
TOOL_STATS = 'tool_stats', TOOL_STATS = 'tool_stats',
QUIT = 'quit', QUIT = 'quit',
QUIT_CONFIRMATION = 'quit_confirmation',
GEMINI = 'gemini', GEMINI = 'gemini',
COMPRESSION = 'compression', COMPRESSION = 'compression',
SUMMARY = 'summary', SUMMARY = 'summary',
@@ -342,12 +335,6 @@ export type Message =
duration: string; duration: string;
content?: string; content?: string;
} }
| {
type: MessageType.QUIT_CONFIRMATION;
timestamp: Date;
duration: string;
content?: string;
}
| { | {
type: MessageType.COMPRESSION; type: MessageType.COMPRESSION;
compression: CompressionProps; compression: CompressionProps;
@@ -404,7 +391,3 @@ export interface ConfirmationRequest {
export interface LoopDetectionConfirmationRequest { export interface LoopDetectionConfirmationRequest {
onComplete: (result: { userSelection: 'disable' | 'keep' }) => void; onComplete: (result: { userSelection: 'disable' | 'keep' }) => void;
} }
export interface QuitConfirmationRequest {
onConfirm: (shouldQuit: boolean, action?: string) => void;
}