whitelonng
dsh-worktree
No description
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 15, 2026
- Updated
- Aug 15, 2026
Introduction
dsh-worktree
A DeepSeek Harness (DSH) plugin: a git worktree slot pool that lets multiple sessions (conversations) work on the same repository in parallel without stepping on each other — with a constant branch count that never grows.
The design borrows from TalkCody's worktree pool: a fixed number of slots, a fixed set of branches, reused instead of recreated.
Problems it solves
| Scenario | Without the pool | With the pool |
|---|---|---|
| Multiple sessions editing one repo | Same working tree, silent lost updates | Each session gets a physical worktree |
| One branch per conversation | Hundreds/thousands of branches pile up | Branches stay fixed at dsh-slot-0..N-1 |
| Forgot to merge, opened a new session | Old branch becomes history junk | acquire guard refuses to clobber unmerged commits |
| Pool exhausted | — | Structured occupancy report; the model relays it and the user decides |
Core mechanics
- Fixed slots: pool size
poolSize(default 3). Slot dirs live at<repo>/.worktrees/pool-{n}, branches are always<prefix>-{n}(defaultdsh-slot-0/1/2). - Reuse, not recreate: re-acquiring a free slot does
reset --hard main && clean -ffdin place — much faster thanworktree addon large repos. - Release ≠ lose work:
wt_releaseonly hands the directory back. All commits stay on the branch and can be merged later withwt_merge. - Double guardrail: reuse/release checks uncommitted changes (
reason=dirty) and unmerged commits (reason=unmerged); both need an explicitautocommitorforce. - Merge frees the slot: a successful
wt_merge(fast-forward or merge commit) auto-releases the slot; conflicts returnreason=conflictplus the file list. - Self-healing:
wt_gcauto-releases slots whose branch is already merged, and warns about slots idle longer thanmaxIdleDays. - Concurrency-safe: atomic state-file writes plus an mkdir lock (with stale-lock takeover) — simultaneous calls from multiple sessions cannot corrupt state.
What happens when the pool is full (model protocol)
wt_acquire returns a structured result when the pool is full, and the plugin injects this protocol into every session's system prompt:
If wt_acquire returns reason=pool-full: relay each slot's occupant, idle time, and uncommitted/unmerged counts to the user verbatim, and ask "which slot should be released or merged". Only after explicit user confirmation may you call wt_release / wt_merge. Never use force on your own.
The pool being full is therefore not a dead end: the user chooses — release (work stays on the branch) or merge (work lands in main) — and the slot returns to the pool.
Installation
Via DSH plugin install (recommended)
In DSH, install the plugin from this git repository:
https://github.com/whitelonng/dsh-worktree.git
Restart the app, then in a session inside a git repository:
wt_init(orwt_init(size=5)to resize)wt_acquire(label="feature-a")→ get the slot path, work inside itwt_merge(slot=0)when done;wt_release(slot=0)if discarding
Manual cordis.yml registration
plugins:
- id: dsh-worktree
name: '@whitelonng/dsh-worktree'
config:
poolSize: 3
poolDir: .worktrees
branchPrefix: dsh-slot
maxIdleDays: 7
Tools
| Tool | Purpose | Key results |
|---|---|---|
wt_init(workdir, size?) | Initialize the pool | { ok, poolSize, poolDir } |
wt_status(workdir) | Whole-pool status | Per slot: occupant/idle/dirty/unmerged/merged |
wt_acquire(workdir, label, autocommit?, force?) | Take a slot | { ok, slot, path } or reason: pool-full / dirty / unmerged |
wt_release(workdir, slot, autocommit?, force?) | Hand the slot back | Commits stay on the branch, mergeable anytime |
wt_merge(workdir, slot, message?) | Merge into main | Auto-release on success; reason=conflict + file list |
wt_gc(workdir, maxIdleDays?) | Self-heal | { released: [...], stale: [...] } |
All tools accept workdir (defaults to the process cwd); the plugin resolves the repo root via git rev-parse.
Safety guarantees
- Never loses committed work: release/reuse never deletes commits on a branch; only an explicit
forcediscards (uncommitted changes; unmerged commits require force too). - Never silently picks a side: merge conflicts return only the file list; the user arbitrates (rerere can record resolutions for reuse).
- Never breaks main: merge pre-checks that the main repo is clean and refuses otherwise.
DSH sandbox note
DSH's file sandbox usually only allows writes inside the session workspace, so the pool directory defaults to .worktrees/ inside the repo (it is added to .gitignore automatically by wt_init). Without sandbox restrictions, poolDir can point anywhere (e.g. ~/.talkcody/<project>).
Credits
The slot-pool design borrows from TalkCody's worktree pool (MAX_POOL_SIZE=3, fixed-branch reuse, WORKTREE_HAS_CHANGES guardrail, merge-frees-the-slot). This plugin is pure Node with zero runtime dependencies, built for DSH.
License
MIT