Repository navigation
feat(agent): browse and import local media from a browser-hosted editor - #200
Merged
Merged
Conversation
The built-in Agent's browse_local_media and import_* tools only had an Electron bridge, so a browser-hosted editor answered "desktop app only" even though the server already owns the probe/hash/reference/dedupe chain that offline MCP and occ use. Fall back to same-origin /api/local-media routes that run that same core and prefer the Electron bridge whenever it exists, so desktop behavior is unchanged. The routes share the editor's existing local-device write gate and deliberately do not inherit the desktop "empty AGENT_IMPORT_ROOTS allows everything" default: a page load carries no OS folder grant, so an empty allowlist refuses instead of exposing the machine. Out-of-root paths and symlink escapes are rejected by the existing core. Validated with lint, typecheck, the production build, the new route verify and the tool verify; the local test failures are pre-existing Windows-only issues that reproduce on a clean checkout.
# Conflicts: # CHANGELOG.md
This was referenced Oct 15, 2026
Open
0xsline
added a commit
that referenced
this pull request
Oct 15, 2026
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.
The built-in Agent's
browse_local_mediaandimport_*tools only worked through the Electron bridge, so a browser-hosted editor answered "available in the desktop app only" — even though the server already had the whole import core (probe, hash, reference registration, dedupe) that offline MCP andoccuse. This wires those tools to same-origin endpoints (/api/local-media/browse,/api/local-media/import) that run that same core, and keeps preferring the Electron bridge whenever it exists. Desktop behavior is unchanged.On safety: the endpoints reuse the editor's existing local-device write check (the same one the global request-shape gate applies), and they deliberately do not inherit the desktop default where an empty
AGENT_IMPORT_ROOTSallows everything. A page load carries no OS-level folder grant, so an empty allowlist refuses with403 / IMPORT_ROOTS_NOT_CONFIGUREDinstead of exposing the machine. Paths outside the allowlist, and symlink/junction escapes, are rejected by the existing core. So: desktop stays as-is, browser only sees the roots you list.On tests:
server/plugins/local-media.verify.tsdrives the real route over a loopback socket — cross-site and non-loopback 403, 405/400/413 handling, empty-allowlist 403, browse/search, a real probe+hash+import, dedupe, out-of-root and symlink-escape rejection, and that the plugin is actually registered inserverPlugins().src/agent/tools/agent-path-import-tools.verify.tscovers host resolution, the HTTP fallback, error-code preservation, and that the desktop bridge is still preferred. Tool descriptions, README (EN/ZH),.env.exampleand the CHANGELOG are updated.I ran lint,
tsc -b, the production build, the agent-skill check, the tool-catalog check, the registration/gate-coverage checks and both verifies above locally — all green. A couple of Windows-only verifies fail in my environment (EBUSY/EPERM temp cleanup, Windows path separators, a missingunzipfor the whisper prebuild); each one reproduces identically on a clean checkout ofmain, so they're unrelated to this change.One heads-up for self-hosting setups: because the whole editor write surface is local-device scoped, these routes are reachable from a browser that talks to the same machine running OpenChatCut (the usual reverse-proxy/tunnel arrangement). If your deployment differs, I'm glad to adjust.
Note on AI: I used AI assistance to draft this change, at my own request and under my direction. I've gone through the full diff, I understand how the routes, the auth gate and the allowlist fit together, and I verified the behavior and tests myself. Happy to change anything you'd prefer.
Closes #185.