Git Worktrees for ZCode
by agallardol
README.md
# Git Worktrees for ZCode
[](LICENSE)
[](#tests)

Every thread gets its own worktree — **automatically**. Git Worktrees gives
each new [ZCode](https://z.ai) thread an isolated checkout of your repo, so
tasks run in parallel without stashing, branch juggling, or overwriting each
other. Start chatting; you are already isolated.
```
/worktree:new fix-auth "Refactor the login flow" ← worktree + background agent
/worktree ← dashboard: branches, sizes, agents
/worktree:end fix-auth ← commit everything, remove cleanly
```
**Why you'll want it**
- **Zero setup.** Auto-session mode (on by default) hands every new thread its
own worktree the moment it starts — and resuming a thread returns to the
same one. No commands needed, ever.
- **Never lose work.** Removal of dirty worktrees, running agents, or unmerged
branches is refused without `force` — and even then, uncommitted changes are
snapshotted first (tracked diff + untracked files) to a restorable directory.
Branches are kept by default.
- **Your environment travels with you.** `.env` and friends (anything
gitignored and listed in `.worktreeinclude`) are carried into new worktrees;
`setupCommands` (`pnpm install`, `docker compose up -d`) run automatically.
- **It stays out of your way.** Worktrees live in a central store
(`~/.zcode/worktrees`), your repos stay pristine, and a retention sweep
keeps disk usage bounded. Nothing is ever deleted silently.
## Install
1. In ZCode Desktop, open **Settings → Plugin Management** and click **Add marketplace**.
2. Paste the repo — a GitHub `owner/repo` slug or a full Git URL both work:
```
agallardol/zcode-git-worktrees
```
3. Install **Git Worktrees** from the catalog.
4. Open any git repo and start a thread — you're already isolated. Type `/worktree` for the dashboard.
**Requirements**: ZCode ≥ 3.8.1, `node` ≥ 18 on PATH, `git`.
**If `/worktree` doesn't appear**: run `node --version` in a terminal (the MCP
server needs `node`), confirm the plugin is enabled under Installed, and restart
ZCode if you installed it while the app was open.
## The commands
| Command | What it does |
|---|---|
| `/worktree` | Dashboard — branch, dirty state, size, activity, running agents |
| `/worktree:new [name] [task…]` | Create a worktree (friendly auto-name if omitted); with a task, spawns a **background agent** that works inside it |
| `/worktree:status <name>` | Diff stat, unpushed commits, snapshots |
| `/worktree:remove <name>` | Safe removal — snapshots uncommitted work first |
| `/worktree:cleanup` | Retention sweep (dry-run first; skips anything dirty/locked/active) |
| `/worktree:pr <number\|url>` | Check out a GitHub PR into a review worktree |
| `/worktree:end [name]` | End-of-task: commit everything with a real message, remove, keep branch |
| `/worktree:auto` | Per-session automatic worktrees — see below |
Behind them: nine MCP tools (`worktrees_create`, `worktrees_list`,
`worktrees_status`, `worktrees_remove`, `worktrees_cleanup`, `worktrees_prune`,
`worktrees_snapshot`, `worktrees_set_task`, `worktrees_auto_session`), a
model-facing skill, and hooks — so the agent can use worktrees on its own when
you ask for parallel or isolated work.
## Auto-session worktrees (on by default)
Every new session in a repo's main checkout gets its own worktree
(`zcode/sess-…`); resuming returns to the same one, and file edits to the main
checkout are blocked and redirected to the session worktree. Toggle it in
**Settings → Plugins → Git Worktrees** or with `/worktree:auto` (most recent
change wins). A repo can always opt out:
```json
// .zcode/worktree.json in the repo
{ "autoSession": false }
```
## Repo-side configuration (optional)
`.worktreeinclude` — gitignore-style patterns; only files that are *also*
gitignored are carried into new worktrees (tracked files are never duplicated):
```
.env
config/secrets.json
```
`.zcode/worktree.json` — explicit files, lifecycle hooks, and the auto-session
override:
```json
{
"autoSession": true,
"copyFiles": [".env.local"],
"setupCommands": ["pnpm install"],
"preRemoveCommands": ["docker compose down"]
}
```
Plugin settings (Settings → Plugins → Git Worktrees): worktree root, default
base (`fresh` = origin/HEAD with offline fallback, or `head`), max age days
(14), max worktrees per project (15).
## Safety model
- **Nothing escapes the store** — names validated for path and git-ref safety
(traversal, `.lock`, case-twin, unicode tricks all rejected), full paths
guarded against symlinks, store paths canonicalized; a failed
`git worktree add` rolls back its branch.
- **Concurrency-safe** — mutations serialized by an in-process queue plus a
cross-process lockfile; parallel creates never lose state.
- **Self-healing** — corrupt state quarantined and rebuilt, worktrees re-adopted
from git, out-of-band deletions reconciled by `prune`/`cleanup`.
- **No execution from untrusted repos** — `setupCommands` / `preRemoveCommands`
run **only on worktrees you create explicitly**. Auto-session creates never
execute repo-provided commands: opening a cloned repo is never code
execution. Every git call goes through `execFile`; the only shell execution
is lifecycle commands you opted into.
Compared to the tools that inspired it: PR-number checkouts and
`.worktreeinclude` semantics come from Claude Code, snapshot-before-delete and
the central store from Codex, bounded retention from Cursor/Codex — plus
background-agent task orchestration and hard edit isolation, which none of
them expose to plugins.
## Tests
```sh
npm test # 130 tests: 81 unit (validators, state, carry-over, hooks, edit guard)
# + 13 integration (real MCP stdio JSON-RPC + protocol edges)
# + 36 adversarial & security (hostile names, races, corrupt
# state, out-of-band damage, exploit regressions)
CI runs the suite on macOS and Linux (Node 20 and 22).
```
The suites run entirely against local fixtures — no network, no model calls.
## Notes & limitations
- Auto-session isolation is *soft for commands, hard for edits*: Write/Edit
tools are blocked against the main checkout by a PreToolUse guard; Bash is
guided by injected context, not statically policed.
- ZCode has no session-end event, so nothing is auto-committed or deleted at
exit — `/worktree:end` is the explicit finish line, and the retention sweep
collects what's left idle.
- One-session lag on Settings changes for auto-session (hooks read a marker the
MCP server syncs at session start).
## License
[MIT](LICENSE) © Alfredo Gallardo
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues