Skip to content

/sdlc:find-worktree-init

Generated from solutions/ontological/skills/find-worktree-init/SKILL.md.

Interactively populate or update the worktree_init: list in a project’s top-level sdlc.yaml — the shell verbs /sdlc:task-work Step 4 runs right after git worktree add to bootstrap a fresh worktree. Probes the project root via sdlc project detect-worktree-init for dependency-install, git-hook-arming, and tool-trust commands, presents the detected candidates through AskUserQuestion (multiSelect), and writes the approved subset back to sdlc.yaml. Idempotent — re-running with the same selection is a no-op. Runs standalone or as a called step of /sdlc:setup.

  • Read
  • Write
  • Edit
  • Bash
  • AskUserQuestion

Usage:

  • /sdlc:find-worktree-init — probe the current project, present detected worktree-init candidates, write the user-approved subset to <project-root>/sdlc.yaml’s worktree_init: list.

Read ${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md once before running this skill — its worktree_init: section documents the schema and execution semantics (each entry is a shell verb run via the worktree-init executor in /sdlc:task-work Step 4, in declared order, from the worktree root).

Edit only <project-root>/sdlc.yaml; touch no other file.

Read the current list deterministically:

${CLAUDE_PLUGIN_ROOT}cli/sdlc config get-worktree-init --config <project-root>/sdlc.yaml

Parse the JSON on stdout: verbs is the configured list in file order, fileExists is whether sdlc.yaml is present. Remember verbs — those entries pre-select in Step 3 so re-runs preserve prior choices.

A missing file is not an error (fileExists:false, verbs:[]); treat the existing list as empty and Step 4 creates the file from scratch. If the op exits non-zero (a present-but-malformed sdlc.yaml), surface its stderr to the user and stop.

2. Probe the project for worktree-init candidates

Section titled “2. Probe the project for worktree-init candidates”

Shell out to the detector:

${CLAUDE_PLUGIN_ROOT}cli/sdlc project detect-worktree-init --project-root <project-root>

Parse the JSON on stdout (the op defaults to JSON). Candidates are under the candidates key; each entry has {kind, name, command, source} fields, where kind is the family (deps, git-hooks, tool-trust) and command is the shell verb a user would type. The detector is deterministic and best-effort — absent markers are simply absent from the report, not errors.

If the detector exits non-zero, surface its stderr to the user and stop.

If the candidates array is empty, tell the user no init commands were detected (no recognised lockfile/manifest, no lefthook/pre-commit config, no mise/direnv files) and offer two options via AskUserQuestion:

  • “Record ‘no init needed’ explicitly” — run sdlc config set-worktree-init --verbs '[]' --config <project-root>/sdlc.yaml to write an explicit empty worktree_init: [] (the op stamps the canonical header on create); then go to Step 5 to report and exit.
  • “Leave it / stop” — do nothing. This is the right default for projects whose fresh worktrees genuinely need no setup: a missing worktree_init: key is a silent no-op for /sdlc:task-work.

If the detector returned at least one candidate, call AskUserQuestion with a multiSelect field listing every detected command as an option. Each option’s label is the command itself (e.g. bun install, lefthook install, mise trust); the option’s description can cite the kind and source (“dependency install, from bun.lock”, “git-hook arming, from lefthook.yml”, “tool trust, from .mise.toml”).

Pre-select any option whose command appears in the existing worktree_init: list from Step 1 — this is what makes the skill idempotent under repeat runs.

Phrase the question something like: “Which of the detected commands should run when bootstrapping a fresh worktree for this project? (Select all that apply — these will be written to sdlc.yaml’s worktree_init: list and executed in order by /sdlc:task-work Step 4 right after git worktree add.)”

Capture the user’s selection. Order the resulting list to match the order entries appear in the detector’s report (the detector already sorts deterministically), not the AskUserQuestion-return order.

Hand the ordered selection from Step 3 to the write op as a JSON array:

${CLAUDE_PLUGIN_ROOT}cli/sdlc config set-worktree-init --verbs '<json-array>' --config <project-root>/sdlc.yaml

<json-array> is the detector-ordered selection (e.g. ["bun install","lefthook install"]). The op:

  • round-trips sibling top-level keys (quality_checks:, orchestrator:, …) and comments untouched — it mutates the worktree_init: key in place rather than re-dumping a plain object;
  • writes an explicit worktree_init: [] on an empty selection (the documented opt-out — never a key-delete);
  • stamps the canonical header when creating the file from scratch;
  • is idempotent: a write whose list matches the existing one reports unchanged:true and leaves the file byte-for-byte untouched.

Parse the JSON on stdout: count is the configured verb count, unchanged is the idempotent no-op flag, created is true on a from-scratch write, path is the absolute file written. If the op exits non-zero, surface its stderr and stop.

Print a one-line summary to stdout, driven by the op’s output from Step 4 (unchanged, count, path):

FIND-WORKTREE-INIT-WROTE worktree_init=<count> path=<path>

(or FIND-WORKTREE-INIT-UNCHANGED worktree_init=<count> path=<path> when the op reported unchanged:true — the idempotent no-op case).

Tell the user the file path and remind them they can re-run this skill any time to update the list.

  • Slug-namespaced markers. This skill is invoked as a called step of /sdlc:setup, so its terminal markers are prefixed FIND-WORKTREE-INIT- (per ${CLAUDE_PLUGIN_ROOT}skills/CLAUDE.md) — a parent reading the sub-step’s output must not mistake them for its own verdict.
  • Schema + execution semantics. See ${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md — the worktree_init: section documents the list shape, the /sdlc:task-work Step 4 executor, and why an empty/missing list is a silent no-op (the opposite default from quality_checks:).
  • Related surfaces. /sdlc:setup creates an empty starter sdlc.yaml if absent and calls this skill as a step; /sdlc:find-quality-checks is the twin configurator for the quality_checks: gate list.
  • Idempotent. Re-running with no detector changes and the same user selection is a no-op (the FIND-WORKTREE-INIT-UNCHANGED branch above). The write op owns byte-for-byte parity; the skill’s only ordering obligation is to hand it the detector-sorted selection (Step 3), not the AskUserQuestion return order.
  • No commits. Write sdlc.yaml; do not stage or commit it — leave that to the user.
  • Branch naming. When invoked inside a worktree (e.g. as part of bootstrapping a new project’s planning setup), follow the existing branch convention rather than inventing one. See ${CLAUDE_PLUGIN_ROOT}conventions/branch-naming.md.