Repository navigation
v0.16.0
π The worktree is yours. dobby works wherever you already stand.
Until now /dobby:scope opened its own worktree for every goal β a kit-named branch under .claude/worktrees/, guarded by a scope preflight that computed slug collisions and nesting before anything ran. That ceremony duplicated what every host already does on its own β claude --worktree, Claude Desktop, t3 code, your IDE, a bare git worktree add β and it made a plain checkout with one goal per branch a second-class citizen: the lifecycle simply refused to run there.
v0.16.0 drops the ceremony. Scope grounds the goal where the session already stands, and finish cleans up exactly what it finds there β a worktree somebody opened, or a branch on a plain checkout. Same skills, same bunx dobby up/down, one path fewer to maintain. This very release was built that way: a branch on the main checkout, no worktree, closed by the new finish. It worked the first time.
π§ /dobby:scope no longer creates anything
Run it in a worktree you opened β with any tool β or on a branch in a plain checkout. It writes STATE.md where you are, and brings the run up with bunx dobby up exactly as before (the setup phase, .worktreeinclude re-materialization, the two-step bring-up β all unchanged). The goal's slug is basename(workroot) everywhere: the Neon branch, the cmux panes, the workspace rename. There is no nesting guard left because there is nothing left to nest β whoever made the worktree owns that judgment, not dobby.
π§Ή /dobby:finish is symmetric: it tears down what it stands in
The merge gate is the same as ever β pr watch says merge-ready, you pick "Merge & finish", the squash is pinned to the validated SHA. After bunx dobby down --json, teardown now branches on where the session stands:
- In a linked worktree (whoever made it): finish offers to remove it and its branch β native
ExitWorktreefirst, so the cwd comes back to the main checkout; on refusal, raw git frommainRoot, never from inside the directory it's about to delete. - On a plain checkout: there's no worktree to remove. Finish switches back to the goal's base branch, force-deletes the goal's branch (
-D, because a squash-merge leaves a tip git will always call "unmerged"), and pulls.
Which branch is "back"? That single field took five review rounds, and the answer is now a decision, not a heuristic. Finish returns you to the branch the goal's PR was merged into β its baseRefName, reported as defaultBranch with defaultBranchSource: "pr-base". A goal opened against develop belongs back on develop; dragging you to a repository-wide trunk would move you away from where you were working. Only a branch that never had a PR falls through to the git cascade β a validated origin/HEAD (a dangling symref counts as unset), then origin/main/origin/master, then local main/master, then null β and null stops with the three commands for you to run, rather than guessing at a branch the checkout can't reach. If the base exists only on the remote, finish creates it with git switch --track. The reasoning lives in ADR-0033 so the next reviewer finds the decision, not the question.
π dobby finish --preflight reports where you stand
The payload is rebuilt around the current workroot: inWorktree, worktreePath, mainRoot, branch, defaultBranch + defaultBranchSource, pr (state/mergedAt/url), dirty (count + files, untracked included), dobbyInstalled β now probed at the workroot, not the main root, so a worktree missing its install can't hide behind a healthy main checkout β branchDeleteSafe, reasons[], and the unchanged verdict set (safe / blocked / confirm-required). Nothing in it removes anything; the skill branches on it and asks you at every destructive gate.
β οΈ Breaking changes β read before you upgrade
/dobby:scope opens no worktree. Want the goal isolated? Open one yourself first β claude --worktree, or git worktree add from the main checkout β or just work on a branch. If your CLAUDE.md tells scope to expect or create a worktree, drop that line.
dobby scope preflight is gone. The command, its collision/nesting detection and its suggestedSlug are removed with no replacement. A collision is now whatever your host or git reports.
dobby finish --preflight changed shape. --slug and candidates[] are gone (there is no kit-assigned slug to disambiguate). mode (same-session/orphan) and removeMechanism (ExitWorktree/raw-git) are replaced by inWorktree, worktreePath and mainRoot β the caller derives the removal path from those. defaultBranch and defaultBranchSource are new. Anything scripting against the old keys needs the new payload.
Finish on a plain checkout may stop. When no base branch can be resolved (defaultBranch: null), finish leaves the PR merged and the run torn down, prints git switch <trunk> / git branch -D <branch> / git pull, and ends. That's on purpose β it will not guess.
π¦ Upgrading
bun update @kvnwolf/dobby/dobby:upgrade walks this note (v0.16.md) if you're jumping several versions. The decision and the two rejected alternatives β keep-behind-a-flag, and never-touch-worktrees β are in ADR-0033.