Skip to content

Commit 82e83db

Browse files
committed
Add temporary directory copying for checked files in agentic CLI panel prompts and update path resolution for multi-root workspaces
- for cli invocation for edit/ask prompt types: copy all selected files (possibly spanning multple root folders) in a single temporary directory and invoke the cli from this temp directory (so without asking for root-folder in a mulit-root folder workspaces). for agentic search: keep asking for root folder in a multi root-folder workspaces. └── apps └── editor └── src ├── constants │ └── instructions.ts ├── context │ └── providers │ └── workspace │ └── workspace-provider.ts ├── utils │ └── agentic-cli-invocation │ └── invoke-agentic-cli.ts └── views └── prompt └── backend └── message-handlers ├── handle-copy-prompt.ts ├── handle-invoke-agentic-cli.ts ├── handle-preview-prompt.ts ├── handle-save-prompt-image.ts └── utils └── build-cli-prompt.ts
1 parent acd5968 commit 82e83db

4 files changed

Lines changed: 113 additions & 83 deletions

File tree

‎apps/editor/src/constants/instructions.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,9 @@ export const voice_input_instructions =
7171

7272
export const cli_requirements = {
7373
preloaded_files:
74-
'Tool calling is disabled with exception to media and web access in [task](#task).',
74+
'Tool calling is disabled with exception to media/web access in [task](#task).',
7575
referenced_files_with_some_preloaded:
76-
'Tool calling is disabled with exception to reading large files provided as project-relative paths in [files](#files) and media and web access in [task](#task). Begin by reading large files from [files](#files) in full.',
76+
'Tool calling is disabled with exception to reading large files provided as project-relative paths in [files](#files) and media/web access in [task](#task). You must begin by reading large files from [files](#files) in full.',
7777
referenced_files_only:
78-
'Tool calling is disabled with exception to reading files provided as project-relative paths in [files](#files) and media and web access in [task](#task). Begin by reading files from [files](#files) in full.',
78+
'Tool calling is disabled with exception to reading files provided as project-relative paths in [files](#files) and media/web access in [task](#task). You must begin by reading files from [files](#files) in full.',
7979
}

‎apps/editor/src/utils/agentic-cli-invocation/invoke-agentic-cli.ts‎

