One command,
then you approve.
By the end of this page the overlay is installed in a project on your machine, tailored to your stack, and a first workflow is running under it.
One command installs the overlay. A second command, run inside Claude Code, tailors it to your stack, and that one will ask you before it writes anything.
Check the requirements
Check with node --version. The CLI reads its arguments with node:util parseArgs in strict mode.
Check with bash --version. /init-project stops if bash is older.
Without git, the workflow skips the commit phase and ends after /archive.
Without java, you lose PlantUML diagram checks and /spec-render.
If you are on macOS, note that it still ships bash 3.2, so install a newer one before you reach the configuration step. The installer itself skips this check; /init-project is what makes it, in step two.
The target directory does not have to exist beforehand, because the installer will create it for you.
Install the overlay
$ npx @friedbotstudio/create-baseline ./my-project Baseline installed at /abs/path/my-project (manifest v2). For reproducible installs, pin the exact version: @friedbotstudio/create-baseline@0.26.3
Pin that version wherever your team keeps its tool versions. Two people who install different versions will end up with different hooks and a different constitution, which is a confusing thing to debug later.
Most of the wait is a single download: a PlantUML jar of about 19 MB, taken from the plantuml v1.2026.2 GitHub release and pinned to a sha256. If the network fails or the hash does not match, the install warns you and carries on, and you lose the diagram checks. Pass --no-plantuml to skip the download entirely; a missing java gives you the same warning and the same result.
Later installs will fetch the jar again unless .claude/bin/plantuml.jar is already present and its sha256 matches. A plantuml binary on your PATH does not satisfy the check.
See what landed
The installer writes the tree below, and it also writes a copy of that tree to .claude/.baseline-prior/. The copy is gitignored, and a later upgrade needs it to diff against.
.claude/ ├── hooks/ 27 guards wired at the tool boundary ├── skills/ 59 baseline-owned skills ├── agents/ 1 subagent, swarm-worker ├── commands/ the consent gates you type yourself ├── mcp/ server implementations ├── memory/ the eight canonical memory files ├── schemas/ ├── settings.json which hook fires on which event ├── project.json your stack, once configured ├── workflows.jsonl the selectable tracks └── CONSTITUTION.md the annex CLAUDE.md the in-session constitution .mcp.json the baseline MCP servers docs/init/seed.md the genesis specification .gitignore .githooks/pre-commit scripts/ci/ .github/branch-protection/main.json
Two files you may already own are merged rather than replaced. Your .gitignore stays byte for byte as it was, and the installer only appends the baseline patterns you are missing, under a comment header. That pattern list lives in .claude/skills/gitignore/baseline-ignores.json.
Your .mcp.json gets a deep merge: servers the baseline names refresh from the template, while any server you added yourself stays untouched.
Run the command again
Run the same command again and it exits 1:
$ npx @friedbotstudio/create-baseline ./my-project existing baseline detected at ./my-project: .claude, .claude/.baseline-manifest.json, CLAUDE.md, .mcp.json, docs/init/seed.md. Pass --force to overwrite or use `create-baseline upgrade <target>` to three-way merge.
Those five paths are the sentinels the installer looks for, and finding any one of them stops the run. This is why you cannot wipe a working install by re-running the command out of shell history.
Open the project in Claude Code
Open the project in Claude Code. The SessionStart hook injects the memory index, and Claude opens with the project-agnostic banner:
This repo has the Claude Code baseline installed (27 hooks,
1 subagent, 59 skills). It's in project-agnostic mode —
test_runner and lint_runner are in guide mode and nothing
is tailored to your stack.
From this moment the hooks are live and enforcing, though nothing is tailored to your stack yet. test_runner and lint_runner will print guidance rather than run anything, because nothing has yet told them your test and lint commands.
Configure your stack
Type /init-project yourself. Its frontmatter sets disable-model-invocation: true, which means Claude cannot start it on your behalf.
-
Run
/init-projectNine steps run in order. They include a welcome, a check on your dependencies, and a survey of the whole codebase done in main context. Then the
claude-automation-recommenderskill runs. Last, you get a proposed.claude/project.jsonto approve before anything is written.It also appends a §16 addendum to
docs/init/seed.mdrecording what was added, and runsaudit-baseline. -
Restart Claude Code
The new session reads
project.json. The runner hooks switch from guide mode to enforcing.
You can skip this step for as long as you like, since project-agnostic mode is a supported way to run. What you lose is the tailoring to your stack; every guarantee the overlay makes stays exactly the same.
Start your first workflow
> /triage "your request" > /harness
/triage classifies the request and picks the lightest track whose guardrails still cover the risk, then confirms that choice with you before recording it.
/harness then walks the track from one phase to the next, stopping at each consent gate. Nothing beyond a gate can happen until you type the approval yourself.
Continue with the Org tutorial
Every flag, install mode and exit code lives in the CLI reference, including the upgrade and doctor subcommands you will want the first time a new baseline version ships.
The Org tutorial is the next walkthrough: it takes a pod of peer sessions through a coordinated sprint.