Skip to content

Commit 5c94afd

Browse files
committed
Add dedicated workspace search action command and improve agent search progress feedback
- when agy runs, it feels like notification texts are not as informative as the orgiginal CLI output [Pasted text] - should not update output with 'Synthesizing results...' - Once agent finishes, show notification: Finished in 2m 30s. - when run agent, instead 'searching...', show 'waiting for agent...' - should not trim lines in the notification - the reported progress should be just a raw agent-made text, no 'Running:' prefix, or any other post processing - add missing commands to package json - when running 'search files...' from the command palette we're missing 'agent' option there └── apps └── editor ├── package.json └── src ├── commands │ └── search-files-commands │ ├── index.ts │ ├── search-files-commands.ts │ └── utils │ ├── get-target-folder-path.ts │ └── prompt-for-provided-results.ts ├── features │ └── search-files │ ├── index.ts │ ├── search-files.ts │ ├── search-modes │ │ ├── perform-agent-search-mode │ │ │ ├── agents │ │ │ │ ├── antigravity.ts │ │ │ │ ├── claude.ts │ │ │ │ ├── codex.ts │ │ │ │ ├── cursor.ts │ │ │ │ └── opencode.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── perform-intelligent-search-mode.ts │ │ ├── perform-keywords-search-mode.ts │ │ └── perform-phrase-search-mode.ts │ └── utils │ ├── analyze-files.ts │ ├── check-matches-condition.ts │ ├── create-search-regex.ts │ ├── group-quick-pick-items.ts │ ├── handle-parent-folder-result.ts │ ├── map-files-to-quick-pick-items.ts │ ├── prompt-for-config.ts │ ├── prompt-for-intelligent-search-results.ts │ ├── prompt-for-keywords-match-mode.ts │ ├── prompt-for-keywords-target.ts │ ├── prompt-for-search-mode.ts │ ├── prompt-for-search-results.ts │ ├── prompt-for-search-term.ts │ ├── prompt-for-shrink-mode.ts │ ├── search-files-by-intelligent.ts │ ├── search-files-by-keywords.ts │ ├── search-files-by-phrase.ts │ └── show-search-results-quick-pick.ts └── i18n └── translations ├── commands │ └── search-files.ts └── features └── search-files.ts
1 parent a0ba8e8 commit 5c94afd

10 files changed

Lines changed: 154 additions & 86 deletions

File tree

‎apps/editor/package.json‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,12 @@
343343
"category": "Code Web Chat",
344344
"icon": "$(search)"
345345
},
346+
{
347+
"command": "codeWebChat.searchFilesWorkspaceAction",
348+
"title": "%codeWebChat.searchFilesWorkspaceAction.title%",
349+
"category": "Code Web Chat",
350+
"icon": "$(search)"
351+
},
346352
{
347353
"command": "codeWebChat.searchSelectedFiles",
348354
"title": "%codeWebChat.searchSelectedFiles.title%",
@@ -576,6 +582,10 @@
576582
"command": "codeWebChat.generateCommitMessage",
577583
"when": "false"
578584
},
585+
{
586+
"command": "codeWebChat.searchFilesWorkspaceAction",
587+
"when": "false"
588+
},
579589
{
580590
"command": "codeWebChat.searchFilesFromDirectory",
581591
"when": "false"
@@ -676,7 +686,7 @@
676686
"group": "navigation@2"
677687
},
678688
{
679-
"command": "codeWebChat.searchFiles",
689+
"command": "codeWebChat.searchFilesWorkspaceAction",
680690
"when": "view == codeWebChatViewWorkspace",
681691
"group": "navigation@5"
682692
},

‎apps/editor/src/commands/search-files-commands/search-files-commands.ts‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ export const search_files_commands = (
197197
}
198198

199199
const folder_path = await get_target_folder_path(item)
200-
const is_workspace_action = options?.is_workspace_action ?? !folder_path
201200

202201
let all_files: string[] | undefined
203202

@@ -225,7 +224,7 @@ export const search_files_commands = (
225224
extension_context,
226225
websocket_manager,
227226
folder_path,
228-
is_workspace_action
227+
is_workspace_action: options?.is_workspace_action
229228
})
230229

