Skip to content

ACP input: @ file picker and clipboard image paste - #60

Open
samwdp wants to merge 1 commit into
masterfrom
cursor/acp-input-file-picker-image-paste-81fc
Open

ACP input: @ file picker and clipboard image paste#60
samwdp wants to merge 1 commit into
masterfrom
cursor/acp-input-file-picker-image-paste-81fc

Conversation

@samwdp

@samwdp samwdp commented Aug 17, 2026

Copy link
Copy Markdown
Owner

Summary

Extends the ACP buffer input with two context features modeled after Zed and the Agent Client Protocol content spec:

@ file picker

  • Typing @ in the ACP input opens a fuzzy picker of git-visible workspace files (git ls-files --cached --others --exclude-standard).
  • Selecting a file inserts @relative/path into the message.
  • On submit, @-mentions are resolved to embedded ContentBlock::Resource blocks (text or blob) with ResourceLink fallback, sent alongside the text block in the ACP PromptRequest.

Image paste

  • Ctrl+Shift+V in the ACP input checks clipboard image MIME types first (image/png, image/jpeg, image/webp, image/gif) via SDL3 SDL_GetClipboardData.
  • If no raw image is present, a single-line clipboard path to an image file is loaded instead (avoids pasting a filepath string alongside image data, per Zed's approach).
  • Pasted images are held as pending attachments until submit, shown in the footer hint ("N images attached"), and sent as ContentBlock::Image with base64 payload per ACP.

Testing

Added unit tests:

  • acp_file_completion_query_detects_trailing_at_mention_token
  • parse_at_mentions_collects_unique_paths
  • build_acp_prompt_blocks_embeds_text_files_and_images
  • clipboard_image_from_path_text_reads_supported_image_files
cargo test -p editor-sdl build_acp_prompt_blocks acp_file_completion_query parse_at_mentions clipboard_image_from_path
Open in Web Open in Cursor 

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

cursor Bot commented Aug 17, 2026

Copy link
Copy Markdown

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +1238 to +1240
fn acp_file_completion_query(text: &str) -> Option<&str> {
let at_index = text.rfind('@')?;
let after = &text[at_index + 1..];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +1303 to +1306
let rest = &text[start..];
let end = rest
.find(|character: char| character.is_whitespace())
.unwrap_or(rest.len());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Comment on lines +7754 to +7758
user_lines.extend(acp_render_content_block(
block,
prefix,
AcpColorRole::Accent,
));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants