/sdlc:setup
Generated from solutions/ontological/skills/setup/SKILL.md.
Description
Section titled “Description”Initialize the docs/planning/
Allowed tools
Section titled “Allowed tools”BashSkill
Source
Section titled “Source”Usage:
/sdlc:setup— ensuredocs/planning/<type>/exists for every schema the plugin ships, ensure a top-levelsdlc.yamlexists at the project root for per-project runtime configuration (a fresh file is written fully defined — a schema-driven projection ofSdlcConfigSchema: every key at its default with the schema’s own descriptions as comments, so a new consumer sees the whole surface at a glance and it cannot drift from the schema. Preview it withsdlc config scaffold; see${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md), and ensure the project’s.gitignorecontains the canonical# --- Claude Code project-local ---block (including!.claude/hooks/and!.claude/hooks/**so hook scripts under.claude/hooks/<name>.pycan be committed withoutgit add -f). All three pieces are idempotent — existing dirs / files are left alone; a fence-present.gitignoreblock missing only the hooks un-ignore lines is patched in place, leaving the rest of the file byte-identical./sdlc:setup --dry-run— report what would be created or patched without touching the filesystem. Applies to every write path: directories,sdlc.yaml, and.gitignore./sdlc:setup --obsidian— additionally emit one Obsidian Bases file per entity that ships a view template, atdocs/planning/<plural>/<plural>.base, copied verbatim from${CLAUDE_PLUGIN_ROOT}entities/<type>/obsidian-index.yaml. Idempotent: existing.basefiles are skipped unless--forceis also passed./sdlc:setup --obsidian --force— overwrite existing.basefiles from the template./sdlc:setup --detect— when creating a freshsdlc.yaml, probe the project with the same runner-detection logic assdlc quality detectand write the detected verbs as commented-out suggestions underquality_checks:so the user opts in by uncommenting. No effect on an existingsdlc.yaml(re-run/sdlc:find-quality-checksto refresh interactively).
Once the structure and sdlc.yaml are in place, /sdlc:setup calls the two interactive gate
configurators — /sdlc:find-quality-checks (Step 6) then /sdlc:find-worktree-init (Step 7),
unless --dry-run — to populate sdlc.yaml’s quality_checks: list (the gates /sdlc:task-work
Step 7 runs before opening a PR) and its worktree_init: list (the verbs Step 4 runs to bootstrap a
fresh worktree — install deps, arm git hooks, trust tools).
Project context (don’t re-derive every run):
- The plugin keeps one schema per artifact type at
${CLAUDE_PLUGIN_ROOT}entities/<type>/schema.ts(e.g.entities/task/schema.ts), validated viasdlc entities validate. For each, the canonical home isdocs/planning/<plural>/under the project root —task→docs/planning/tasks/. Other skills (/sdlc:task-work,/sdlc:task-review) assume those paths exist. sdlc.yamlat the project root holds per-project runtime configuration consumed by other skills (/sdlc:task-workStep 7 reads itsquality_checks:list; Step 4 reads itsworktree_init:list). Shape documented at${CLAUDE_PLUGIN_ROOT}conventions/sdlc-yaml.md. Setup creates an empty starter when the file is absent (with a commented-outworktree_init:hint block); bothquality_checks:andworktree_init:are then populated interactively by the configurator steps below (Steps 6 and 7) — or edited directly..gitignoreat the project root needs a canonical# --- Claude Code project-local ---block so project-local Claude Code state (.claude/settings.json,.claude/skills/,.claude/commands/,.claude/agents/,.claude/hooks.json, and.claude/hooks/<name>.py) is committable while transient state under.claude/stays ignored. Setup writes the block on a fresh.gitignore, appends it when no fence is present, and patches in the!.claude/hooks//!.claude/hooks/**lines when the fence exists but those lines don’t. A fully-populated block is left alone.
-
Run the setup op from the project root:
${CLAUDE_PLUGIN_ROOT}cli/sdlc project setupAppend
--dry-runif the user invoked the skill with--dry-run. Append--obsidian(optionally with--force) if the user invoked the skill with those flags — the op then emits one<plural>.basefile per entity into the matchingdocs/planning/<plural>/directory after creating the directories themselves. Append--detectif the user invoked with that flag — the op then runs thesdlc quality detectrunner-detection logic and pre-populates the newsdlc.yamlwith commented-out runner suggestions. -
Read the op output. Summarize for the user:
- How many dirs were created (or would be, in dry-run).
- How many already existed.
- The full list of resulting
docs/planning/<type>/paths. - Whether
sdlc.yamlwas created or already existed; if created with--detect, mention the number of detected runner suggestions written as commented lines. - What
.gitignoreaction was taken: created (no prior file), appended block (file existed without the Claude fence), patched (fence present but hooks lines missing), or left alone (canonical block already present). Under--dry-runthe verbs are prefixed withwould ….
-
If nothing was created and everything already existed (planning dirs,
sdlc.yaml, and the canonical.gitignoreblock), say so plainly — the planning environment is already set up. -
Check plugin runtime dependencies advisorily. Run:
${CLAUDE_PLUGIN_ROOT}cli/sdlc project doctorproject doctorprobes the core runtime deps (bun/node, git, gh, and the recommendedclaude) and emits any missing ones asMISSING-DEP: <name>; install via <hint>lines on stderr. Pass those lines through to the user, ignore the doctor exit code here, and continue setup regardless of what’s missing. Separately remind the user that/project-check’s mermaid-parse lint needsmmdc(npm i -g @mermaid-js/mermaid-cli) —project doctordoes not probe it, so call it out explicitly when relevant. -
Surface a lease-namespace conflict if the setup op reports one. When
sdlc.yamldeclares alease_authority:carrying a literalrefs/sdlcref that shadows the lease namespace, the setup op (Step 1) exits with code 3 and emits aNAMESPACE-CONFLICT ref=refs/sdlc sha=<sha>line plus a one-line remediation (delete the offending ref on the authority, or pick a different namespace). Pass both through to the user and point them at the ADR’s Namespace conflict guard for context. Resolving the conflict is the operator’s call; do NOT delete the ref yourself. -
Configure quality-check gates. Unless
--dry-run, invoke/sdlc:find-quality-checksvia theSkilltool. It probes the project for runner candidates (just / npm / make / cargo / python / pyproject tools), asks (via AskUserQuestion) which to gate intosdlc.yaml’squality_checks:list, and writes the approved subset to the file Step 1 ensured exists. Capture its terminal marker —FIND-QUALITY-CHECKS-WROTE quality_checks=<count> path=<path>orFIND-QUALITY-CHECKS-UNCHANGED quality_checks=<count> path=<path>— and fold the count into the Step 2 summary.Skip this step entirely under
--dry-run: it is interactive and writessdlc.yaml, neither of which belongs in a dry-run. -
Configure worktree-init verbs. Unless
--dry-run, invoke/sdlc:find-worktree-initvia theSkilltool. It probes the project for dependency-install, git-hook-arming, and tool-trust commands, asks (via AskUserQuestion) which to write tosdlc.yaml’sworktree_init:list, and writes the approved subset to the file Step 1 ensured exists. Capture its terminal marker —FIND-WORKTREE-INIT-WROTE worktree_init=<count> path=<path>orFIND-WORKTREE-INIT-UNCHANGED worktree_init=<count> path=<path>— and fold the count into the Step 2 summary.Skip this step entirely under
--dry-run: it is interactive and writessdlc.yaml, neither of which belongs in a dry-run. -
Audit existing entities against current schemas. Run:
${CLAUDE_PLUGIN_ROOT}cli/sdlc entities auditThis is read-only — it reports drift but never modifies files. Skip this step when
--dry-runis set (the audit doesn’t write anything anyway, but the structure may not exist yet in a dry-run scenario).Interpret the exit code:
0— every existing entity is in sync with the current schemas. Tell the user so.1— drift was found on at least one active entity. Print the audit’s markdown output and tell the user they can run/sdlc:entities-auditfor the same report standalone, or/sdlc:entities-migrateto apply theauto_fixable=truedrift mechanically. Closed entities are skipped by default (they’re frozen artefacts of an earlier schema generation); pass--include-closedto opt them back into both audit and migrate.2— op error; show the stderr.
Do NOT attempt to fix any drift from inside
/sdlc:setup— setup scaffolds structure (directories); fixing content (instance files) is/sdlc:entities-migrate’s job.
- Steps 6 and 7 call the two interactive gate configurators —
/sdlc:find-quality-checks(quality_checks:) and/sdlc:find-worktree-init(worktree_init:) — both skipped under--dry-run. They are symmetric: each probes the project, asks which detected commands to keep, and writes the approved subset. Re-run either skill standalone any time to refresh its list. Without a configuredquality_checks:list,/sdlc:task-workStep 7 warn-and-skips. - Adopting the plugin in a project that already has planning content (READMEs with roadmap sections,
brain-dump notes, dated checklists)? Run
/sdlc:import-planningafter this skill — it walks the repo, surfaces planning-shaped files, and produces draft tasks/milestones from them so prior intent isn’t re-keyed by hand. --obsidianwrites Obsidian Bases files (per-folder YAML query files that render frontmatter as tables). The per-entity templates live at${CLAUDE_PLUGIN_ROOT}entities/<type>/obsidian-index.yamland are copied verbatim — edit those templates to change column sets or sort order, then re-run with--obsidian --forceto refresh. Only entities that ship anobsidian-index.yamlget a.base.- The op discovers artifact types from
${CLAUDE_PLUGIN_ROOT}entities/<type>/schema.ts. When a new schema is added to the plugin later, re-running/sdlc:setuppicks it up automatically. - The op does not create README/template files inside the new dirs; the skill is scoped to “directories exist.”
- Re-running setup is the update path; there is no separate
/sdlc:update.