feat(web): insert path mentions for non-image file drops and pastes - #5543
feat(web): insert path mentions for non-image file drops and pastes#5543kristjaningi wants to merge 12 commits into
Conversation
Dropping or pasting a non-image file into the composer previously failed with "Unsupported file type ... Please attach image files only." Referencing a file by dragging it into the prompt is a standard workflow in comparable tools, so non-image files now become file mention chips instead: - Drop: non-image files are partitioned away from the image-attachment flow and inserted as mentions at the end of the prompt, workspace-relative when the file lives inside the repo, absolute otherwise. Directories (empty MIME type) work the same way. Mixed drops attach the images and mention the rest. - Paste: the editor's paste command inserts mention chips at the cursor for non-image clipboard files, leaving images to the existing attachment path. - Desktop bridge: expose webUtils.getPathForFile as an optional DesktopBridge.getPathForFile, since Electron >= 32 removed File.path and the renderer cannot learn a dropped file's location otherwise. Browser tabs have no OS path access and keep the previous behavior. - Thread titles: seed titles now render file links as their basename instead of raw "[name](path)" markup. This also fixes titles for existing file-tree drag mentions. No contract or server protocol changes: mentions are plain prompt text, so remote environments and every provider handle them unchanged.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Backslash is a valid filename character on POSIX, so normalizing it to "/" turned a dropped /repo/a\b.txt into a mention for a/b.txt, a different or nonexistent file. Separator normalization (and the case-insensitive compare) now applies only when both sides are Windows paths.
Two workspaceRelativeDropPath fixes: - A POSIX workspace root of "/" trimmed to an empty string and bailed, so files under a filesystem-root workspace were mentioned by absolute path. The empty-root guard now checks the original input, and the separator appended for the prefix check restores the trimmed root. - The relative slice offset came from the lowercased comparable prefix, whose length can differ from the original for some Unicode (e.g. "İ" lowercases to two code points), truncating the result. Slice by the original root's length instead, and require the boundary character to be the separator so any residual misalignment falls back to the absolute path rather than a wrong relative one.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ded9627d13
ℹ️ 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".
In desktop WSL-only mode the WSL server occupies the primary backend slot, so the connection-target gate passed while webUtils.getPathForFile returned Windows host paths the Linux-side agent cannot read. Dropped files were mentioned as C:/... paths pointing nowhere. The resolver now also compares the resolved path's style against the selected environment's platform.os and treats mismatches as unresolvable, surfacing the existing per-environment error instead. Mismatches are rejected rather than translated because WSL mount roots are configurable and a guessed /mnt/c/... path would silently point at a nonexistent file.
A paste can land while a chip is node-selected, so $getSelection() is not a range selection and $insertPastedFileMentions bailed without inserting. Nothing downstream recovers: the default paste cannot turn files into mentions and the composer's paste handler prevents it while only reporting unresolvable files, so resolvable files vanished with no chip and no error. Fall back to a range selection at the end of the prompt instead of bailing.
ApprovabilityVerdict: Needs human review This PR adds a new feature (non-image file drop/paste to path mentions) with substantial new logic for cross-platform path resolution and desktop bridge integration. There is also an unresolved comment identifying a potential bug in error handling for mixed image/file drops. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 00bf04e0c2
ℹ️ 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".
Ported from pingdotgg#5543. Co-authored-by: Kristján Ingi <k.geirsson@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dcf162b71b
ℹ️ 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".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61f56a001e
ℹ️ 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".
serializeComposerFileLink treated every backslash as a directory separator, so a POSIX file named a\b.txt became a chip labeled b.txt. Basename handling is now platform-aware, and token parsing still accepts older Windows mentions that used a backslash as a separator.
addComposerImages clears the thread error on successful validation, so writing the mention-unavailable message after it hid a real attachment count error. Mixed drops now compose both messages in one write.
Non-image drops and pastes now insert path mentions on desktop, with different fallbacks in the browser and on remote or WSL-only environments. That is user-visible behavior and belongs in shipped docs.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4683aee. Configure here.
| const addComposerImages = async ( | ||
| files: File[], | ||
| options?: { fallbackThreadError?: string | null }, | ||
| ) => { |
There was a problem hiding this comment.
Mention error dropped on plan prompts
Medium Severity
Moving unresolved-file errors into addComposerImages via fallbackThreadError skips that path when plan questions are pending. The helper returns early after the image toast and never applies the fallback, and paste/drop only call setThreadError in the no-images branch, so a mixed image plus unresolved file no longer surfaces the mention error.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit 4683aee. Configure here.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4683aeefd0
ℹ️ 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".
| setThreadError( | ||
| threadId, | ||
| composeComposerFileDropThreadError(error, options?.fallbackThreadError ?? null), | ||
| ); |
There was a problem hiding this comment.
Preserve mention errors after image compression fails
When a mixed paste/drop contains an unavailable non-image file—for example, in a browser or remote environment—and an image that passes initial validation but later fails compression, the mention error is combined only here; the later setThreadError(threadId, compressionError) overwrites it. The non-image file is therefore omitted without explanation, so retain or merge fallbackThreadError when reporting asynchronous compression failures as well.
AGENTS.md reference: AGENTS.md:L74-L74
Useful? React with 👍 / 👎.


What
Dropping or pasting a non-image file into the composer currently fails with "Unsupported file type ... Please attach image files only." This PR turns those files into file mention chips instead, so the agent can read them where they already live:
webUtils.getPathForFileas an optionalDesktopBridgemethod (Electron >= 32 removedFile.path). Browser tabs have no OS path access; they keep the image-only flow with a clearer error.[name](path)markup (also fixes titles for existing file-tree drag mentions).Why this shape
Mentions are plain prompt text, so there are zero contract or server protocol changes. I'm aware of the orchestration V2 rework (#2829) that closed #4058 - this deliberately stays out of that layer entirely, and follows @juliusmarminge's suggestion there to just provide the path where the agent can find the file. Complementary to the attachment work in #3927.
Fixes #2126
Before Screenshots ⛔
After Screenshots ✅
Verification
Note
Insert path mentions for non-image file drops and pastes in the chat composer
composerFileDrop.tswith platform-aware path resolution, file partitioning, and error composition utilities used byChatComposer.getPathForFileonwindow.desktopBridgeviapreload.tsso the renderer can resolve on-disk paths for dropped files.replaceComposerFileLinksWithBasenamesinstead of raw markdown.Macroscope summarized 4683aee.
Note
Low Risk
Composer UX and prompt text only; no server protocol changes. Path gating limits wrong-filesystem mentions; extensive unit tests cover edge cases.
Overview
Non-image OS files dropped or pasted into the chat composer become file path mention chips (workspace-relative when inside the project, absolute otherwise) instead of failing as unsupported attachments. Images still use the existing attachment flow; mixed clipboard/drops attach images and mention the rest.
The desktop bridge adds optional
getPathForFilevia ElectronwebUtilsso the renderer can resolve dropped file paths. Mentions are only offered for the primary same-host environment, with Windows vs POSIX path-style checks (e.g. WSL-only) so bad paths are not sent to the agent; browser/remote/SSH cases keep image-only behavior with clearer thread errors.Lexical paste handling inserts mention chips for pasted non-image files; drop handling partitions files and appends serialized link text. Shared token/serialization logic now treats POSIX filenames with backslashes correctly. New thread titles seed from basenames via
replaceComposerFileLinksWithBasenamesinstead of raw[name](path)markup. User docs add a composer page describing images, mentions, and limits.Reviewed by Cursor Bugbot for commit 4683aee. Bugbot is set up for automated code reviews on this repo. Configure here.