-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Expand file tree
/
Copy pathclearCommand.ts
More file actions
130 lines (116 loc) · 3.9 KB
/
clearCommand.ts
File metadata and controls
130 lines (116 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type { SlashCommand, SlashCommandActionReturn } from './types.js';
import { CommandKind } from './types.js';
import { t } from '../../i18n/index.js';
import {
uiTelemetryService,
SessionEndReason,
SessionStartSource,
ToolNames,
SkillTool,
type PermissionMode,
ideContextStore,
} from '@qwen-code/qwen-code-core';
export const clearCommand: SlashCommand = {
name: 'clear',
altNames: ['reset', 'new'],
get description() {
return t(
'Clear screen, or use --history/--all to clear conversation and reset session',
);
},
kind: CommandKind.BUILT_IN,
completion: async () => [
{
value: '--history',
description: t(
'Clear dialogue history (keep system prompt + memory + context)',
),
},
{ value: '--all', description: t('Complete reset (like a new session)') },
],
action: async (context, args): Promise<void | SlashCommandActionReturn> => {
const hasAll = args.includes('--all');
// --all is a superset of --history; if both are provided, treat as --all
const isAll = hasAll;
const isHistory = !hasAll && args.includes('--history');
if (!isHistory && !isAll) {
// Clear UI only for immediate responsiveness
context.ui.clear();
return;
}
if (!context.overwriteConfirmed) {
return {
type: 'confirm_action',
prompt: isAll
? t('Are you sure you want to completely reset the session?')
: t('Are you sure you want to clear the conversation history?'),
originalInvocation: {
raw:
context.invocation?.raw ||
`/clear ${isAll ? '--all' : '--history'}`,
},
};
}
const { config } = context.services;
if (config) {
// Fire SessionEnd event (non-blocking to avoid UI lag)
config
.getHookSystem()
?.fireSessionEndEvent(SessionEndReason.Clear)
.catch((err) => {
config.getDebugLogger().warn(`SessionEnd hook failed: ${err}`);
});
const newSessionId = config.startNewSession();
// Reset UI telemetry metrics for the new session
uiTelemetryService.reset();
// Clear loaded-skills tracking so /context doesn't show stale data
const skillTool = config
.getToolRegistry()
?.getAllTools()
.find((tool) => tool.name === ToolNames.SKILL);
if (skillTool instanceof SkillTool) {
skillTool.clearLoadedSkills();
}
if (isAll) {
// --history preserves IDE context (system prompt + memory + context);
// --all performs a full reset including IDE context store
ideContextStore.clear();
}
if (newSessionId && context.session.startNewSession) {
context.session.startNewSession(newSessionId);
}
// Clear UI first for immediate responsiveness
context.ui.clear();
const geminiClient = config.getGeminiClient();
if (geminiClient) {
context.ui.setDebugMessage(
t('Starting a new session, resetting chat, and clearing terminal.'),
);
// If resetChat fails, the exception will propagate and halt the command,
// which is the correct behavior to signal a failure to the user.
await geminiClient.resetChat();
} else {
context.ui.setDebugMessage(t('Starting a new session and clearing.'));
}
// Fire SessionStart event (non-blocking to avoid UI lag)
config
.getHookSystem()
?.fireSessionStartEvent(
SessionStartSource.Clear,
config.getModel() ?? '',
String(config.getApprovalMode()) as PermissionMode,
)
.catch((err) => {
config.getDebugLogger().warn(`SessionStart hook failed: ${err}`);
});
} else {
context.ui.setDebugMessage(t('Starting a new session and clearing.'));
context.ui.clear();
}
},
};