feat(chat): accept OS file-manager drops as external context - #64
Merged
Merged
Conversation
Finder/Explorer drags previously fell through to the browser's default drop and pasted the file's content into the composer. Claim these drags in the composer drop zone: directories and non-image files become external context roots (the scanner now accepts a single file as a context root), images keep attaching via the image manager, and the drop is always preventDefaulted so no text is inserted. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
Round out OS drag-and-drop support: resolve dropped files through Electron's webUtils.getPathForFile (File.path was removed in Electron 32), claim the drag lifecycle on the window capture phase so host-level interceptors cannot swallow real Finder/Explorer drops, and scope claiming to drags that end inside the composer. Drops now report the added path or the rejection reason, and the external-context badge shows the count even for a single path. Add a protocol-driven e2e check (npm run test:e2e:file-drop) that drives a folder drop through Chromium's input protocol against a running Obsidian. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
`@root/` previously stayed unresolved in outgoing prompts because the external mention resolver required a file path after the root. Resolve the bare root to the context root's absolute path so external folders behave like vault folder mentions. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
Selecting an external context root inserted `@root/` without a chip and then immediately reopened the dropdown drilled into that root's files, so the whole-folder reference never settled. Register a folder chip for the root and insert `@root/ ` with a trailing space; typing `/` still drills into the root's files. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
User-message bubbles only chipped `@path` tokens that resolved inside the vault, so an external context root or file mention stayed raw text after sending. Recognize external context roots by name (`@root/` chips as a folder, `@root/relative/path` as a file), which needs no scan on the render path, and pass the tab's external contexts into the renderer. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
External chips now carry their absolute path, and clicking one opens it in Finder/Explorer through Electron's shell instead of silently failing the vault lookup. Vault chips keep Obsidian's reveal behavior. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
The render catch replaced content with a generic message and swallowed the cause, so a render regression looked like a plain text failure with no diagnostic trail. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
Persistence validated paths with the directory-only check, so a file root added by an OS drop could not be kept across sessions and the rejection message was misleading. Validate with the file-tolerant check and filter persisted settings paths the same way. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
filterValidPaths and isValidDirectoryPath lost their last production caller when persistence switched to the file-tolerant validators. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
dragenter fires for every child element under the pointer, and Obsidian's class helpers rewrite the attribute even when the value is unchanged. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
Windows normalizes the path separators, so asserting the exact POSIX literal failed there. Co-authored-by: QoderAI (Qwen 3.8 Max) <qoder_ai@qoder.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
webUtils.getPathForFile(the replacement forFile.path, removed in Electron 32) with atext/uri-listfallback. Images keep attaching through the image manager, and every OS drag is claimed (window-capture listeners) so the dropped file's content is never pasted into the input as text.@mentions: selecting one inserts@root/with a folder chip and settles (typing/still drills into its files), and a bare@root/resolves to the root's absolute path at send time.npm run test:e2e:file-drop) plus a CONTRIBUTING note.Verification
npm run typechecknpm run lintnpm run test— 164 suites / 3536 tests passnpm run test:e2e:file-drop— 4/4 against a running Obsidian (folder drop → external context, notice + badge, dragover accepted before simulated host interception, dropped content not pasted)shell.showItemInFolder(<path>); single-file persistence round-trips through settingsSafety
CHANGELOG.mdCo-authored-by: QoderAI (Qwen 3.8 Max) qoder_ai@qoder.com