Fix inbound file handling and add cross-container file exchange#28
Open
lundog wants to merge 2 commits into
Open
Fix inbound file handling and add cross-container file exchange#28lundog wants to merge 2 commits into
lundog wants to merge 2 commits into
Conversation
Makes SimpleX file transfer work reliably in external mode, including when the simplex-chat runtime runs in a separate container sharing a volume rather than a filesystem. Transport-agnostic. Inbound: - Fix a file-receive race: queue the pending file and retry the accept on rcvFileDescrReady, cancelling on timeout, so a not-yet-ready XFTP descriptor no longer drops the file. - Stage received files into OpenClaw's media/inbound store so media tools and sandboxed workspaces can read them. - Resolve relative inbound paths against connection.filesFolder (default ~/.simplex/files, matching the runtime service) instead of a hardcoded /tmp. When the runtime runs with --files-folder it reports a bare file name, which is joined to filesFolder; absolute paths (no --files-folder) are read directly. - Log the reported inbound path (absolute vs relative) for diagnosability. Outbound: - Add connection.outboundFolder. When set, outbound media is staged into that directory before sending, and the staged path — valid inside the runtime's container when both sides mount the dir verbatim — is what travels over the WebSocket. Staged files are cleaned up after the send. Unset = legacy single-filesystem behavior (the local path is passed as-is). - Resolve media://<subdir>/<id> store references to a physical path on send (e.g. re-sending a received file). Config connection gains filesFolder and outboundFolder (types, schema, manifest). Adds unit tests for inbound resolution, outbound staging/cleanup, the readable-path guard, and media reference handling; documents both settings. Co-Authored-By: Claude Opus 4.8
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.
Why
Makes SimpleX file transfer reliable in external mode, including the common case where the
simplex-chatruntime runs in a container (a filesystem OpenClaw doesn't share) while OpenClaw runs on the host or in its own container. It's transport-agnostic — no native-mode code — and everything is additive and backward compatible (unset config = today's behavior).This is the file-exchange half of the earlier native-mode PR, split out per that PR's discussion so it can be reviewed and land on its own. A native-transport PR follows, stacked on top of this branch.
What
Inbound
rcvFileDescrReady, cancelling on timeout — a not-yet-ready XFTP descriptor no longer drops the file.media/inboundstore so media tools and sandboxed workspaces can read them.connection.filesFolder(default~/.simplex/files, matching the bundled runtime service). When the runtime runs with--files-folderit reports a bare file name, which is joined tofilesFolder; without it, the runtime reports absolute paths and they're read directly.Outbound
connection.outboundFolder. When set, outbound media is staged there before sending, and the staged path — valid on the runtime's side — is what travels over the WebSocket. Staged files are cleaned up after the send. Unset = the local path is passed as-is (single-filesystem default).connection.outboundFolderOnClientfor split-path deployments where the two sides mount the shared directory at different paths: the plugin stages intooutboundFolderbut rewrites the directory prefix to this before sending, so no verbatim/matching path is required. No effect withoutoutboundFolder.media://<subdir>/<id>store references to a physical path on send (e.g. re-sending a received file).Housekeeping
wsto^8.21.0(dependency-audit fix).Config
connectiongainsfilesFolderandoutboundFolder(types, Zod schema, regenerated manifest). Adds unit tests for inbound resolution, outbound staging/cleanup, the readable-path guard, and media reference handling; documents both settings in the config reference and the runtime-setup guide (symmetric inbound/outbound sections).Compatibility
Additive and backward compatible: existing configs are unaffected, and with
filesFolder/outboundFolderunset the plugin behaves exactly as before.Testing
Validated end-to-end against a containerized
simplex-chatruntime with OpenClaw on the host, sharing an inbound volume and a verbatim outbound mount:filesFolder, staged intomedia/inbound.media://store reference, and anhttp(s)URL — each staged into the shared outbound dir, delivered, and cleaned up.tsc,biome, andvitestall green.