| name | project-kit |
| description | Bootstrap a project's agent-facing context system โ structured JSON docs (live status + decision records) rendered by a live HTML dashboard, plus the operating rules that keep them current, wired into CLAUDE.md. Use when setting up context docs for a new or existing project, "set up project docs", "scaffold status/ADRs", or first-time project setup. Usage: /project-kit [--minimal | --full] [path]
|
| trigger | /project-kit |
| user-invocable | true |
| argument-hint | [--minimal | --full] [path] |
| allowed-tools | ["Read","Write","Edit","Bash","Glob","Grep","AskUserQuestion"] |
/project-kit
Bootstrap a project's agent-facing context system into any project, on the first
session. It creates a small set of living docs as structured JSON (so they're machine-
readable and never drift from a separate copy), ships a live HTML dashboard to read them
at a glance, and wires the rules that keep them current into CLAUDE.md.
The system is layered by how fast things change. The data is JSON (the source of truth that
agents read and write); the dashboard renders it for humans:
| Layer | File | Role |
|---|
| Primer (auto-loaded) | CLAUDE.md | Always-on orientation + the self-maintaining rule. Points at status.json, doesn't duplicate it. |
| Live state | docs/pm/status.json | Now / Next / Milestones / Blocked / Shipped. The "where are we" source of truth. |
| Decisions | docs/pm/decisions/NNNN-*.json | One ADR (JSON) per direction change. Numbered, fixed once accepted. |
| Field contracts | docs/pm/schema/*.schema.json | JSON Schema for each doc โ the shape + per-field guidance. Consult before writing. |
| Dashboard | docs/pm/dashboard/ | Read-only viewer: serve.py (stdlib, live-reload) + index.html. python3 docs/pm/dashboard/serve.py. |
| Thesis & spec (opt-in) | docs/pm/project-summary.json, prd.json | The "why" and the buildable "what". Only with --full. |
Lean by default: status + ADRs + schemas + dashboard + the CLAUDE.md rules. The thesis/spec layer is opt-in.
Usage
/project-kit # infer from repo, interview only for gaps, scaffold lean
/project-kit --minimal # blank templates, no inference, no questions
/project-kit --full # also scaffold project-summary.json + prd.json
/project-kit <path> # target a different project root (default: current dir)
/project-kit --help # print this Usage block and stop
If invoked with --help / -h and no other arguments, print the ## Usage block
verbatim and stop. Do nothing else.
What you must do when invoked
The templates live next to this file under templates/. The JSON docs and the CLAUDE.md block
carry {{TOKEN}} placeholders you substitute (mapping below) โ you (the agent) do the
substitution; the tokens are not a runtime feature. The dashboard (dashboard/) and schemas
(schema/) are static tooling copied verbatim, with no tokens.
Step 0 โ Parse arguments
--minimal โ skip Steps 2 & 3 entirely (no inference, no questions); write templates with the
bracketed [โฆ] placeholders left in place for the user to fill.
--full โ in Step 4, also scaffold the optional thesis + spec docs (and their two schemas).
- A bare non-flag argument โ the target project root. Default: the current working directory.
- Resolve the skill's own directory (where
templates/ sits) so you can read the templates โ
e.g. ls "$(dirname โฆ)"; if unsure, the templates are at ~/.claude/skills/project-kit/templates/.
Step 1 โ Detect & protect (always)
Inspect the target root. Use Glob/Read โ do not assume.
- Is there a
CLAUDE.md? a docs/pm/? docs/pm/status.json? docs/pm/decisions/? docs/pm/schema/? docs/pm/dashboard/?
- Build a create vs. skip list. Never overwrite an existing file. If a target file already
exists, leave it untouched and report it as skipped in Step 6.
- The one exception is the marked block in
CLAUDE.md (Step 5) and the generated decisions index
(Step 4a), which are refreshed in place.
Step 2 โ Infer from the repo (skip if --minimal)
Draft the project's identity from what's already there, so the scaffold ships filled, not empty:
- README (
README*), and any existing CLAUDE.md โ project name, one-liner, purpose.
- Manifests โ
package.json, pyproject.toml/setup.py, Cargo.toml, go.mod, *.xcodeproj/project.yml, pom.xml, etc. โ name, language/stack, scripts.
git log --oneline -20 and git config user.name โ recent direction, current focus, owner.
- Top-level layout โ what kind of project this is and where the work is.
From these, draft: PROJECT_NAME, ONE_LINER, a first-pass NOW / NEXT, any obvious
milestones, and a sketch of the CORE_BET. Today's date: get it with date +%F.
Step 3 โ Interview for gaps only (skip if --minimal)
Use AskUserQuestion to fill only what inference could not resolve confidently. Do not
re-ask what the repo already answered. Typical gaps: the core bet (the non-obvious idea),
the near-term focus for Now/Next, and confirmation of the name/one-liner if ambiguous.
Keep it to 1โ3 questions. If everything was inferable, skip this step.
Step 4 โ Fill & write the JSON docs
The templates are valid JSON. Substitute scalar tokens, and for array fields replace the
bracketed placeholder entries with real inferred content (or, under --minimal, leave the
bracketed placeholder strings intact โ the file stays valid JSON either way). Write to the
target root:
docs/pm/status.json โ templates/status.json
docs/pm/decisions/_template.json โ templates/decisions/_template.json
docs/pm/decisions/0001-initial-direction.json โ templates/decisions/0001-initial-direction.json
docs/pm/decisions/README.md โ the decisions index, generated (see Step 4a)
--full only: docs/pm/project-summary.json โ templates/optional/project-summary.json,
and docs/pm/prd.json โ templates/optional/prd.json.
For any file already present (from Step 1), skip it โ never clobber. After writing, the JSON must
parse: each shape is defined in docs/pm/schema/ (copied in Step 4b) โ match it.
Token map (scalars; substitute directly):
| Token | Source |
|---|
{{PROJECT_NAME}} | inferred / confirmed (Steps 2โ3) |
{{ONE_LINER}} | inferred / confirmed |
{{CORE_BET}} | interview (Step 3); under --minimal leave the bracketed placeholder |
{{NOW}} / {{NEXT}} | inferred / interview โ these sit inside the now / next arrays |
{{DATE}} | date +%F |
{{OWNER}} | git config user.name (fallback: leave [name]) |
{{OPTIONAL_LAYOUT_LINES}} | empty for lean; under --full, two bullets for project-summary.json + prd.json (see Step 5) |
Array fields beyond now/next (milestones, blocked, shipped, etc.) aren't single tokens โ fill
them from inference, or under --minimal leave the seeded bracketed placeholder entry. status.json
ships with one shipped entry recording the bootstrap; keep it.
Step 4a โ Generate the Decisions index (always)
Write docs/pm/decisions/README.md โ a catalog of the ADRs. Build it from the JSON files, don't hand-author it:
- List every
docs/pm/decisions/NNNN-*.json, sorted by number โ exclude _template.json. (On an existing project this picks up all prior ADRs, not just 0001.)
- For each: read
number, title, and status from the JSON. Link the number to the .json file.
- Mark supersession from the structured fields, not prose: a record whose
supersededBy is set takes status Superseded (by NNNN) in the index (zero-pad NNNN). The supersedes/supersededBy pair is authoritative โ no need to read the body.
- Emit the rows into the
templates/decisions/README.md layout (keep its marker comment + surrounding prose).
This file is a generated artifact, so unlike the source docs it is regenerated, not skipped, on re-run โ but only when it is absent or carries the <!-- project-kit:decisions-index --> marker. If a README.md exists in that folder without the marker, treat it as the user's own file: leave it and report it skipped.
Step 4b โ Copy the dashboard + schemas (always; static, no tokens)
Copy these verbatim (no substitution) into the target โ they are tooling, not content:
docs/pm/dashboard/index.html โ templates/dashboard/index.html
docs/pm/dashboard/serve.py โ templates/dashboard/serve.py
docs/pm/schema/status.schema.json โ templates/schema/status.schema.json
docs/pm/schema/decision.schema.json โ templates/schema/decision.schema.json
--full only: docs/pm/schema/project-summary.schema.json and docs/pm/schema/prd.schema.json.
These are skip-if-exists like the source docs โ never clobber a dashboard the user has customized.
(To pick up an updated renderer later, the user deletes the file and re-runs.) Prefer a real file
copy (e.g. cp) so bytes are identical; only fall back to Read+Write if needed.
Step 5 โ Merge into CLAUDE.md (always)
The block to insert is templates/CLAUDE.block.md (with tokens substituted). It is delimited by
<!-- project-kit:begin โฆ --> / <!-- project-kit:end -->.
Never edit any part of an existing CLAUDE.md outside the marked region.
Step 6 โ Report
Print a short tree of what was created vs. skipped (already existed), note how CLAUDE.md
was handled (created / block-updated / appended / Status-section-omitted), and end with the next
steps: "Fill the bracketed placeholders in docs/pm/status.json and decisions/0001-โฆjson, then
view it live: python3 docs/pm/dashboard/serve.py. Commit when ready."
Design rules (hold to these)
- Idempotent / non-destructive. Safe to re-run. Never overwrite a user's file. The two generated
artifacts โ the
CLAUDE.md marked region and decisions/README.md (its index marker) โ are refreshed
in place; everything else (JSON docs, schemas, dashboard) is skip-if-exists.
- JSON is the source of truth; the dashboard is a view. Agents read and write the JSON; humans read
the rendered dashboard. There is no second copy to keep in sync.
- Generalize, don't copy. These templates carry the patterns (layer split, the self-maintaining
rule, the ADR skeleton, the dated/falsifiable discipline) โ never any one project's domain content.
- Infer-first, interview-for-gaps. Ship filled content; ask only what the repo can't tell you.
- Lean by default. Status + ADRs + schemas + dashboard + CLAUDE rules; thesis/spec are opt-in via
--full.
- Keep entries specific and falsifiable โ the docs you scaffold should model the discipline: cite
dates, link commits/ADRs, snapshot-not-journal.