dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
写时复制权限预设:shell 命令在工作区专属的 Sandboxie 沙盒内运行,工作区外的写入落进沙盒副本、真实磁盘不受影响(仅 Windows,需先安装 Sandboxie-Plus)。
中文版:README.zh.md
A DSH bundle that adds a fourth permission preset, Copy-on-write (写时复制): shell commands run inside a Sandboxie box dedicated to the workspace, so writes inside the workspace land on the real disk as usual, while writes, edits and deletions anywhere else keep succeeding — but only inside that box's copy. The three shipped presets (read-only, workspace-write, danger-full-access) behave exactly as before.
┌─ your DSH session ────────────────┐
│ file policy: copy-on-write │
│ │
│ shell command ──▶ Sandboxie box ─┼──▶ workspace writes → real disk
│ (inside the box) (per workspace)┼──▶ writes elsewhere → box copy
│ │ deletes elsewhere → tombstone in copy
│ read/write/edit ──▶ host process ┼──▶ unchanged: writable inside the
│ (outside the box) │ workspace, refused outside it
└───────────────────────────────────┘
| Term | Meaning |
|---|---|
| Real disk | Where files actually live (for example C:\Users\…). |
| Sandbox / box | The isolated environment Sandboxie creates. This plugin creates one per workspace. |
| Copy | The box's private storage for changes to files outside the workspace (under the sandbox root), kept apart from the real files. |
| Inside / outside the box | Under Copy-on-write, shell commands run inside the box; the DSH app and its file tools (read/write/edit) run outside it. |
| Merged view | What a command inside the box sees: the copy's content overlaid on the real file. |
| SandMan | Sandboxie-Plus's GUI, for inspecting, recovering and deleting sandboxes. |
Prerequisite: Sandboxie-Plus (source). The installer must have created its service; every box this plugin uses is created and managed by Sandboxie.
Any installation folder works — there is nothing to configure. The plugin does not assume Sandboxie lives in one fixed directory: it reads Sandboxie's own registry entries first (the SbieSvc service's ImagePath is the authority — an installation that can create a box always has it, followed by the driver service and the installer's uninstall entry), then the conventional folders and PATH, and only as a last resort sweeps well-known parent folders and each fixed drive's root for a folder named after Sandboxie that holds SbieDll.dll. Another drive, a per-user folder and a portable directory all work. Only when every one of those comes up empty does it report "not installed", and that message names DSH_SBIE_DIR (see Environment) as the way to point at it directly.
DSH's own installation folder is not assumed either. The koffi.node the launcher needs ships inside DSH, under its resources\app.asar.unpacked, and the launcher is a plain Node process with no process.resourcesPath. So the plugin locates DSH itself: the Node running the launcher (the desktop app's own runtime lives inside the installation, so that path points back at it), then the installer's uninstall entry, then the conventional folders and PATH. DSH installed on another drive works too.
The package is a DSH bundle: installing it also adds its configuration layer, so no profile file needs hand-editing.
# install into a profile (the CLI creates it if needed and appends this bundle)
dsh plugin --profile <profile> add @lone-wolf-akela/dsh-sandboxie-redirect
# check the layer without booting, then start
dsh --profile <profile> --dump-config # expect a "# == @lone-wolf-akela/dsh-sandboxie-redirect" layer
dsh --profile <profile>
Other supported sources, for a local checkout or an offline machine:
dsh plugin --profile <profile> add C:\path\to\dsh-sandboxie-redirect # a checkout (linked)
dsh plugin --profile <profile> add .\lone-wolf-akela-dsh-sandboxie-redirect-0.3.1.tgz
Which command for which profile? The CLI refuses to touch a profile that a running desktop app owns (
profile "desktop" is managed exclusively by the Electron application). For that profile, install from inside the app: Settings → Plugins → add a bundle, and give the package name above. For any other profile, the CLI works normally.
Then restart the client, open the permission dropdown, and select ❐ Copy-on-write 写时复制. The preset appears once per session as needed; the title bar shows the box name after the first shell command.
Earlier revisions were installed by copying the tree into ~/.dsh/plugins/dsh-sandboxie-redirect and adding rows to ~/.dsh/profiles/<profile>/cordis.patch.yml. If your profile still carries those rows, remove them before switching to the bundle channel: two active rows into the same dsh.client package fail the boot ("resolves from multiple active Loader sources"). The rows to delete are the ones whose name is an absolute path ending in lib\provider.mjs, plus the sandbox and permission rows this plugin added. tools/install.mjs remains in the repository for that manual channel, and it must be run outside the sandbox.
| Location | Behavior |
|---|---|
| Writes, edits, deletions inside the workspace | Applied directly to the real disk |
| Writes, edits outside the workspace | The command reports success, but the change lands in that workspace's box copy; the real disk is untouched |
| Deletions outside the workspace | The real file survives; the copy records only a deletion marker |
DSH's own file tools (read/write/edit) run outside the box and keep the workspace-write rule: writable inside the workspace, refused outside it. To read a file as the sandbox sees it, read it with a shell command — see Read-side divergence.
Under this preset the session's policy text gains a paragraph that tells the model how the mode behaves and what to watch for, so an agent does not have to infer it.
Under Copy-on-write the title bar shows the box name (for example dsh_able_willow; hover for the copy's root). It appears only when both hold: this session's preset is Copy-on-write, and this workspace really owns a box — so it shows up after the first command, and disappears when the preset changes or the box is cleaned.
The preset carries an icon (two overlapping sheets) in the dropdown and the bottom button, following the active theme. The preset's display name starts with ❐ for the same reason: the shipped dropdown takes icons from a closed id→icon map, so the name is the one surface that always renders.
sandbox_clear toolIn-session, sandbox_clear inspects or discards this workspace's copy: mode: "inspect" reports (file count, size), mode: "clear" deletes the copy and its configuration. It works in every permission mode, and can only ever touch boxes Sandboxie attributes to this workspace. A diagnostic mode: "status" reports what the session projection registry holds for the calling session — it separates "the fold never ran" from "the client never got it", so it is the first thing to look at when the title-bar box name is missing (it only actually worked from 0.3.3 on).
sandbox_permissions parameter description is not written for this preset. DSH generates that one text for every preset, and it reads as "the retry after a denial" — under Copy-on-write an out-of-workspace write is never denied (it succeeds into the copy), so no denial marker appears and there is nothing to retry. The session's policy text says so explicitly; escalation is a deliberate "run this one call on the real disk" lever, not a follow-up to a failure.<sandbox root>\drive\<drive>\<path>; paths under the user profile at <sandbox root>\user\current\<relative path>. Sandboxie's own sandbox folder is followed automatically (its FileRootPath, box setting or [GlobalSettings], with %USER%/%SANDBOX% expanded); DSH_SBIE_ROOT overrides that if you need it (see Environment).C:\Windows\Temp: modifying an existing file there may be refused — native Sandboxie behavior, not this plugin's. Creating and deleting files there works.sandbox_clear only deletes.sandbox_clear, or --manage clean) if you want the space back.node bin\dsh-sbie-run.mjs --manage list # list managed boxes
node bin\dsh-sbie-run.mjs --manage clean "<workspace>" # clean one workspace's boxes
node bin\dsh-sbie-run.mjs --manage delete-box <box> # delete one box
--manage must run outside the box (an ordinary terminal, or a danger-full-access session): a process inside a box cannot see Sandboxie's box list. The same operations are available in SandMan.
All optional; each exists as an escape hatch rather than a configuration surface.
| Variable | Effect |
|---|---|
DSH_SBIE_DIR | The Sandboxie installation folder (the one holding SbieDll.dll). Normally unnecessary: the automatic lookup reads Sandboxie's registry entries, the conventional folders and PATH first. Use it when Sandboxie lives somewhere unusual and that lookup misses it. |
DSH_SBIE_NODE | The node.exe that runs the launcher. Set it if the plugin cannot find one (the desktop app's own runtime, then $DSH_HOME/dsh-runtimes, are searched automatically). |
DSH_SBIE_ROOT | Overrides the sandbox root. Normally unnecessary: Sandboxie's configured FileRootPath is followed. Default %SystemDrive%\Sandbox\%USERNAME%. |
DSH_SBIE_LOG_DIR | Where diagnostics land. Default $DSH_HOME/state/dsh-sandboxie-redirect. |
DSH_SBIE_INI | The Sandboxie configuration file to read. Default %SystemDrive%\Windows\Sandboxie.ini. |
DSH_SBIE_KOFFI / DSH_SBIE_KOFFI_ROOT | A koffi.node (or a directory holding one) for the launcher. Normally unnecessary: DSH's own installation folder is located automatically (see Installation). |
DSH_SBIE_BOX / DSH_SANDBOX_ROOT | Set by the plugin inside a command; authoritative for "which box am I in" — never derive the name from the workspace path. |
Diagnostics: provider.log, host.log, tool.log under the log directory above. The host log is capped at 512 KB and records only state transitions.
sandbox row (@deepseek-ai/dsh-sandbox-local) and inserts this package's provider, which subclasses it: only the Copy-on-write preset is diverted, every other mode delegates to the stock ACL path. A configured runnerCommand cannot do this — it would apply to every mode.copy-on-write into the permission preset list, keeping whatever the layers before it contributed.bin/dsh-sbie-run.mjs, a plain-Node child process that holds the Sandboxie FFI. Sandboxie builds processes through its service and drops the standard handles, so stdio is relayed over a loopback TCP channel with length-prefixed frames.dsh_<adjective>_<noun>), so no state file is needed to find a workspace's box; a collision steps to the next candidate, and a name is only adopted when Sandboxie's own configuration says that workspace owns it.See CONTRIBUTING.md for setup and the development loop, and AGENTS.md for the architecture and the hard-won constraints. The short version:
npm test # unit + host projection + bundle-layer validation (no DSH, no Sandboxie)
npm run test:acceptance # acceptance: real boxes, real redirection (outside any box, medium IL)
npm run pack:check # what the published tarball would contain
Security issues: see SECURITY.md.
MIT — see LICENSE.