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 6 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".
| export function canResolveComposerHostFilePaths( | ||
| targetTag: ConnectionTarget["_tag"] | null, | ||
| ): boolean { | ||
| return targetTag === "PrimaryConnectionTarget"; |
There was a problem hiding this comment.
Exclude WSL-only primary backends from host-path mentions
In desktop WSL-only mode, this returns true because the WSL server still occupies the primary backend slot (DesktopBackendConfiguration.ts selects buildWslPrimaryConfig for that slot), while webUtils.getPathForFile returns a Windows host path. Dropping C:\Users\me\file.txt into a WSL project therefore inserts C:/Users/me/file.txt, which is not the file's Linux/WSL path and cannot be read by the agent. Include the actual primary backend kind in this gate, or translate Windows paths before enabling mentions.
AGENTS.md reference: AGENTS.md:L74-L74
Useful? React with 👍 / 👎.
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.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ded9627. Configure here.
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 introduces a new feature for handling non-image file drops/pastes as path mentions. An unresolved P1 comment identifies a bug in WSL-only mode where Windows paths would be inserted but are unreadable by the WSL agent. The combination of new capability and an identified implementation bug warrants human review. You can customize Macroscope's approvability policy. Learn more. |

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
window.desktopBridge.getPathForFile(Electron), and computing workspace-relative paths with platform-aware (Windows/POSIX) semantics.registerComposerInlineTokenPastein composerInlineTokenPaste.ts is extended to accept aresolvePastedFilePathcallback and insert mention nodes for pasted non-image files.replaceComposerFileLinksWithBasenamesin composerInlineTokens.ts.Macroscope summarized d544e80.
Note
Medium Risk
User-facing composer and prompt text change with cross-platform path rules; mistakes could point the agent at wrong or unreadable paths, though scope is limited to primary same-host desktop and covered by new unit tests.
Overview
Non-image OS files in the composer now become file path mentions (workspace-relative when under
gitCwd, otherwise absolute) instead of failing as unsupported attachments. Images still use the existing attachment flow; mixed drops attach images and mention the rest.Desktop exposes optional
getPathForFileonDesktopBridge(ElectronwebUtils) so the renderer can resolve dropped/pasted file paths afterFile.pathwas removed. Web has no path API and keeps image-only behavior with a clearer thread error when non-images are pasted without a resolvable path.Mentions are only built when the active environment is
PrimaryConnectionTargetand the resolved path style matches the environment OS (avoids unusable Windows paths against a Linux/WSL agent). NewcomposerFileDrophelpers partition drops, relativize paths, and wire through Lexical paste handling viaresolvePastedFilePath.Thread title seeds now run prompts through
replaceComposerFileLinksWithBasenamesso[name](path)markup does not show raw in the thread list.Reviewed by Cursor Bugbot for commit d544e80. Bugbot is set up for automated code reviews on this repo. Configure here.