Lines changed: 96 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as vscode from 'vscode'
22
import * as os from 'os'
3+
import * as fs from 'fs'
4+
import * as path from 'path'
35
import { WorkspaceProvider } from '@/context/providers/workspace/workspace-provider'
46
import { t } from '@/i18n'
57
import { spawn } from 'child_process'
@@ -26,7 +28,7 @@ export const invoke_agentic_cli = async (params: {
2628
last_used_agent_config_name?: string
2729
last_selected_workspace_state_key: string
2830
show_back_button?: boolean
29-
cli_prompt_type?: 'edit-files' | 'ask-about-files'
31+
panel_prompt_type?: 'edit-files' | 'ask-about-files'
3032
cli_configuration_name?: string
3133
use_quick_pick?: boolean
3234
on_agent_selected?: (name: string) => void
@@ -299,90 +301,108 @@ export const invoke_agentic_cli = async (params: {
299301
while (true) {
300302
let selected_root: string | undefined
301303

302-
if (roots.length == 1) {
303-
selected_root = roots[0]
304+
if (params.panel_prompt_type) {
305+
const temp_dir_path = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'cwc-cli-'))
306+
const checked_files = params.workspace_provider.get_checked_files()
307+
308+
for (const file_path of checked_files) {
309+
const root = params.workspace_provider.get_workspace_root_for_file(file_path)
310+
if (!root) continue
311+
const rel = path.relative(root, file_path)
312+
const dest_rel = roots.length > 1 ? path.join(params.workspace_provider.get_workspace_name(root), rel) : rel
313+
const dest_path = path.join(temp_dir_path, dest_rel)
314+
315+
await fs.promises.mkdir(path.dirname(dest_path), { recursive: true })
316+
await fs.promises.copyFile(file_path, dest_path)
317+
}
318+
319+
selected_root = temp_dir_path
304320
} else {
305-
const picks = roots.map((root) => ({
306-
label: params.workspace_provider.get_workspace_name(root),
307-
description: root,
308-
root
309-
}))
310-
311-
const last_selected_root =
312-
params.extension_context.workspaceState.get<string>(
313-
params.last_selected_workspace_state_key
321+
if (roots.length == 1) {
322+
selected_root = roots[0]
323+
} else {
324+
const picks = roots.map((root) => ({
325+
label: params.workspace_provider.get_workspace_name(root),
326+
description: root,
327+
root
328+
}))
329+
330+
const last_selected_root =
331+
params.extension_context.workspaceState.get<string>(
332+
params.last_selected_workspace_state_key
333+
)
334+
const active_item =
335+
picks.find((p) => p.root == last_selected_root) || picks[0]
336+
337+
const quick_pick = vscode.window.createQuickPick<
338+
vscode.QuickPickItem & { root: string }
339+
>()
340+
quick_pick.items = picks
341+
if (active_item) {
342+
quick_pick.activeItems = [active_item]
343+
}
344+
quick_pick.title = t(
345+
'utils.agentic-cli-invocation.agent.select-workspace'
346+
)
347+
quick_pick.placeholder = t(
348+
'utils.agentic-cli-invocation.agent.select-workspace-placeholder'
314349
)
315-
const active_item =
316-
picks.find((p) => p.root == last_selected_root) || picks[0]
350+
quick_pick.buttons = [vscode.QuickInputButtons.Back, close_button]
351+
quick_pick.ignoreFocusOut = true
352+
353+
const res = await new Promise<string | undefined | 'back'>(
354+
(resolve) => {
355+
let is_resolved = false
356+
357+
quick_pick.onDidTriggerButton((button) => {
358+
if (button === vscode.QuickInputButtons.Back) {
359+
is_resolved = true
360+
resolve('back')
361+
quick_pick.hide()
362+
} else if (button === close_button) {
363+
is_resolved = true
364+
resolve(undefined)
365+
quick_pick.hide()
366+
}
367+
})
317368

318-
const quick_pick = vscode.window.createQuickPick<
319-
vscode.QuickPickItem & { root: string }
320-
>()
321-
quick_pick.items = picks
322-
if (active_item) {
323-
quick_pick.activeItems = [active_item]
324-
}
325-
quick_pick.title = t(
326-
'utils.agentic-cli-invocation.agent.select-workspace'
327-
)
328-
quick_pick.placeholder = t(
329-
'utils.agentic-cli-invocation.agent.select-workspace-placeholder'
330-
)
331-
quick_pick.buttons = [vscode.QuickInputButtons.Back, close_button]
332-
quick_pick.ignoreFocusOut = true
333-
334-
const res = await new Promise<string | undefined | 'back'>(
335-
(resolve) => {
336-
let is_resolved = false
337-
338-
quick_pick.onDidTriggerButton((button) => {
339-
if (button === vscode.QuickInputButtons.Back) {
340-
is_resolved = true
341-
resolve('back')
342-
quick_pick.hide()
343-
} else if (button === close_button) {
344-
is_resolved = true
345-
resolve(undefined)
346-
quick_pick.hide()
347-
}
348-
})
369+
quick_pick.onDidAccept(() => {
370+
const selected = quick_pick.selectedItems[0]
371+
if (selected) {
372+
is_resolved = true
373+
resolve(selected.root)
374+
quick_pick.hide()
375+
}
376+
})
349377

350-
quick_pick.onDidAccept(() => {
351-
const selected = quick_pick.selectedItems[0]
352-
if (selected) {
353-
is_resolved = true
354-
resolve(selected.root)
355-
quick_pick.hide()
356-
}
357-
})
378+
quick_pick.onDidHide(() => {
379+
if (!is_resolved) {
380+
resolve('back')
381+
}
382+
quick_pick.dispose()
383+
})
358384

359-
quick_pick.onDidHide(() => {
360-
if (!is_resolved) {
361-
resolve('back')
362-
}
363-
quick_pick.dispose()
364-
})
385+
quick_pick.show()
386+
}
387+
)
365388

366-
quick_pick.show()
389+
if (res == 'back') {
390+
go_back_to_agent = true
391+
show_quick_pick = true
392+
current_agent_config_name = undefined
393+
break
367394
}
368-
)
369395

370-
if (res == 'back') {
371-
go_back_to_agent = true
372-
show_quick_pick = true
373-
current_agent_config_name = undefined
374-
break
375-
}
396+
if (!res) {
397+
return undefined
398+
}
376399

377-
if (!res) {
378-
return undefined
400+
selected_root = res
401+
await params.extension_context.workspaceState.update(
402+
params.last_selected_workspace_state_key,
403+
selected_root
404+
)
379405
}
380-
381-
selected_root = res
382-
await params.extension_context.workspaceState.update(
383-
params.last_selected_workspace_state_key,
384-
selected_root
385-
)
386406
}
387407

388408
const agent_info = CLI_AGENTS.find(
@@ -418,7 +438,7 @@ export const invoke_agentic_cli = async (params: {
418438
}
419439
}
420440

421-
if (params.cli_prompt_type === 'ask-about-files') {
441+
if (params.panel_prompt_type === 'ask-about-files') {
422442
const final_prompt = await params.build_prompt(selected_root!)
423443
const base_args = agent_info.get_ask_args
424444
? agent_info.get_ask_args(final_prompt)

‎apps/editor/src/views/prompt/backend/message-handlers/handle-invoke-agentic-cli.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export const handle_invoke_agentic_cli = async (
4040
last_used_agent_config_name,
4141
last_selected_workspace_state_key:
4242
LAST_SELECTED_WORKSPACE_IN_AGENTIC_CLI_STATE_KEY,
43-
cli_prompt_type: prompt_type,
43+
panel_prompt_type: prompt_type,
4444
cli_configuration_name: message.cli_configuration_name,
4545
use_quick_pick: message.use_quick_pick,
4646
on_agent_selected: (name: string) => {

‎apps/editor/src/views/prompt/backend/message-handlers/utils/build-cli-prompt.ts‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ export const build_cli_prompt = async (params: {
2828
image_as_paths: true
2929
})
3030

31+
const roots = prompt_view_provider.workspace_provider.get_workspace_roots()
32+
3133
if (!selected_root) {
32-
const roots = prompt_view_provider.workspace_provider.get_workspace_roots()
3334
const last_selected_root =
3435
prompt_view_provider.extension_context.workspaceState.get<string>(
3536
LAST_SELECTED_WORKSPACE_IN_AGENTIC_CLI_STATE_KEY
@@ -47,8 +48,17 @@ export const build_cli_prompt = async (params: {
4748
let total_content_length = 0
4849

4950
for (const f of checked_files) {
50-
const rel = selected_root ? path.relative(selected_root, f) : f
51-
const relative_path = (rel.startsWith('..') ? f : rel).replace(/\\/g, '/')
51+
const root = prompt_view_provider.workspace_provider.get_workspace_root_for_file(f)
52+
let relative_path = f
53+
54+
if (root) {
55+
const rel = path.relative(root, f)
56+
const temp_rel = roots.length > 1 ? path.join(prompt_view_provider.workspace_provider.get_workspace_name(root), rel) : rel
57+
relative_path = temp_rel.replace(/\\/g, '/')
58+
} else {
59+
const rel = selected_root ? path.relative(selected_root, f) : f
60+
relative_path = (rel.startsWith('..') ? f : rel).replace(/\\/g, '/')
61+
}
5262

5363
try {
5464
const content = await fs.readFile(f, 'utf8')

0 commit comments

Comments
 (0)