dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Move a DeepSeek Harness workspace folder to a new path — session logs' cwd is rewritten too — and give every new session its own output folder under sessions/.DSH 插件:迁移工作区文件夹并改写会话日志的 cwd;为每个新会话建立独立输出目录;支持空闲会话的移动与删除。
A DeepSeek Harness (DSH) plugin: move a workspace folder to a new location, give every new session its own output folder, and restart the desktop app from the header.
English | 简体中文
DSH binds each session to a workspace directory, and every session of that workspace shares it — so scripts, logs, downloads and screenshots from unrelated conversations pile up in the same place. This plugin adds four things on top of that model, without patching DSH itself:
cwd is rewritten to the new path, so sessions keep working and stay listed under the new workspace.<workspace>/sessions/<YYYY-MM-DD>_<title>/, the model is told (through a session-scoped system prompt) to write its artifacts there, and a write that would create a file at the workspace root asks for confirmation first.Tested with DSH Desktop 0.2.1-rc.2 on Windows. Host code uses Node built-ins only; the client is a hand-written CommonJS bundle, so there is no build step.
# from npm (prebuilt, no build approval needed)
dsh plugin --profile web add dsh-session-workspace-organizer
# from GitHub source
dsh plugin --profile web add github:dream-fish69/dsh-session-workspace-organizer
# local development checkout
dsh plugin --profile web add link:/absolute/path/to/the/checkout
On the Desktop app, use the Plugins page: remove the old entry, then install dsh-session-workspace-organizer or github:dream-fish69/dsh-session-workspace-organizer from the install field. Restart DSH after installing or upgrading — the Host half is only loaded at startup.
Uninstall:
dsh plugin --profile web remove dsh-session-workspace-organizer
Removing the plugin leaves the sessions/ folders and their files alone.
Settings → Workspaces (the section title follows the DSH language: 工作区 in Chinese). Three things live there:
Pick a registered workspace, choose a target parent folder and type the new folder name.
The plugin then performs a strict relocation:
sessions/ included — is moved to the new path, and the old path is deleted; no junction or symlink is left behind;cwd equals the old path is rewritten: the first zstd frame carries the header, only its cwd is replaced, and every later frame is kept byte-identical; the log directory is then moved from --<old cwd>-- to --<new cwd>--;pending-attach.json and attached automatically after a DSH restart;EBUSY/EPERM/EACCES — e.g. DSH still holds a handle), the plugin falls back to a copy migration: copy and verify, rewrite the copied logs, switch the registry, then delete the old directory if it can and report the exact reason when it cannot.Hard requirement: the workspace being moved must have no running session, because session logs are append-only and a live write handle cannot be rewritten safely. Open a conversation in another workspace and trigger the move from there. If sessions are still running, a dialog lists them (title + id) and offers to cancel their turns, wait for them to settle, and continue with the copy path — unless the session you are typing in is itself in the target workspace, which always has to be moved from elsewhere.
If the old path was DSH's launch directory, the plugin also switches the process working directory and the sandbox fallback root, but desktop shortcuts or launcher configuration still have to be updated by hand.
Creates sessions/ and sessions/README.md when missing. With move loose files ticked, ordinary files sitting at the workspace root are moved into sessions/<date>_整理/; dotfiles, README.md, AGENTS.md and common project manifests are left where they are.
sessions/ folder with everything inside it, and files the session wrote through write/edit elsewhere inside the source workspace.verify.COT中文翻译插件.md; nothing is overwritten.sessions/ are only removed when you tick that option, and only inside the session's source workspace.For every new or resumed session whose cwd is inside a registered workspace:
<workspace>/sessions/<YYYY-MM-DD>_<title>/ is created, and renamed when the session title changes (the date prefix stays; duplicates get -2);.dsh-session marker inside the folder records sessionId, workspacePath and createdAt, so a resumed session finds its folder again — do not delete it;write triggers a confirmation dialog; existing files and common manifests (README.md, AGENTS.md, package.json, lockfiles, Makefile, Dockerfile, …) pass through untouched.The restart button in the conversation header ends and relaunches the whole application, so every cached service, plugin and module is rebuilt from disk — unlike a page refresh.
{"force": true} overrides the gate server-side, and nothing malformed ever counts as force.document.body, so it survives the React tree being torn down. A failed restart flips it to a red state that names the error instead of spinning forever.GET /workspace-organizer/restart reports whether a restart is possible (mode, revision, lastError), and answers 409 with busy: true while work is live.
Override the plugin row in the profile's cordis.patch.yml:
- id: workspace-organizer
config:
sessionFolders: true # create the per-session output folder
guardRootWrites: true # confirm before creating files at the workspace root
sessionsDirName: sessions # parent folder name for session folders
maxTitleChars: 40 # max title characters in the folder name (8-80)
# sessionsRoot: /path/to/dsh/home/sessions # only if DSH stores logs elsewhere
0.2.x (Web and Desktop profiles that include dsh-base + dsh-web-app).| Layer | File | Responsibility |
|---|---|---|
| Host | index.js | Registers the workspace-relocate-check / workspace-relocate-strict / workspace-organize / session-relocate-plan / session-relocate / session-relocate-batch / session-delete-preview / session-delete / session-delete-batch commands; agent/created builds the session folder and the scoped prompt; session/event renames it on title change; tools/pre-execute guards root writes; serves the restart route |
| Host | lib/fs-ops.js | Directory move (same-disk rename, cross-disk copy + verify + rollback), name sanitizing, loose-file scan |
| Host | lib/session-logs.js | zstd first-frame header parsing, cwd-only rewrite, later frames untouched, log-directory re-homing |
| Host | lib/restart.js | Full-process restart: shell-first shutdown (so no native error dialog), detached relaunch helper, liveness check, bounded restart logs |
| Client | client.js | settings.section page with the move / organize / sessions dialogs, the header restart button and its confirmation/progress layers, bilingual copy from locale/*.json |
npm run check # node --check on index.js, client.js and the three lib modules
npm test # node --test tests/ (path safety, copy/merge, header rewrite, restart routes)
No bundler: lib/ is the committed source, client.js is the bundle DSH loads through window.__ModuleLoader__. Host changes need a DSH restart; client changes need a page refresh.
MIT