ACP input: @ file picker and clipboard image paste - #60
Conversation
Extend the ACP buffer input with two context features aligned with Zed and the Agent Client Protocol: - Typing @ opens a fuzzy picker of git-visible workspace files; selecting a file inserts @relative/path into the prompt. - On submit, @-mentions are resolved to embedded Resource content blocks (with ResourceLink fallback) alongside the text block. - Ctrl+Shift+V pastes clipboard images as pending attachments using SDL3 clipboard image MIME types (image/png, jpeg, webp, gif), with a file-path fallback for copied image files. - Prompts are sent as multi-block ACP PromptRequest payloads including Text, Resource, and Image ContentBlocks per the ACP spec. Co-authored-by: samwdp <samwdp@gmail.com>
|
Cursor Agent can help with this pull request. Just |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 76dde128ea
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let Some(root) = workspace_root else { | ||
| return Ok(()); | ||
| }; | ||
| let files = list_repository_files(&root).unwrap_or_default(); |
There was a problem hiding this comment.
Resolve picker paths relative to the workspace
When the workspace root is a subdirectory of a larger Git repository, every picker result resolves incorrectly. list_repository_files runs git ls-files --full-name (crates/editor-git/src/lib.rs:437-443), and git ls-files -h defines that option as “make the output relative to the project top directory”; for a workspace at /repo/sub, it returns sub/file, but this code later joins it as /repo/sub/sub/file. Selecting such an entry therefore sends a fallback link instead of the file contents, so the paths must be rebased from the repository top or emitted relative to root.
Useful? React with 👍 / 👎.
| fn acp_file_completion_query(text: &str) -> Option<&str> { | ||
| let at_index = text.rfind('@')?; | ||
| let after = &text[at_index + 1..]; |
There was a problem hiding this comment.
Require a token boundary before treating @ as a file mention
When ordinary text ends in an email address or handle, such as send to foo@example.com, this unconditional rfind('@') opens the file picker; pressing Enter then submits the selected picker entry rather than the prompt and replaces the address suffix. The submit parser applies the same unrestricted interpretation and can also attach a workspace file named example.com or add a bogus resource link, so @ should only trigger at the start of input or after an accepted token boundary.
Useful? React with 👍 / 👎.
| let rest = &text[start..]; | ||
| let end = rest | ||
| .find(|character: char| character.is_whitespace()) | ||
| .unwrap_or(rest.len()); |
There was a problem hiding this comment.
Preserve whitespace in selected file references
When the picker returns a valid Git path containing whitespace, such as docs/my file.md, it is inserted verbatim, but this parser stops the mention at the first whitespace and resolves only docs/my. The selected file is consequently never embedded and the agent receives an incorrect resource link; picker selections need quoting/escaping or structured tracking instead of whitespace-delimited reparsing.
Useful? React with 👍 / 👎.
| user_lines.extend(acp_render_content_block( | ||
| block, | ||
| prefix, | ||
| AcpColorRole::Accent, | ||
| )); |
There was a problem hiding this comment.
Render attached resources without reporting an error
Whenever a user submits an @ file reference, UserMessage passes its new ContentBlock::Resource through acp_render_content_block, whose resource branch renders the warning “Unsupported ACP content block.” Thus every successful file attachment is shown as an error in the conversation even though it was sent to the agent; user resources should render a file/link summary or be omitted from the visible block list.
Useful? React with 👍 / 👎.
Summary
Extends the ACP buffer input with two context features modeled after Zed and the Agent Client Protocol content spec:
@ file picker
@in the ACP input opens a fuzzy picker of git-visible workspace files (git ls-files --cached --others --exclude-standard).@relative/pathinto the message.@-mentions are resolved to embeddedContentBlock::Resourceblocks (text or blob) withResourceLinkfallback, sent alongside the text block in the ACPPromptRequest.Image paste
Ctrl+Shift+Vin the ACP input checks clipboard image MIME types first (image/png,image/jpeg,image/webp,image/gif) via SDL3SDL_GetClipboardData.ContentBlock::Imagewith base64 payload per ACP.Testing
Added unit tests:
acp_file_completion_query_detects_trailing_at_mention_tokenparse_at_mentions_collects_unique_pathsbuild_acp_prompt_blocks_embeds_text_files_and_imagesclipboard_image_from_path_text_reads_supported_image_files