Skip to content

Commit 951ffc5

Browse files
committed
Refactor agent search flags to use workspace configuration settings and standardize undo translations
- we want to make a few changes: 1) store flags of each agent in settings.json as .e.g 'agenticSearchCodexFlags' 2) update the flow to allow managing multiple sets of flag strings in each supported agent - if there are agents with custom flags, show one without any as well - drop parenthesis [Image], move the value to description - change icon from 'add' to 'flags' - allow undoing an agent with flags deletion, make sure the quick pick re-appear with the item restored - rename 'flag deleted' to 'Flags deleted.' - add missing translations [Fragment] - move [Fragment] to common translations - use the shared 'common.undo' └── apps └── editor ├── package.json └── src ├── commands │ ├── copy-paths-command.ts │ ├── duplicate-workspace-command.ts │ └── history-command │ ├── actions │ │ ├── clear-all-checkpoints.ts │ │ ├── create-temporary-checkpoint.ts │ │ ├── delete-checkpoint-with-undo.ts │ │ ├── restore-checkpoint.ts │ │ ├── sync-workspace-from-dir.ts │ │ ├── toggle-checkpoint-pin.ts │ │ └── update-checkpoint-description.ts │ ├── history-command.ts │ ├── index.ts │ └── utils │ └── sync-directory.ts ├── constants │ └── state-keys.ts ├── context │ └── context-initialization.ts ├── features │ ├── context-restoration │ │ └── utils │ │ └── source-selector.ts │ └── search-files │ └── search-modes │ └── perform-agent-search-mode │ ├── agents │ │ ├── antigravity.ts │ │ ├── claude.ts │ │ ├── codex.ts │ │ └── opencode.ts │ ├── index.ts │ ├── types.ts │ └── utils.ts ├── i18n │ └── translations │ ├── commands │ │ └── history.ts │ ├── common.ts │ ├── features │ │ └── search-files.ts │ └── views │ ├── settings │ │ └── handlers │ │ ├── handle-delete-model-provider.ts │ │ └── handle-delete-template.ts │ └── shared │ └── actions │ ├── api │ │ └── delete.ts │ └── web │ └── delete.ts └── views ├── prompt │ └── backend │ ├── message-handlers │ │ ├── handle-autofill.ts │ │ ├── handle-delete-task.ts │ │ ├── handle-save-edit-format.ts │ │ ├── handle-select-edit-format-instructions.ts │ │ ├── handle-template-quick-pick.ts │ │ └── handle-update-last-used-web-configuration.ts │ └── prompt-view-provider.ts ├── settings │ └── backend │ └── message-handlers │ ├── handle-delete-model-provider.ts │ └── handle-delete-template.ts └── shared └── actions ├── api │ └── delete.ts └── web └── delete.ts
1 parent 76bc806 commit 951ffc5

14 files changed

Lines changed: 282 additions & 164 deletions

File tree