231230
if (!result || result == 'back') return
@@ -301,7 +300,6 @@ export const search_files_commands = (
301300
is_workspace_action?: boolean
302301
}
303302
) => {
304-
let actual_item = item
305303
let actual_options = options
306304
if (
307305
item &&
@@ -312,11 +310,16 @@ export const search_files_commands = (
312310
item.is_workspace_action !== undefined)
313311
) {
314312
actual_options = item
315-
actual_item = undefined
316313
}
317-
return search_handler(actual_item, actual_options)
314+
return search_handler(undefined, {
315+
...(actual_options || {}),
316+
is_workspace_action: actual_options?.is_workspace_action ?? true
317+
})
318318
}
319319
),
320+
vscode.commands.registerCommand('codeWebChat.searchFilesWorkspaceAction', () =>
321+
search_handler(undefined, { is_workspace_action: true })
322+
),
320323
vscode.commands.registerCommand('codeWebChat.searchSelectedFiles', () =>
321324
search_selected_files_handler()
322325
),

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

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,44 +21,47 @@ export const antigravity_agent: CodingAgent = {
2121
if (step.step_type == 'tool') {
2222
const tool_name = step.tool_name || step.tool_info?.name
2323
if (tool_name) {
24-
let msg = `Using ${tool_name.replace(/_/g, ' ')}...`
24+
let msg = tool_name
2525
const params = step.tool_info?.parameters
2626

2727
if (params) {
28+
const formatted_name = tool_name.toLowerCase()
29+
2830
if (
29-
tool_name == 'run_command' &&
30-
(params.CommandLine || params.command)
31+
(formatted_name.includes('run') ||
32+
formatted_name.includes('command') ||
33+
formatted_name.includes('bash')) &&
34+
(params.CommandLine || params.command || params.cmd)
3135
) {
32-
msg = `Running: ${params.CommandLine || params.command}`
33-
} else if (tool_name == 'read_file' && params.path) {
34-
msg = `Reading: ${params.path}`
36+
msg = params.CommandLine || params.command || params.cmd
37+
} else if (formatted_name.includes('read') && params.path) {
38+
msg = params.path
3539
} else if (
36-
(tool_name == 'write_file' || tool_name == 'write_to_file') &&
40+
(formatted_name.includes('write') || formatted_name.includes('edit')) &&
3741
params.path
3842
) {
39-
msg = `Writing: ${params.path}`
40-
} else if (tool_name == 'list_directory' && params.path) {
41-
msg = `Listing: ${params.path}`
43+
msg = params.path
44+
} else if (formatted_name.includes('list') && params.path) {
45+
msg = params.path
4246
} else if (
43-
tool_name == 'search_files' &&
44-
(params.query || params.pattern)
47+
(formatted_name.includes('search') ||
48+
formatted_name.includes('find') ||
49+
formatted_name.includes('grep')) &&
50+
(params.query || params.pattern || params.description || params.keyword)
4551
) {
46-
msg = `Searching: ${params.query || params.pattern}`
52+
msg = params.query || params.pattern || params.description || params.keyword
53+
} else if (params.path) {
54+
msg = params.path
55+
} else if (params.command || params.cmd || params.CommandLine) {
56+
msg = params.command || params.cmd || params.CommandLine
4757
}
4858
}
4959

50-
if (msg.length > 60) {
51-
msg = msg.substring(0, 57) + '...'
52-
}
5360
report_progress(msg)
5461
}
5562
} else if (step.subagent_info?.subagents?.length > 0) {
5663
const subagent = step.subagent_info.subagents[0]
57-
report_progress(
58-
`Delegating to ${subagent.role || subagent.type_name}...`
59-
)
60-
} else if (step.step_type == 'agent_response') {
61-
report_progress('Synthesizing results...')
64+
report_progress(subagent.role || subagent.type_name)
6265
}
6366
} else if (parsed.event == 'result' && parsed.result) {
6467
return { output: parsed.result.response || '' }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const claude_agent: CodingAgent = {
2727
) {
2828
const tool_name = parsed.event.content_block.name
2929
if (tool_name) {
30-
report_progress(`Using ${tool_name.replace(/_/g, ' ')}...`)
30+
report_progress(tool_name)
3131
}
3232
}
3333
} else if (parsed.type == 'result' && parsed.result) {

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,10 @@ export const codex_agent: CodingAgent = {
1717
parse_stream_line: (parsed, report_progress) => {
1818
if (parsed.type == 'item.started' && parsed.item) {
1919
const item = parsed.item
20-
let msg = ''
2120
if (item.type == 'command_execution' && item.command) {
22-
msg = `Running: ${item.command}`
21+
report_progress(item.command)
2322
} else if (item.type) {
24-
msg = `Running ${item.type.replace(/_/g, ' ')}...`
25-
}
26-
if (msg) {
27-
if (msg.length > 60) {
28-
msg = msg.substring(0, 57) + '...'
29-
}
30-
report_progress(msg)
23+
report_progress(item.type)
3124
}
3225
} else if (parsed.type == 'item.completed' && parsed.item) {
3326
if (parsed.item.type == 'agent_message' && parsed.item.text) {

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

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ export const cursor_agent: CodingAgent = {
2222
if (tool_call) {
2323
let msg = ''
2424
if (tool_call.readToolCall?.args?.path) {
25-
msg = `Reading: ${tool_call.readToolCall.args.path}`
25+
msg = tool_call.readToolCall.args.path
2626
} else if (tool_call.writeToolCall?.args?.path) {
27-
msg = `Writing: ${tool_call.writeToolCall.args.path}`
27+
msg = tool_call.writeToolCall.args.path
2828
} else {
2929
const key = Object.keys(tool_call)[0]
3030
if (key) {
@@ -42,31 +42,28 @@ export const cursor_agent: CodingAgent = {
4242
formatted_name.includes('bash')) &&
4343
(args?.command || args?.cmd || args?.CommandLine)
4444
) {
45-
msg = `Running: ${args.command || args.cmd || args.CommandLine}`
45+
msg = args.command || args.cmd || args.CommandLine
4646
} else if (
4747
(formatted_name.includes('search') ||
4848
formatted_name.includes('grep') ||
4949
formatted_name.includes('find')) &&
5050
(args?.query || args?.pattern)
5151
) {
52-
msg = `Searching: ${args.query || args.pattern}`
52+
msg = args.query || args.pattern
5353
} else if (
5454
formatted_name.includes('list') &&
5555
args?.path
5656
) {
57-
msg = `Listing: ${args.path}`
57+
msg = args.path
5858
} else if (args?.path) {
59-
msg = `Accessing: ${args.path}`
59+
msg = args.path
6060
} else {
61-
msg = `Using ${formatted_name.replace(/_/g, ' ').trim()}...`
61+
msg = key
6262
}
6363
}
6464
}
6565

6666
if (msg) {
67-
if (msg.length > 60) {
68-
msg = msg.substring(0, 57) + '...'
69-
}
7067
report_progress(msg)
7168
}
7269
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const opencode_agent: CodingAgent = {
1717
],
1818
parse_stream_line: (parsed, report_progress) => {
1919
if (parsed.type == 'tool_call' && parsed.tool) {
20-
report_progress(`Using ${parsed.tool}...`)
20+
report_progress(parsed.tool)
2121
} else if (parsed.type == 'result' && parsed.result) {
2222
return {
2323
output:

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

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { codex_agent } from './agents/codex'
2020
import { cursor_agent } from './agents/cursor'
2121
import { opencode_agent } from './agents/opencode'
2222
import { CodingAgent } from './types'
23+
import { format_duration } from './utils'
2324

2425
const AGENTS: CodingAgent[] = [
2526
antigravity_agent,
@@ -200,32 +201,39 @@ export const perform_agent_search_mode = async (params: {
200201
.get<string[]>(e.item.configKey, [])
201202
.filter((f) => f.trim() !== '')
202203
const deleted_flag = flags[e.item.flag_index]
203-
const new_flags_array = flags.filter((_, i) => i !== e.item.flag_index)
204-
205-
config.update(
206-
e.item.configKey,
207-
new_flags_array,
208-
vscode.ConfigurationTarget.Global
209-
).then(() => {
210-
const undo_action = t('common.undo')
211-
vscode.window.showInformationMessage(
212-
t('feature.search-files.agent.deleted' as any),
213-
undo_action
214-
).then((choice) => {
215-
if (choice === undo_action) {
216-
const current_config = vscode.workspace.getConfiguration('codeWebChat')
217-
const current_flags = current_config
218-
.get<string[]>(e.item.configKey, [])
219-
.filter((f) => f.trim() !== '')
220-
current_flags.splice(e.item.flag_index, 0, deleted_flag)
221-
current_config.update(
222-
e.item.configKey,
223-
current_flags,
224-
vscode.ConfigurationTarget.Global
204+
const new_flags_array = flags.filter(
205+
(_, i) => i !== e.item.flag_index
206+
)
207+
208+
config
209+
.update(
210+
e.item.configKey,
211+
new_flags_array,
212+
vscode.ConfigurationTarget.Global
213+
)
214+
.then(() => {
215+
const undo_action = t('common.undo')
216+
vscode.window
217+
.showInformationMessage(
218+
t('feature.search-files.agent.deleted'),
219+
undo_action
225220
)
226-
}
221+
.then((choice) => {
222+
if (choice === undo_action) {
223+
const current_config =
224+
vscode.workspace.getConfiguration('codeWebChat')
225+
const current_flags = current_config
226+
.get<string[]>(e.item.configKey, [])
227+
.filter((f) => f.trim() !== '')
228+
current_flags.splice(e.item.flag_index, 0, deleted_flag)
229+
current_config.update(
230+
e.item.configKey,
231+
current_flags,
232+
vscode.ConfigurationTarget.Global
233+
)
234+
}
235+
})
227236
})
228-
})
229237
}
230238
})
231239

@@ -331,9 +339,10 @@ export const perform_agent_search_mode = async (params: {
331339
root
332340
}))
333341

334-
const last_selected_root = params.extension_context.workspaceState.get<string>(
335-
LAST_SELECTED_WORKSPACE_IN_AGENT_SEARCH_STATE_KEY
336-
)
342+
const last_selected_root =
343+
params.extension_context.workspaceState.get<string>(
344+
LAST_SELECTED_WORKSPACE_IN_AGENT_SEARCH_STATE_KEY
345+
)
337346
const active_item =
338347
picks.find((p) => p.root == last_selected_root) || picks[0]
339348

@@ -479,6 +488,7 @@ export const perform_agent_search_mode = async (params: {
479488
let agent_output = ''
480489
let raw_stream_output = ''
481490
let is_cancelled = false
491+
const start_time = Date.now()
482492

483493
try {
484494
await vscode.window.withProgress(
@@ -488,7 +498,7 @@ export const perform_agent_search_mode = async (params: {
488498
},
489499
async (progress, token) => {
490500
progress.report({
491-
message: t('feature.search-files.progress.searching')
501+
message: t('feature.search-files.agent.waiting-for-agent')
492502
})
493503

494504
return new Promise<void>((resolve, reject) => {
@@ -577,6 +587,11 @@ export const perform_agent_search_mode = async (params: {
577587
continue
578588
}
579589

590+
const duration = format_duration(Date.now() - start_time)
591+
vscode.window.showInformationMessage(
592+
t('feature.search-files.agent.finished', { duration })
593+
)
594+
580595
if (agent_output.trim() == '') {
581596
vscode.window.showInformationMessage(
582597
t('feature.search-files.no-files')
@@ -592,13 +607,10 @@ export const perform_agent_search_mode = async (params: {
592607
let prefix = ''
593608

594609
if (roots.length > 1 && selected_root) {
595-
const workspace_name = params.workspace_provider.get_workspace_name(
596-
selected_root
597-
)
610+
const workspace_name =
611+
params.workspace_provider.get_workspace_name(selected_root)
598612
prefix = `${workspace_name}/`
599-
const root_files = workspace_files.filter((f) =>
600-
f.startsWith(prefix)
601-
)
613+
const root_files = workspace_files.filter((f) => f.startsWith(prefix))
602614
const stripped_files = root_files.map((f) =>
603615
f.substring(prefix.length)
604616
)
@@ -614,9 +626,7 @@ export const perform_agent_search_mode = async (params: {
614626
new Set(
615627
valid_paths.map((p) => {
616628
const relative_path =
617-
prefix && p.startsWith(prefix)
618-
? p.substring(prefix.length)
619-
: p
629+
prefix && p.startsWith(prefix) ? p.substring(prefix.length) : p
620630
return path.join(selected_root!, relative_path)
621631
})
622632
)
@@ -637,7 +647,8 @@ export const perform_agent_search_mode = async (params: {
637647
| undefined
638648

639649
while (true) {
640-
const currently_checked = params.workspace_provider.get_checked_files()
650+
const currently_checked =
651+
params.workspace_provider.get_checked_files()
641652
const unmatched_checked_files =
642653
restored_unmatched_paths ??
643654
(params.is_search_in_selected

0 commit comments

Comments
 (0)