opencode-worktree-guard
v0.3.7
Published
OpenCode plugin to enforce Git worktree discipline - one session, one worktree
Maintainers
Readme
opencode-worktree-guard
OpenCode plugin to enforce Git worktree discipline — one session, one worktree.
Problem
When working with Git worktrees, it's easy to accidentally edit files in the wrong worktree or mix work across different worktrees in the same session.
Solution
This plugin enforces the "one session, one worktree" principle through a three-phase lifecycle:
bootstrap ──(worktree_lock)──> locked ──(worktree_done)──> unlocked- Bootstrap Phase: All file writes and git state-changing commands are blocked until you lock to a worktree
- Locked Phase: All operations are validated/restricted to the locked worktree; branch creation/switching is blocked
- Unlocked Phase: After
worktree_done(), all restrictions are lifted. Cannot re-lock — start a new session for new work.
Installation
Add to your opencode.json:
{
"plugin": [
"opencode-worktree-guard"
]
}Then install dependencies:
cd ~/.config/opencode && bun installUsage
1. Lock to a worktree before writing
worktree_lock({ target: "/path/to/your/feature-worktree" })2. Work normally — all operations are now restricted
- File writes (
write,edit,apply_patch) are validated to be inside the locked worktree - Git state-changing commands (
commit,push, etc.) are auto-prefixed withcd <locked-root> - Re-targeting flags (
-C,--work-tree,--git-dir) are blocked - Chained git commands (
&&,;,|) are blocked - Branch creation (
git checkout -b,git switch -c,git branch <name>) is blocked in both phases - Branch switching (
git checkout <branch>,git switch <branch>) is blocked in locked phase
3. Finish up — release the lock
After your feature branch is merged:
worktree_done()The plugin checks git merge-base --is-ancestor HEAD origin/main to confirm the merge. If the merge can't be confirmed (e.g. squash or rebase merge), use force:
worktree_done({ force: true })Optional arguments:
baseRef: Base branch to check against (default:"main")remote: Remote name (default:"origin")
4. To work on a new feature — start a new session
After unlocking, the session cannot be re-locked. Start a new OpenCode session for your next feature.
Blocked Operations
| Phase | Operation | Result | |-------|-----------|--------| | Bootstrap | File writes | Blocked — "Call worktree_lock first" | | Bootstrap | git commit/push/add | Blocked — "Call worktree_lock first" | | Bootstrap | git checkout -b / git branch <name> | Blocked — "Use git worktree add instead" | | Locked | Write outside worktree | Blocked — "Path outside locked worktree" | | Locked | git -C / --work-tree | Blocked — "Re-targeting flags blocked" | | Locked | git cmd1 && git cmd2 | Blocked — "Split into separate calls" | | Locked | git checkout <branch> / git switch | Blocked — "Branch switch blocked" | | Locked | git checkout -b / git branch <name> | Blocked — "Use git worktree add instead" | | Unlocked | (any) | Allowed — no restrictions |
Configuration
Disable the plugin via environment variable:
OPENCODE_WORKTREE_GUARD_DISABLE=1Companion Skill
For best results, also use the git-worktree skill which teaches the AI the correct workflow:
- Never use
git checkout -b— usegit worktree add -binstead - Immediately call
worktree_lockafter creating a worktree - After merge, call
worktree_done()to release the lock - Start a new session for new feature work
License
MIT