‎apps/editor/package.json‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,34 @@
10441044
"scope": "resource",
10451045
"default": false
10461046
},
1047+
"codeWebChat.agenticSearchAntigravityFlags": {
1048+
"type": "array",
1049+
"scope": "resource",
1050+
"items": {
1051+
"type": "string"
1052+
}
1053+
},
1054+
"codeWebChat.agenticSearchClaudeFlags": {
1055+
"type": "array",
1056+
"scope": "resource",
1057+
"items": {
1058+
"type": "string"
1059+
}
1060+
},
1061+
"codeWebChat.agenticSearchCodexFlags": {
1062+
"type": "array",
1063+
"scope": "resource",
1064+
"items": {
1065+
"type": "string"
1066+
}
1067+
},
1068+
"codeWebChat.agenticSearchOpencodeFlags": {
1069+
"type": "array",
1070+
"scope": "resource",
1071+
"items": {
1072+
"type": "string"
1073+
}
1074+
},
10471075
"codeWebChat.webConfigurations": {
10481076
"type": "array",
10491077
"scope": "resource",

‎apps/editor/src/commands/history-command/actions/delete-checkpoint-with-undo.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export const delete_checkpoint_with_undo = async (params: {
5959
params.set_active_operation(operation)
6060

6161
params.on_before_show_message?.()
62-
const undo_action = t('command.history.action.undo')
62+
const undo_action = t('common.undo')
6363
const choice = await vscode.window.showInformationMessage(
6464
t('command.history.success.deleted'),
6565
undo_action

‎apps/editor/src/constants/state-keys.ts‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ export const LAST_SEARCH_FILES_FOR_CONTEXT_MODE_STATE_KEY =
8585
export const LAST_SELECTED_WORKSPACE_IN_AGENT_SEARCH_STATE_KEY =
8686
'last-selected-workspace-in-agent-search'
8787

88-
export const get_agent_flags_state_key = (cmd: string) =>
89-
`agent-flags-${cmd}`
88+
9089

9190
export const LAST_INTELLIGENT_FILE_SEARCH_SHRINK_STATE_KEY =
9291
'last-intelligent-file-search-shrink'

‎apps/editor/src/features/search-files/search-modes/perform-agent-search-mode/index.ts‎

Lines changed: 193 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import * as path from 'path'
66
import * as fs from 'fs'
77
import {
88
LAST_SELECTED_WORKSPACE_IN_AGENT_SEARCH_STATE_KEY,
9-
LAST_SEARCH_FILES_AGENT_QUERY_STATE_KEY,
10-
get_agent_flags_state_key
9+
LAST_SEARCH_FILES_AGENT_QUERY_STATE_KEY
1110
} from '@/constants/state-keys'
1211
import { extract_paths_from_text } from '@/utils/extract-paths-from-text'
1312
import { get_all_workspace_files } from '@/context/helpers/get-all-workspace-files'
@@ -63,79 +62,180 @@ export const perform_agent_search_mode = async (params: {
6362
return undefined
6463
}
6564

66-
const edit_button = {
65+
const add_button = {
6766
iconPath: new vscode.ThemeIcon('flag'),
67+
tooltip: t('feature.search-files.agent.add-flags')
68+
}
69+
const edit_button = {
70+
iconPath: new vscode.ThemeIcon('edit'),
6871
tooltip: t('feature.search-files.agent.edit-flags')
6972
}
73+
const delete_button = {
74+
iconPath: new vscode.ThemeIcon('trash'),
75+
tooltip: t('feature.search-files.agent.delete-flags')
76+
}
7077
const doc_button = {
71-
iconPath: new vscode.ThemeIcon('globe'),
78+
iconPath: new vscode.ThemeIcon('question'),
7279
tooltip: t('feature.search-files.agent.learn-more')
7380
}
7481

75-
const agent_picks = available_agents.map((a) => {
76-
const pick: vscode.QuickPickItem & { cmd: string } = {
77-
label: a.label,
78-
cmd: a.cmd
79-
}
82+
type AgentPickItem = vscode.QuickPickItem & {
83+
cmd: string
84+
agent_id: string
85+
flag_index: number
86+
flag_value: string
87+
configKey: string
88+
}
8089

81-
pick.buttons = [edit_button, doc_button]
90+
const build_agent_picks = (): AgentPickItem[] => {
91+
const agent_picks: AgentPickItem[] = []
92+
93+
for (const a of available_agents) {
94+
const configKey = `agenticSearch${
95+
a.id.charAt(0).toUpperCase() + a.id.slice(1)
96+
}Flags`
97+
const config = vscode.workspace.getConfiguration('codeWebChat')
98+
let flags = config.get<string[]>(configKey)
99+
if (!Array.isArray(flags)) {
100+
flags = []
101+
}
82102

83-
return pick
84-
})
103+
const custom_flags = flags.filter((f) => f.trim() !== '')
104+
const display_flags = ['', ...custom_flags]
105+
106+
display_flags.forEach((flag, index) => {
107+
const buttons: vscode.QuickInputButton[] = []
108+
if (index === 0) {
109+
buttons.push(add_button)
110+
buttons.push(doc_button)
111+
} else {
112+
buttons.push(edit_button)
113+
buttons.push(delete_button)
114+
}
115+
116+
agent_picks.push({
117+
label: a.label,
118+
description: flag ? flag : undefined,
119+
cmd: a.cmd,
120+
agent_id: a.id,
121+
flag_index: index > 0 ? index - 1 : -1,
122+
flag_value: flag,
123+
configKey,
124+
buttons
125+
})
126+
})
127+
}
128+
return agent_picks
129+
}
85130

86131
const close_button = {
87132
iconPath: new vscode.ThemeIcon('close'),
88133
tooltip: t('common.close')
89134
}
90135

91-
const agent_quick_pick = vscode.window.createQuickPick<
92-
vscode.QuickPickItem & { cmd: string }
93-
>()
94-
agent_quick_pick.items = agent_picks
136+
const agent_quick_pick = vscode.window.createQuickPick<AgentPickItem>()
137+
agent_quick_pick.items = build_agent_picks()
95138
agent_quick_pick.title = t('feature.search-files.agent.select-agent')
96139
agent_quick_pick.placeholder = t(
97140
'feature.search-files.agent.select-agent-placeholder'
98141
)
99142
agent_quick_pick.buttons = [vscode.QuickInputButtons.Back, close_button]
100143
agent_quick_pick.ignoreFocusOut = true
101144

102-
const selected_agent_cmd = await new Promise<
103-
string | undefined | 'back' | { edit_agent: string }
104-
>((resolve) => {
105-
let is_resolved = false
106-
107-
agent_quick_pick.onDidTriggerButton((button) => {
108-
if (button === vscode.QuickInputButtons.Back) {
109-
is_resolved = true
110-
resolve('back')
111-
agent_quick_pick.hide()
112-
} else if (button === close_button) {
113-
is_resolved = true
114-
resolve(undefined)
115-
agent_quick_pick.hide()
116-
}
117-
})
145+
const config_listener = vscode.workspace.onDidChangeConfiguration((e) => {
146+
if (e.affectsConfiguration('codeWebChat')) {
147+
agent_quick_pick.items = build_agent_picks()
148+
}
149+
})
118150

119-
agent_quick_pick.onDidTriggerItemButton((e) => {
120-
if (e.button === doc_button) {
121-
const agent = available_agents.find((a) => a.cmd == e.item.cmd)
122-
if (agent) {
123-
vscode.env.openExternal(
124-
vscode.Uri.parse(agent.get_documentation_url())
125-
)
151+
type AgentSelectionResult =
152+
| 'back'
153+
| undefined
154+
| { action: 'run'; cmd: string; flag_value: string }
155+
| { action: 'edit'; configKey: string; index: number; value: string }
156+
| { action: 'add'; configKey: string }
157+
158+
const agent_selection_result = await new Promise<AgentSelectionResult>(
159+
(resolve) => {
160+
let is_resolved = false
161+
162+
agent_quick_pick.onDidTriggerButton((button) => {
163+
if (button === vscode.QuickInputButtons.Back) {
164+
is_resolved = true
165+
resolve('back')
166+
agent_quick_pick.hide()
167+
} else if (button === close_button) {
168+
is_resolved = true
169+
resolve(undefined)
170+
agent_quick_pick.hide()
126171
}
127-
} else if (e.button === edit_button) {
128-
is_resolved = true
129-
resolve({ edit_agent: e.item.cmd })
130-
agent_quick_pick.hide()
131-
}
132-
})
172+
})
173+
174+
agent_quick_pick.onDidTriggerItemButton((e) => {
175+
if (e.button === doc_button) {
176+
const agent = available_agents.find((a) => a.cmd == e.item.cmd)
177+
if (agent) {
178+
vscode.env.openExternal(
179+
vscode.Uri.parse(agent.get_documentation_url())
180+
)
181+
}
182+
} else if (e.button === edit_button) {
183+
is_resolved = true
184+
resolve({
185+
action: 'edit',
186+
configKey: e.item.configKey,
187+
index: e.item.flag_index,
188+
value: e.item.flag_value
189+
})
190+
agent_quick_pick.hide()
191+
} else if (e.button === add_button) {
192+
is_resolved = true
193+
resolve({ action: 'add', configKey: e.item.configKey })
194+
agent_quick_pick.hide()
195+
} else if (e.button === delete_button) {
196+
const config = vscode.workspace.getConfiguration('codeWebChat')
197+
const flags = config
198+
.get<string[]>(e.item.configKey, [])
199+
.filter((f) => f.trim() !== '')
200+
const deleted_flag = flags[e.item.flag_index]
201+
const new_flags_array = flags.filter((_, i) => i !== e.item.flag_index)
202+
203+
config.update(
204+
e.item.configKey,
205+
new_flags_array,
206+
vscode.ConfigurationTarget.Global
207+
).then(() => {
208+
const undo_action = t('common.undo')
209+
vscode.window.showInformationMessage(
210+
t('feature.search-files.agent.deleted' as any),
211+
undo_action
212+
).then((choice) => {
213+
if (choice === undo_action) {
214+
const current_config = vscode.workspace.getConfiguration('codeWebChat')
215+
const current_flags = current_config
216+
.get<string[]>(e.item.configKey, [])
217+
.filter((f) => f.trim() !== '')
218+
current_flags.splice(e.item.flag_index, 0, deleted_flag)
219+
current_config.update(
220+
e.item.configKey,
221+
current_flags,
222+
vscode.ConfigurationTarget.Global
223+
)
224+
}
225+
})
226+
})
227+
}
228+
})
133229

134-
agent_quick_pick.onDidAccept(() => {
230+
agent_quick_pick.onDidAccept(() => {
135231
const selected = agent_quick_pick.selectedItems[0]
136232
if (selected) {
137233
is_resolved = true
138-
resolve(selected.cmd)
234+
resolve({
235+
action: 'run',
236+
cmd: selected.cmd,
237+
flag_value: selected.flag_value
238+
})
139239
agent_quick_pick.hide()
140240
}
141241
})
@@ -144,44 +244,77 @@ export const perform_agent_search_mode = async (params: {
144244
if (!is_resolved) {
145245
resolve(undefined)
146246
}
247+
config_listener.dispose()
147248
agent_quick_pick.dispose()
148249
})
149250

150251
agent_quick_pick.show()
151252
}
152253
)
153254

154-
if (selected_agent_cmd == 'back') {
255+
if (agent_selection_result == 'back') {
155256
return 'back'
156257
}
157258

158-
if (!selected_agent_cmd) {
259+
if (!agent_selection_result) {
159260
return undefined
160261
}
161262

162-
if (
163-
typeof selected_agent_cmd === 'object' &&
164-
'edit_agent' in selected_agent_cmd
165-
) {
166-
const cmd = selected_agent_cmd.edit_agent
167-
const key = get_agent_flags_state_key(cmd)
168-
const current_flags =
169-
params.extension_context.globalState.get<string>(key) || ''
263+
if (agent_selection_result.action === 'add') {
264+
const { configKey } = agent_selection_result
265+
const new_flags = await vscode.window.showInputBox({
266+
title: t('feature.search-files.agent.add-flags'),
267+
prompt: t('feature.search-files.agent.edit-flags-prompt'),
268+
placeHolder: t('feature.search-files.agent.edit-flags-placeholder'),
269+
value: '',
270+
ignoreFocusOut: true
271+
})
272+
if (new_flags !== undefined && new_flags.trim() !== '') {
273+
const config = vscode.workspace.getConfiguration('codeWebChat')
274+
const flags = config
275+
.get<string[]>(configKey, [])
276+
.filter((f) => f.trim() !== '')
277+
await config.update(
278+
configKey,
279+
[...flags, new_flags],
280+
vscode.ConfigurationTarget.Global
281+
)
282+
}
283+
continue
284+
}
170285

286+
if (agent_selection_result.action === 'edit') {
287+
const { configKey, index, value } = agent_selection_result
171288
const new_flags = await vscode.window.showInputBox({
172289
title: t('feature.search-files.agent.edit-flags'),
173290
prompt: t('feature.search-files.agent.edit-flags-prompt'),
174291
placeHolder: t('feature.search-files.agent.edit-flags-placeholder'),
175-
value: current_flags,
292+
value: value,
176293
ignoreFocusOut: true
177294
})
178-
179295
if (new_flags !== undefined) {
180-
await params.extension_context.globalState.update(key, new_flags)
296+
const config = vscode.workspace.getConfiguration('codeWebChat')
297+
const flags = config
298+
.get<string[]>(configKey, [])
299+
.filter((f) => f.trim() !== '')
300+
const new_flags_array = [...flags]
301+
if (new_flags.trim() !== '') {
302+
new_flags_array[index] = new_flags
303+
} else {
304+
new_flags_array.splice(index, 1)
305+
}
306+
await config.update(
307+
configKey,
308+
new_flags_array,
309+
vscode.ConfigurationTarget.Global
310+
)
181311
}
182312
continue
183313
}
184314

315+
const selected_agent_cmd = agent_selection_result.cmd
316+
const flags_string = agent_selection_result.flag_value
317+
185318
let go_back_to_agent = false
186319

187320
while (true) {
@@ -330,11 +463,6 @@ export const perform_agent_search_mode = async (params: {
330463
const executable = agent_info.cmd
331464
const base_args = agent_info.get_args(query)
332465

333-
const flags_string =
334-
params.extension_context.globalState.get<string>(
335-
get_agent_flags_state_key(executable)
336-
) || ''
337-
338466
const custom_args: string[] = []
339467
if (flags_string.trim()) {
340468
const regex = /([^\s'"]+)|"([^"]*)"|'([^']*)'/g

0 commit comments

Comments
 (0)