| name | project-init |
| description | Scaffold an unconfigured directory into a configured pi project. Interactive, profile-driven: lists project profiles (coding, docs, plus user profiles), asks which to use, previews the planned writes, and on confirmation writes AGENTS.md, .pi/settings.json (with a worktreeInit hook + toolset), and prompt files. Use when a bare directory needs turning into a working pi project, or when the dashboard's "Initialize" button spawns this session.
|
| license | MIT |
| metadata | {"author":"pi-dashboard","version":"1.0"} |
Project Init
Turn the current directory into a configured pi project through a guided,
conversational flow. You are running as a first-class interactive session —
converse, confirm, and only write files after the user agrees.
Target directory = your current working directory (cwd). All writes land
there. All profile/doctrine paths below are relative to THIS skill's directory
(the folder containing this SKILL.md); call it <skill>.
Step 1 — Resolve the available profiles
A profile is a directory bundle: profile.json (optional, carries
description + dox), AGENTS.md.tmpl, settings.json.tmpl, and
prompts/*.md.
Enumerate profiles from two sources, user wins by name:
- Shipped:
<skill>/profiles/*
- User:
~/.pi/project-profiles/*
ls -1 "<skill>/profiles" 2>/dev/null
ls -1 "$HOME/.pi/project-profiles" 2>/dev/null
Merge: a user profile of the same name fully shadows the shipped one. A
directory is only a usable profile when it contains BOTH AGENTS.md.tmpl and
settings.json.tmpl. Read each profile.json for its description and dox
flag (dox defaults to false when absent or unreadable).
Step 2 — Ask which profile
Use ask_user (select) to present the resolved profiles by name +
description. Shipped defaults are coding (TDD/simplicity/surgical, OpenSpec
on, npm ci worktree-init) and docs (writing structure, OpenSpec off, no
build step).
Step 2b — Resolve the technology stack (stack-aware profiles only)
When the chosen profile's profile.json has "stackAware": true (the shipped
coding profile does), its templates carry technology placeholders
({{INSTALL_CMD}}, {{TEST_CMD}}, {{BUILD_CMD}}, {{INIT_GATE}},
{{INIT_COMMAND}}) that must be filled from the project's stack — a coding repo
may be Node, Rust, Go, Python, Java, etc.
Auto-detect + confirm:
-
Detect a best guess from marker files in the target directory:
| Marker file(s) | Stack | install / test / build | init gate + run |
|---|
pnpm-lock.yaml | pnpm | pnpm install --frozen-lockfile / pnpm test / pnpm build | test ! -d node_modules / pnpm install --frozen-lockfile |
yarn.lock | yarn | yarn install --frozen-lockfile / yarn test / yarn build | test ! -d node_modules / yarn install --frozen-lockfile |
bun.lockb / bun.lock | bun | bun install / bun test / bun run build | test ! -d node_modules / bun install |
package-lock.json / package.json | npm | npm ci / npm test / npm run build | test ! -d node_modules / npm ci |
Cargo.toml | cargo | cargo fetch / cargo test / cargo build | test ! -d target / cargo fetch |
go.mod | go | go mod download / go test ./... / go build ./... | test ! -f go.sum / go mod download |
poetry.lock or pyproject.toml+[tool.poetry] | poetry | poetry install / poetry run pytest / poetry build | test ! -d .venv / poetry install |
requirements.txt / pyproject.toml | pip | venv+pip install / .venv/bin/pytest / python -m build | test ! -d .venv / venv+pip install |
pom.xml | maven | mvn -q dependency:go-offline / mvn test / mvn -q package -DskipTests | test ! -d target / mvn -q dependency:go-offline |
build.gradle(.kts) | gradle | ./gradlew dependencies / ./gradlew test / ./gradlew build -x test | test ! -d .gradle / ./gradlew dependencies |
Prefer a JS lockfile over a plain package.json. A bare directory yields no
guess.
-
Confirm with the user (ask_user): show the detected stack (or "none
detected") and let them confirm or pick a different stack from the table.
Never scaffold a stack-aware profile without a resolved stack.
-
Substitute the chosen stack's values for the {{…}} placeholders when
writing the templates in Step 4. After writing, verify NO {{…}} placeholder
remains in AGENTS.md or .pi/settings.json — an unfilled placeholder means
the stack was not resolved; go back and ask.
Step 3 — Ask about optional capabilities, preview, then confirm
3a — Ask about DOX (all profiles)
DOX seeds a directory-level documentation doctrine and wires the kb toolset (see
Step 5). It is now an interactive choice on every profile, not a fixed
per-profile switch. Ask with ask_user (confirm), pre-selecting the profile's
dox value as the DEFAULT answer:
Enable DOX documentation doctrine? Seeds a directory-level AGENTS.md discipline
into ./AGENTS.md and enables the kb toolset. (default: <profile.dox>)
Record the answer as DOX_ENABLED. The dox flag in profile.json only sets
the default; the user's answer decides. Step 5 gates on DOX_ENABLED, not the
raw flag.
3b — Ask about OpenSpec init (coding profile only)
Gate: only when the selected profile is coding (skip for docs / any
OpenSpec-off profile), mirroring Steps 4b and 5. Skip the prompt entirely when an
openspec/ directory already exists in the target (idempotent — treat as
already-initialized). Otherwise ask with ask_user (confirm):
Initialize OpenSpec for this project? Runs openspec init --tools pi, which
creates the openspec/ scaffold and wires the OpenSpec commands into pi.
Record the answer as OPENSPEC_INIT. The actual run happens in Step 6.
3c — Preview + confirm
List exactly what you will write, then ask the user to confirm (ask_user
confirm). The writes for profile <p> are:
./AGENTS.md ← <skill>/profiles/<p>/AGENTS.md.tmpl (substitute {{PROJECT_NAME}} with the directory basename)
./.pi/settings.json ← <skill>/profiles/<p>/settings.json.tmpl
./.pi/prompts/*.md ← each file in <skill>/profiles/<p>/prompts/
When DOX_ENABLED is true, ALSO name in the preview:
- the DOX doctrine seed appended to
./AGENTS.md (see Step 5)
- the kb toolset flip written to
./.pi/dashboard/knowledge_base.json
When OPENSPEC_INIT is true, ALSO disclose the side effect (see Step 6) — NOT a
plain file write:
- runs
openspec init --tools pi, scaffolding ./openspec/ and wiring pi
When the chosen profile is coding, ALSO disclose the possible side effect (see
Step 4b) — NOT a file write:
- may offer to
pi install the eng-disciplines skills user-globally
(writes ~/.pi/agent/settings.json). This is machine-wide: the skills become
available in all projects on this machine, not just this one. Always
opt-in via a separate prompt; never forced. Needs Node/npm on the machine
(the install runs pi install npm:…); the scaffolded repo itself gains no
dependency.
Idempotency: before writing, check whether ./AGENTS.md or
./.pi/settings.json already exist. If they do, ask before overwriting — never
clobber silently.
Step 4 — Write the scaffold
On confirmation, write the files listed above. Substitute {{PROJECT_NAME}}
in AGENTS.md.tmpl with the target directory's basename, and — for a
stack-aware profile — the stack placeholders resolved in Step 2b.
Validate the hook. After writing ./.pi/settings.json, confirm its
worktreeInit is a valid change-A hook: a non-empty gate string plus a run
that is either { type: "script", command: "<non-empty>" } or
{ type: "agent", prompt: "<non-empty>" }. If it is not valid, warn the user —
an invalid hook fails open (change-A ignores it) and the Initialize button will
loop back to this skill instead of running the hook.
Step 4b — Ensure discipline skills (only when the profile is coding)
The coding template's ## Discipline Skills checkpoint table references the
eng-disciplines skills. This step makes those references live. Gate: run
only when the selected profile is coding (skip for docs / any
OpenSpec-off profile), mirroring how Step 5 gates on dox: true.
Detect (read-only; both forms tolerate a missing pi binary):
pi list 2>/dev/null | grep -q pi-dashboard-eng-disciplines \
|| stat ~/.pi/agent/npm/node_modules/@blackbelt-technology/pi-dashboard-eng-disciplines >/dev/null 2>&1
If pi is not on PATH and the stat misses, treat as ABSENT but do NOT error
the init — fall through to the footnote. (Known limit: the stat form only sees
the npm: global path; a git:/renamed install is invisible and would
re-prompt.)
PRESENT → skills already global. Skip the prompt (idempotent re-run) and
write NO activation footnote into ./AGENTS.md. If a prior run left the
"not detected" footnote (e.g. the skills were installed after a decline),
remove that line before exiting so the file never claims the skills are missing
when they are present. Done.
ABSENT → ask_user (confirm):
Install the discipline skills globally? They power the checkpoint table this
project's AGENTS.md references, and become available in ALL projects on this
machine. Writes ~/.pi/agent/settings.json (user-global, not project-local).
-
Yes → run pi install npm:@blackbelt-technology/pi-dashboard-eng-disciplines
and verify exit 0. On success, write NO footnote. On non-zero exit (or a
missing pi), fall through to the footnote path.
-
No / install failed → append ONE line under the ## Discipline Skills
table in ./AGENTS.md:
Discipline skills not detected — run pi install npm:@blackbelt-technology/pi-dashboard-eng-disciplines to activate the checkpoints above.
The footnote is detection-conditional: written only on the absent/declined
branch, never on the present/installed path (so a successfully-wired project
never carries a false "not detected" line). The install is always user-global
and never forced.
Step 5 — DOX doctrine seed (only when DOX_ENABLED is true)
Gated on the user's Step 3a answer (DOX_ENABLED), NOT the raw profile.json
dox flag — the flag only supplied the default. Skip this step entirely when
the user declined DOX.
The canonical doctrine ships once at <skill>/dox-doctrine.md. Do NOT copy the
whole file. Seed a single block into ./AGENTS.md only when it does not
already carry the marker <!-- dox-doctrine --> (idempotent — if the marker
is present, skip this step entirely).
Compose the seeded block as:
- The marker line
<!-- dox-doctrine -->
- The WRITE discipline — the text between
<!-- dox:write:start --> and
<!-- dox:write:end --> in dox-doctrine.md.
- ONE READ discipline variant:
- If the kb toolset is wired (this profile writes
knowledge_base.json with indexAgentsFiles/directoryLevelAgents),
use the text between <!-- dox:read:kb:start --> and
<!-- dox:read:kb:end --> (references kb agents / kb_search).
- Otherwise use the text between
<!-- dox:read:manual:start --> and
<!-- dox:read:manual:end --> (manual chain-walk; no kb references).
Strip the delimiter comments from the seeded text. Append the block to
./AGENTS.md.
Then write ./.pi/dashboard/knowledge_base.json (when absent) enabling the
directory-level AGENTS.md toolset:
{
"sources": [{ "kind": "filesystem", "ref": "." }],
"indexAgentsFiles": true,
"directoryLevelAgents": { "enabled": true }
}
Step 6 — Run OpenSpec init (only when OPENSPEC_INIT is true)
Gated on the user's Step 3b answer (OPENSPEC_INIT); this only becomes true for
the coding profile when no openspec/ dir pre-existed. Mirrors Step 4b's
side-effect pattern — opt-in, verified, never forced.
Run (always non-interactive so it never hijacks the conversation):
openspec init --tools pi
The --tools pi flag pins the wiring to pi and skips OpenSpec's interactive tool
picker. Verify exit 0 and that ./openspec/ now exists. On success, tell the
user OpenSpec is wired (the coding AGENTS.md already documents
openspec change new <name>). On non-zero exit (or a missing openspec binary),
warn the user and point them at openspec init --tools pi to run manually — do
NOT error the init; the scaffold is already written.
Idempotent re-run: if ./openspec/ already existed, Step 3b never asked, so
OPENSPEC_INIT is false and this step is skipped — no clobber.
Step 7 — Done
Confirm what was written. Writing worktreeInit flips the directory to
"configured": the next dashboard Initialize click runs the hook (change-A)
instead of re-launching this skill. Tell the user they can click Initialize
again to run npm ci (or the profile's hook).