Introduction¶
In DSH (DeepSeek Harness), a workspace is a record in the registry that points to a directory; a session belongs to a workspace based on the canonical cwd recorded in the session’s immutable header. Once a directory is moved, both sides become invalid: the workspace reports missing-dir, and the sessions it lists cannot resolve their working directory, causing all tool calls to fail.
Since headers are append-only storage, there is no built-in migration interface. This means: to make the “spelling” of the old path resolvable to the new location again, while moving the workspace record to the new canonical path — that is, establishing a directory route (on Windows, this is a directory junction). This is a routing problem, not a history rewriting problem.
The blankwy/dsh-workspace-relink introduced below is a client plugin that does exactly this: move directories without rewriting any session history.
What is it¶
dsh-workspace-relink is maintained by blankwy, classified as a client plugin, currently with 0 stars on the repository, and is MIT licensed. It solves the problem: after a project directory is moved, allowing old workspaces and old sessions to remain usable, rather than rendering the entire session history obsolete.
The plugin itself does not move files or delete files. You move the files to a new location; it creates a junction at the old location, points the workspace record to the new path, then transfers session ownership one by one using the built-in attach/detach validation in the registry, and finally deregisters the old entry.
Core Features¶
Routing-based migration, not history rewriting. Schematic of the migration result:
D:\A\B\C ──► moved by you to ──► D:\E\F\A\B\C
│ │
└── becomes a junction ───────────────┘
(workspace record now lives here)
The process consists of three steps:
- You move the files yourself; the plugin does not participate in the move.
- On the plugin page (Plugins → Workspace Route Migration), use
Change Locationto input the new path.Preview Planwill first check if the new directory exists and if the old path is free, listing the actions to be taken, and clearly stating blocking items and warnings before writing to disk. - Click
Execute Migration: create a junction at the old path, create or reuse a workspace at the new canonical path, transfer ownership of sessions one by one via the registry’s attach/detach validation, and deregister the old entry after clearing it.
The same page also supports: moving a single session to another workspace; viewing the routes created by this plugin and their target liveness status; removing recorded routes.
The plugin also has agent tools, visible to the model when agentTools is not set to false. Each tool returns one line of human-readable summary plus the full JSON:
| Tool | Purpose |
|---|---|
workspace_relink_status |
Lists workspaces, paths, status, session counts, and recorded routes; when includeSessions: true, returns the id, title, recorded cwd, cwdState, and live flag for each session. |
workspace_relink_plan |
Dry run for relocating a single workspace. |
workspace_relink_apply |
Execute (requires confirmed: true). |
workspace_relink_move_session |
Move a single session into another workspace. |
workspace_relink_route_remove |
Remove a recorded route. |
Installation and Enablement¶
The README and documentation in the repository do not provide an installation command, so I won’t concatenate dsh plugin add github:owner/repo here. The plugin has an entry on the directory page skillhub.cn; you can confirm the current installation or integration method from the directory page before using it. The repository address is at the end of the article.
Known environment requirements: DSH >= 0.2.0, Node >= 20; on Windows, creating a junction does not require administrator privileges (fs.symlink(..., 'junction')). The web page is accessed via the dsh bundle mechanism; configuration can be found in cordis.patch.yml inside the package.
Configuration items are only two:
| Key | Default | Meaning |
|---|---|---|
agentTools |
true |
Whether to expose the tools in the table above to the model; the page is always available. |
allowSessionRoutes |
true |
Whether to allow creating a route when moving a session whose directory no longer exists. |
After enabling, open the page from Plugins → Workspace Route Migration.
Typical Usage¶
First move the directory (example, Windows):
move D:\A\B\C D:\E\F\A\B\C
Then execute on the page:
- Find the workspace reporting
missing-dirand clickChange Location. - Enter
D:\E\F\A\B\C, or select viaBrowse…. - Click
Preview Planand confirm there are no blocking items. - Click
Execute Migration.
Upon completion, the old path D:\A\B\C is a junction pointing to the new directory, the workspace record is located at the new path, and the historical sessions remain intact and usable.
To run the self-test provided by the plugin, execute in the repository root directory:
node scripts/selftest.mjs
The self-test runs against a simulated registry, reproducing DSH’s member attribution rules (equality of realpath(header.cwd), plus the wildcard case for missing cwd), covering broken states, plan, apply, route reuse, rejection scenarios, moving residual directories, single session adoption, and route removal; it writes nothing except for temporary directories.
Applicable Scenarios and Notes¶
Suitable for situations where the directory has already been moved (or is intended to be moved), but you do not want to lose the session history in the workspace or restart new sessions.
Limitations to know before use:
- The old and new directories must be reachable on the same machine; junctions are local filesystem objects.
- If the old directory is not cleaned up completely (e.g., copied instead of moved), the plan will be blocked until you allow the plugin to rename it to
<name>.moved-<timestamp>; the plugin does not delete any content. - Removal is only allowed if the route is recorded by this plugin and the path is currently a junction; sessions that resolve their working directory via this route will revert to the “directory missing” state.
- If a session’s recorded directory is an existing directory, the plugin will refuse to reassign it to a mismatched workspace (DSH itself will also refuse), rather than silently detaching.
- Sessions without
cwdin the logs will be marked as non-migratable and will not be guessed at.
Two more points: The plugin runs with the permissions of the current DSH process; you should check the source code and license before installing. It is only responsible for routing and ownership transfer, not for rewriting session history.
Route records are written to <DSH_HOME>/workspace-relink/routes.json (absolute path, type, id, timestamp). It is merely a file system index, not the source of truth: manually created symbolic links will not be touched, and routes with broken links in the record are simply reported as is.
Conclusion¶
The key to migrating a workspace is to leave a resolvable route for the old path, rather than rewriting history. blankwy/dsh-workspace-relink handles these two tasks cleanly, and the functional boundaries and failure modes are also clearly documented in the README.
- Directory page: https://www.skillhub.cn/plugins/blankwy/dsh-workspace-relink
- GitHub: https://github.com/blankwy/dsh-workspace-relink