From ok-planner
ONLY activated by explicit /execute-plan-in-worktree slash command. Never auto-triggered by conversation content.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ok-planner:execute-plan-in-worktreeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Wraps `ok-planner:execute-plan` with isolation setup. Creates a git
Wraps ok-planner:execute-plan with isolation setup. Creates a git
worktree on a new branch, copies ephemeral local config (.env*) and
the target spec+plan into the worktree, provisions fresh host ports if
the project parameterizes them through docker-compose or .env, then
switches the session into the worktree (via the harness's native
worktree tool where available) and hands off to
ok-planner:execute-plan. The original checkout is left untouched —
useful when the host project already has a dev stack running and you
want plan execution to land on a side branch without colliding with it.
The user explicitly types /execute-plan-in-worktree. Typical case: a
docker-compose-backed development loop where running a second instance
in the same checkout would fight the first for ports, volumes, or
working-tree state.
If the user is unsure whether they want isolation, they should use
/execute-plan instead — this wrapper is a deliberate choice.
Identify the plan.
.ok-planner/plans/ and present
them as a short prose list (A, B, C…) for the user to pick from.
If the directory is empty or missing, stop and tell the user.**Spec:** header. Resolve the spec path under
the original root. If the header is none, missing, or points
at a file that does not exist, proceed with no spec; note it in
the end-of-skill summary.ORIG_ROOT). Every file operation in steps 4–6 uses absolute
paths against ORIG_ROOT and the worktree and needs no session
switch; the switch into the worktree happens in step 8 (on a
harness that switches the session wholesale, do it just before
step 7's affirm — see step 8).Preserve pending work on the current branch. The wrapper always creates a new branch for the worktree (step 3 picks the name); the question this step answers is what that branch inherits. If the original checkout has uncommitted changes the plan will need, the worktree should see them — so the skill commits them on the current branch first, and the new worktree branches off the resulting HEAD.
Detect the relevant state with git symbolic-ref -q HEAD
(returns empty when detached) and git status --porcelain (any
output = dirty). Branch on the 2×2:
git add -A) and
commit on the current branch. Use this message:
wip: preserved by /execute-plan-in-worktree
Pending changes auto-committed before creating worktree
branch <branch-name> for plan <plan-basename>. Undo with
`git reset --mixed HEAD^` on the original checkout to
restore these as unstaged changes.
Capture the new HEAD sha and the file count for the
end-of-skill summary so the user can find or undo the commit
trivially. Use git add -A (not -u) so newly-created files
come along; .gitignore is what keeps secrets and build
artifacts out. If the user's .gitignore is incomplete, the
auto-commit is a symptom, not the cause — surface anything
surprising in the summary.git switch -c <name>) and re-run, or stash and re-run."After this step the original checkout is in one of three valid states for step 4: on a branch (originally clean or just auto-committed), or at a clean detached commit.
Pick the worktree path and branch name.
ok-planner/<plan-basename-without-extension>.<dirname(ORIG_ROOT)>/<basename(ORIG_ROOT)>-<branch-leaf>
resolved to an absolute path (e.g. /Users/p/code/myapp →
/Users/p/code/myapp-add-auth).-2,
-3, … until both are free. Surface the chosen path in the
end-of-skill summary so the user can spot collisions.Create the worktree.
git -C <ORIG_ROOT> worktree add -b <branch> <worktree-path> HEAD
If this fails, stop and surface the error — do not paper over it and proceed into setup with a half-built worktree.
Copy ephemeral local config from the original root to the
worktree. These are files git ignores but the running app
depends on. Scan ORIG_ROOT (not recursively — top level only is
the common case; recurse only if the project's convention puts
env files in a subdirectory like apps/web/.env and the
user/project layout makes that obvious):
.env, .env.local, .env.* (including .env.development,
.env.test, etc.).envrc (direnv)git check-ignore -v <file> to confirm a file is gitignored before copying — copying
a tracked file is fine but copying something the user
deliberately committed differently is rude).Use cp -p to preserve modes/timestamps. Do not follow symlinks
blindly (cp -P). Do not copy node_modules/, build outputs,
virtualenvs, .git/, or anything else regeneratable.
Record the copied list for the end-of-skill summary.
Provision fresh host ports if the project parameterizes them. Heuristic:
docker-compose.y*ml, compose.y*ml,
docker-compose.*.y*ml at ORIG_ROOT. In each, scan ports:
blocks for ${VAR_NAME[:-default]} patterns. Collect the set
of port-controlling env-var names plus their defaults..env* files in the worktree for keys
matching *_PORT$ or ^PORT$. Add those to the set..env* first, else
the docker-compose default).
b. Pick a free TCP port starting from current + 1000 and
probing upward. Probe with lsof -nP -iTCP:<n> -sTCP:LISTEN
(preferred) or nc -z localhost <n> (fallback). Skip any
port currently bound on the host or already chosen earlier
in this run.
c. Write or update the assignment in the worktree's
.env.local (create it if absent). Prefer .env.local over
.env so a later git pull cannot clobber the override
if .env is tracked.If neither lsof nor nc is available on this system, stop and
surface that — port provisioning without a probe is a guess, and
guessing port numbers in an isolation skill defeats the purpose.
Copy the spec and plan into the worktree's .ok-planner/.
The local versions on the original checkout are usually ahead of
what's committed (often not committed at all). The worktree starts
from HEAD, so without this copy the plan files would be missing
or stale inside the worktree.
ok-planner:affirm from the worktree to ensure
.ok-planner/{plans,specs,...} exists there. Affirm must run
against the worktree, not the original checkout. On a harness
that switches the session wholesale (step 8's native-tool path),
do the step-8 switch first, then run affirm and the copies
below from inside the worktree. Otherwise run affirm with the
worktree as CWD (cd <worktree> && …) or via any mechanism that
targets the worktree — the mechanical detail does not matter,
only that affirm lands in the worktree.<ORIG_ROOT>/<plan-relpath> to
<worktree>/<plan-relpath> (same relative path —
.ok-planner/plans/<basename>). Overwrite if present.<ORIG_ROOT>/<spec-relpath> to <worktree>/<spec-relpath>
similarly.execute-plan later archives, it archives the worktree's
copies; the originals stay until the user merges the worktree
branch back or cleans them up manually.Switch the session into the worktree. Everything that follows
— affirm, the plan copy, and especially execute-plan's pass
implementers — must run inside the worktree, not the original
checkout. How depends on the harness:
EnterWorktree with path: <worktree>), use it to
adopt the worktree created in step 4 and switch the session into
it. This is the robust path: it repoints the session's working
directory — and every subsequent tool call and dispatched
subagent — at the worktree. Enter the existing worktree by
path; do not use the tool's create mode (it would spawn a
second worktree with its own naming/base-ref). The user invoking
/execute-plan-in-worktree is the explicit instruction such
tools require.cd <worktree> && … and pass the absolute worktree path into
each dispatched subagent. A lone cd <worktree> is not
reliable — many harnesses (Claude Code included) reset the shell
working directory to the project root after each command, so it
silently fails to persist and the run lands in the original
checkout. Never depend on cd persistence.Verify before handing off: run pwd and git rev-parse --show-toplevel; both must resolve to the worktree. If they do
not, the switch did not take — stop and fix it. The failure is
silent, and a subagent that runs in the original checkout mutates
the very tree this skill exists to protect.
Cleanup note: a worktree entered by path is not removed by
the session-switch tool's exit (ExitWorktree) — keep simply
returns the session to the original directory, consistent with the
"Do not delete or remove worktrees" rule below. Leave the session
in the worktree through handoff; never tear it down.
Surface the setup summary. Before handing off, emit a short block the user can scan:
Worktree: <absolute path>
Branch: <branch name>
Base: <commit sha + original branch name>
Preserved: <sha-short> on <original-branch> (N files; `git reset --mixed HEAD^` on the original checkout to undo) [omit this line if step 2 didn't auto-commit]
Env files: <comma-separated list>
Ports: WEB_PORT 3000 → 4000, DB_PORT 5432 → 6432 (or "none provisioned")
Plan: <path inside worktree>
Spec: <path inside worktree, or "none">
Hand off to ok-planner:execute-plan. Invoke the skill with
the plan path. Because the session is now in the worktree (step
8), the plan's original-relative path resolves against the
worktree — the path string is identical either way. From here,
execute-plan owns the run: it drives the plan pass by pass as a
background Workflow (dispatching pass implementers, flip-gating
verification, repairing defective gates, running the divergence
audit, archiving inside the worktree). Do not shadow or replicate
any of its behavior.
Worktree-locality of the workflow. execute-plan executes as a
background Workflow whose dispatched agents run shell commands —
those agents MUST operate in the worktree, not the original
checkout, or the isolation this skill exists for is lost. The step-8
switch must still be in effect when execute-plan launches the
Workflow. After the workflow starts, confirm its agents are in the
worktree (e.g. the first agent's git rev-parse --show-toplevel
resolves to the worktree path); if the harness runs background
workflow agents from the original checkout regardless of the session
switch, stop and surface it — do not let the run mutate the original
tree.
.git/worktrees/<name>/ via git worktree add).execute-plan already
enforces this; the wrapper does too.git worktree remove)
is the user's call — there may be in-progress build state or work
they want to preserve.main/master without explicit user
consent. If the original checkout is on main or master, ask
before running step 4.execute-plan with a half-built worktree.npm install,
pip install, etc.). The plan's first pass — or the project's
own bootstrap — handles that. If the user wants the wrapper to
bootstrap, they can say so and the orchestrator can run the
obvious command after step 8 and before step 10..env* or any config.
Port overrides are written only to the worktree's
.env.local.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub fallguyconsulting/ok-planner --plugin ok-planner