Skip to main content

project-init

Get a repository ready for the dev-team toolchain in one command — detect the tech stack (JS/TS, Python, C#, Java), inventory the static-analysis tools the project already has, confirm a plan, and install only what's missing, repo-level. This is the canonical source of truth for tech-stack detection and toolchain installation — NOT dev-team-specific config (CLAUDE.md generation, agent template activation, PostToolUse hooks, the generated `/pr` command all live in `/setup`, which invokes this skill first for the stack signal). Also installs the detection-gated capability tools other skills depend on — semgrep, Playwright + Chromium, adr, gh, and the docker scanners (hadolint/trivy/grype). For JavaScript it scaffolds a new project with ES modules, functional style, prettier, oxlint, editorconfig, vitest, and gitignore. Use this skill whenever the user wants to start a new JS project, scaffold a Node.js app, create a new package, bootstrap a JavaScript repo, or says things like "init a new project", "set up a JS

Source facts

Repository
bdfinst/agentic-dev-team
Last source activity
August 4, 2026 at 22:55
Detected SKILL.md language
English
Stars
299
Forks
36

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
5 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
project-init
description
Get a repository ready for the dev-team toolchain in one command — detect the tech stack (JS/TS, Python, C#, Java), inventory the static-analysis tools the project already has, confirm a plan, and install only what's missing, repo-level. This is the canonical source of truth for tech-stack detection and toolchain installation — NOT dev-team-specific config (CLAUDE.md generation, agent template activation, PostToolUse hooks, the generated `/pr` command all live in `/setup`, which invokes this skill first for the stack signal). Also installs the detection-gated capability tools other skills depend on — semgrep, Playwright + Chromium, adr, gh, and the docker scanners (hadolint/trivy/grype). For JavaScript it scaffolds a new project with ES modules, functional style, prettier, oxlint, editorconfig, vitest, and gitignore. Use this skill whenever the user wants to start a new JS project, scaffold a Node.js app, create a new package, bootstrap a JavaScript repo, or says things like "init a new project", "set up a JS project", "create a new node app", "start a new frontend project", or "bootstrap a new package". Also trigger when the user says "set up my project's toolchain", "install the linters for this repo", "get this repo ready for the plugin", or asks to add standard tooling (linting, formatting, testing) to a new or existing project in any supported language.
role
worker
user-invocable
true
argument-hint
[--yes] [--force]
# Project Initializer One command to get a repository ready for the dev-team toolchain, whatever the stack. Detect the project's language(s), inventory the static-analysis tools already present, confirm a three-column plan, then install only the missing tools — lane tools and Playwright always repo-level, never user-level or global. It then installs the detection-gated **capability tools** other skills depend on (semgrep, Playwright, adr, gh, docker scanners — see Step 4b), which are user/system-level CLIs by nature. Supported stacks: **JS/TS**, **Python**, **C#**, **Java** — the four lanes registered in `${CLAUDE_PLUGIN_ROOT}/skills/static-analysis-integration/references/tool-configs.md` § Build-time lanes. Tool facts (choice, versions, install mechanism) follow that registry; provider-binding semantics (capability slots, ordered provider lists, bind-don't-replace, the qualification contract) follow `${CLAUDE_PLUGIN_ROOT}/skills/build/references/static-self-heal.md`. The manual commands stay documented in `${CLAUDE_PLUGIN_ROOT}/skills/static-analysis-integration/references/language-setup.md`; this skill automates them. ## Arguments Arguments: $ARGUMENTS - `--yes`: Run unattended — auto-confirm each gate below with its **safe** default and never wait for input. `/setup --yes` passes this through. - `--force`: Bypass Step 0's idempotency short-circuit and force the full Step 1-6 sequence even when `.claude/init-state.json` records a matching `last_run` (#1778). Independent of `--yes` — combine them to force a full unattended re-check. ### `--yes` semantics **Affirmative** (auto-confirm, no prompt): - **Step 3 three-column plan** — proceed: install the "missing and will add" column's defaults, repo-level. Existing configs are still never overwritten (that is already the plan's contract, not a prompt). - **Step 4b capability tools** — install every tool whose detection signal fired and that is still missing. Tools whose signal did not fire are still not installed. - **Step 4c CodeGraph** — install if missing (its recommended default is already yes, as part of the interactive keyless-pair prompt — see Step 4c). CodeGraph never writes to the repo, so it stays in this bucket. Repowise, offered alongside it in the same interactive prompt, does **not** stay here — see the Conservative bucket below (#1690). **Conservative** (skip with a printed note — never mutate the repo by surprise): - **Step 4c Graphify** — skipped for this run, because `graphify install --project` writes PreToolUse hook entries embedding this machine's absolute binary path into the shared, git-tracked `.claude/settings.json` (see the settings.json absolute-path guard, #1367, in the Graphify sub-section below) — a write that file cannot simply be gitignored out of (unlike the generated git hooks themselves, which are). It also writes a `## graphify` section into the tracked `.claude/CLAUDE.md`. Print `Graphify: skipped under --yes (repo-writing; run /project-init without --yes to add it)` and do **not** record a durable decline in `.claude/init-state.json`, so a later interactive run still offers it. - **Step 4c Repowise** — skipped for this run, because `repowise init` writes a `## Codebase Intelligence for <project> (Repowise)` section into the tracked `.claude/CLAUDE.md` (see the Repowise sub-section below) — the same class of repo-level write Graphify is gated for above (#1670 item 3 made this write explicit; #1690 is what moves Repowise to this bucket to match). Repowise's own `.mcp.json` write also carries a machine-specific path, but that file IS gitignored by the standing check below — it is the tracked CLAUDE.md write, not the `.mcp.json` write, that puts Repowise here. Print `Repowise: skipped under --yes (repo-writing; run /project-init without --yes to add it)` and do **not** record a durable decline in `.claude/init-state.json`, so a later interactive run still offers it as part of the keyless-pair prompt. CodeGraph, the other half of that same prompt, is unaffected — it stays in the Affirmative bucket above and installs under `--yes` regardless. - **Step 1 zero/ambiguous stack** — never guess. Report the supported stacks and exit gracefully without writing files or installing anything, exactly as the interactive path's "something else" branch. - **Greenfield JS/TS scaffold** — the confirm step proceeds with the documented defaults (no customization prompt); it only writes into an empty/near-empty directory, so nothing existing is overwritten. ## Workflow ### Step 0: Idempotency short-circuit (#1778) `/project-init` is invoked far more often than it has anything new to do — most re-invocations find every slot still bound and every capability tool still resolved (installed or durably declined), and re-running the full Steps 1-6 sequence for that outcome burns tokens presenting a three-column plan whose answer never changed. This step does not skip detection — it only skips Step 3's plan presentation and any install when detection itself proves there is nothing to install. 1. **Always run Step 1's stack detection, Step 2's tool inventory, Step 4b's capability-tool detection signals, and Step 4c's "Detect which are already present" probes first** — all cheap, deterministic, filesystem/PATH-only signals with no network and no builds, so running them here is not new work, only reordered. Their live result is authoritative for step 2 below — never substitute a cached value for what they just found, per this file's own stale-state override rule (§ "Detect which are already present"). 2. **Short-circuit** only when `--force` was **not** passed AND the just-run detection shows: the stack list matches `.claude/init-state.json`'s `last_run.stack` (if the key is absent, this condition fails and step 3 below never fires — first run always takes the full path), Step 2's fresh inventory has every lane's capability slot bound (Step 3's own "missing and will add" column would be empty), and every Step 4b/4c capability tool is installed or durably declined per its own already-present/decline state (never "signal fired, decision still open"). All three are re-derived from the live probes just run, not read back from `last_run` — `last_run.stack` is the only field compared against a recorded value, because the other two must reflect what the filesystem shows *right now*, exactly as an uninstalled tool or a wiped config file must be caught on this very run, not papered over by a stale cache. 3. **Before stopping, still run both of this file's standing checks** — the `.mcp.json` machine-specific-path hygiene scan (§ "Standing check — `.mcp.json` machine-specific-path hygiene") and Graphify's settings.json absolute-path scan (§ "Standing check — run even when Graphify install is skipped") — both are explicitly documented elsewhere in this file as running "unconditionally, once per `/project-init` (and therefore `/setup`) run," independent of every other branch, and a short-circuited pass is not an exception to that. Fold their one-line outcomes into the short-circuit's own report. 4. Print exactly one line reporting both the short-circuit and the standing checks' outcomes — e.g. `Project already initialized for <stack> — nothing changed since the last run (.claude/init-state.json); .mcp.json hygiene: <outcome>; Graphify path check: <outcome or "not applicable">. Re-run with --force to re-check anyway.` — and stop. Do not proceed to Step 3's plan presentation or any install step. 5. **Otherwise** (first run, no `last_run` key, a changed stack, an unbound slot, an unresolved capability tool, or `--force`), proceed to Step 3 as normal with the detection/inventory results already in hand from step 1 above — do not re-run them a second time. 6. **`--force`** always bypasses this short-circuit and forces the full Step 1-6 sequence, exactly as if `last_run` were absent (already listed in the Arguments section above). On a normal, successful completion, Step 6 writes the `last_run` snapshot into `.claude/init-state.json` — see its final bullet below. A run that stops early (Step 1's zero/ambiguous-stack exit, an install failure) does not write `last_run`, so the next invocation naturally re-checks from scratch rather than caching a failed or incomplete state as "done." ### Step 1: Detect the stack Probe the working directory with cheap, deterministic filesystem signals — no builds, no network: | Signal | Stack | |---|---| | `package.json`, `tsconfig.json`, `*.js`/`*.jsx`/`*.ts`/`*.tsx` sources | JS/TS | | `pyproject.toml`, `requirements*.txt`, `setup.cfg`/`setup.py`, `*.py` sources | Python | | `*.sln`, `*.csproj`, `global.json` | C# | | `pom.xml`, `build.gradle`/`build.gradle.kts`, `*.java` sources | Java | - **Multiple stacks detected** → multi-stack setup: run every matched language's inventory and install, mirroring the self-heal pass's mixed-language lane dispatch. - **Zero or ambiguous signals** (empty dir, README-only repo) → **ask the user**: present the four supported stacks plus "something else". "Something else" explains what's supported and exits gracefully — no files written, nothing installed. **Under `--yes`, do not prompt** — never guess a stack: report the supported stacks and exit gracefully, exactly as the "something else" branch. ### Step 2: Inventory the existing toolchain Stack detection says which lanes apply; the inventory then establishes, per capability slot (**autofix** / **diagnostic**, as the lane registry defines them), which recognized provider — if any — the project already has. Three signal classes, still cheap and deterministic — no builds, no network: 1. **Config-file signals** — `eslint.config.js`/`.eslintrc*`, `biome.json`, `[tool.ruff]`/`[tool.black]`/`[tool.mypy]` sections in `pyproject.toml`, `.flake8`/`setup.cfg` sections, `.pylintrc`, `checkstyle.xml`, PMD rulesets (`pmd-ruleset.xml`). 2. **Dependency signals** — `package.json` devDependencies, `requirements-dev.txt`/the `pyproject.toml` dev group, Maven/Gradle plugin blocks. 3. **Executable probes** — the lane registry's detection probes, run per candidate provider down each slot's ordered provider list (`tool-configs.md` § Build-time lanes; repo-local locations first, then PATH). Binding follows **bind-don't-replace**: an existing, configured tool that passes the qualification contract is bound as its slot's provider, and the plugin's default is never installed over it. A bound equivalent — black + flake8 as a pair, biome, an ESLint kept under demotion, checkstyle — satisfies its slot; nothing is installed for it. ### Step 3: Confirm the three-column plan Detection is always confirmed, never assumed. Present the stack + inventory results as a three-column plan and wait for the user to confirm it **before any file is written or any install runs** (**under `--yes`, print the plan and proceed without waiting** — see the Arguments section): 1. **Found and keeping** — providers the inventory bound. Nothing is installed for these slots, and existing configs (`eslint.config.js`, `pyproject.toml` sections, `.editorconfig`, …) are never overwritten — this column doubles as the report of what already exists and is left alone. 2. **Missing and will add** — empty slots to be filled with the lane's default tool. **Only this column installs anything.** 3. **Found but can't participate** — a present tool that fails the qualification contract (e.g. pyright before its adapter exists), with the reason stated and the lane default offered alongside — never a silent replacement. The mode follows from what detection found: - **Existing project** (sources present) → tools-only mode, driven entirely by the three columns: bind, fill empty slots, surface non-conforming tools. No existing config file is modified. - **Greenfield JS/TS** (empty or near-empty dir) → the full scaffold below; its defaults are presented as this plan's **missing and will add** column. - **Greenfield Python/C#/Java** → tools plus minimal config (full config-scaffold parity with the JS path lands as per-language follow-ups). ### Step 4: Install missing tools (repo-level, per lane) Every install lands in the project, versioned with it, reproducible for every contributor and CI — never `pip install --user`, never a global pipx install, never `npm install -g`. - **JS/TS** — greenfield: the full scaffold below (oxlint as the default linter, ESLint behind `lint:deep`). Existing project: fill the empty autofix slot as a devDependency, leaving all configs alone: ```bash npm install --save-dev oxlint ``` If this fails with `npm error code ERESOLVE`, the peer conflict is pre-existing in the repo's tree (not with `oxlint`) — retry once with `--legacy-peer-deps` and note to the user that you did so, rather than aborting. - **Python** — add `ruff` and `mypy` — plus `pytest` if no test runner is present — to the project's own dev-dependency mechanism: the `pyproject.toml` dev group or `requirements-dev.txt`, whichever the project already uses; create `requirements-dev.txt` if neither exists. - **C#** — nothing to install: both lane tools ship with the .NET SDK. Verify the SDK is present — honoring a `global.json` pin when one exists — and that `dotnet format --version` responds. - **Java** — verify a JDK is present (`java` on PATH), then run the plugin's pinned-PMD installer — the user never locates or invokes it by hand: ```bash python3 "${CLAUDE_PLUGIN_ROOT}/scripts/install-java-static-analysis.py" ``` It installs a pinned PMD distribution into the repo-local, gitignored `.pmd/` directory (version pin single-sourced in the script; re-runs are idempotent). Add the `.pmd/` entry to the project's `.gitignore` if it is missing. ### Step 4b: Install capability tools Beyond the four static-analysis lanes, other skills and agents depend on a set of **capability tools**. `references/capability-tools.md` is their single source of truth — a registry of *tool | skills that need it | offer-when signal | OS-aware install command | verify probe*. This step installs the warranted ones so the "run `/project-init`" pointer those skills print is honest. **Run the detection signals** (cheap, deterministic — no builds, no network): | Capability | Skills served | Offer-when signal | |---|---|---| | semgrep | `/semgrep-analyze`, security-assessment | any source lane detected (universal SAST) — always offer, opt-in | | Playwright + Chromium | `/benchmark`, `/browse`, `/browser-testing`, `/performance-benchmark` | frontend signals (React/Svelte/Vue/Angular/Next/Nuxt/SvelteKit/Astro, or an `e2e/` dir, or `playwright.config.*`) in an existing project | | adr | `/adr-tools`, adr-author | `docs/adr/`, `docs/decisions/`, or existing ADR `*.md` files present | | gh | `/issues-from-assessment` and other issue/PR skills | git repo with a GitHub remote (`git remote -v` shows `github.com`) | | docker scanners (hadolint, trivy, grype) | `/docker-image-audit` | a `Dockerfile`/`*.dockerfile`/`compose.y*ml` present | **Present the warranted capability tools as their own group** in the Step 3 three-column plan — a "capability tools" block alongside the lane columns — and **confirm before installing**, same gate as the lanes. **Under `--yes`, install every warranted-and-missing tool without prompting** (see the Arguments section). Install only the tools whose signal fired *and* that the user confirmed *and* that are still missing (skip any already on `PATH`). Use the OS-aware install command from `references/capability-tools.md` for each — never inline a different command. **Install-level honesty.** The "always repo-level, never user/system" rule of the lanes applies to the lane tools **plus Playwright**. The other capability tools are general-purpose CLIs that are **user/system-level by nature** — there is no repo-local install for `gh`, `semgrep`, `adr`, or the docker scanners, so they install via the OS package manager (or pipx / user pip on Linux). **Playwright is the repo-level exception among capability tools**: it installs as an `npm` devDependency (`@playwright/test`), versioned with the project like a lane tool — only its Chromium download is machine-level. State this explicitly to the user when the capability group installs. If the Playwright `npm` install fails with `npm error code ERESOLVE`, the peer conflict is pre-existing in the repo's tree (`@playwright/test` has no framework peer relationship) — retry that install once with `--legacy-peer-deps` and note to the user that you did so, rather than aborting. ### Step 4c: Offer the code-lookup tools (keyless group + keyless Graphify build) Three optional, complementary code-intelligence tools — **CodeGraph**, **Repowise**, and **Graphify** — let the review and analysis agents read verified skeletons, resolved call graphs, modification risk, and decision rationale instead of re-reading whole files. None is required. They are offered by **cost profile**, so the operator never has to accept a model/API-key cost to get the keyless tools (issue #1141, which relaxes the single all-or-none group of #1108): - **Keyless pair — CodeGraph + Repowise.** Both build a purely structural index with **no model/API key** and are safe to build unattended. They are offered as **one all-or-none group** — a single decision that gives the agents a consistent, predictable lookup set (issue #1108). Accepting the group both **installs and builds** every missing tool's index in this same run — it is not a "print instructions and leave it to the user" step (issues #1134, #1135). CodeGraph installs its CLI (`npm install -g @colbymchenry/codegraph`) and runs `codegraph init .`; Repowise installs and runs `repowise init . --no-prose -y` for a keyless index. - **Graphify — full extraction is the target; `--code-only` is a degraded
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub