From dev-team
Detects the tech stack (JS/TS, Python, C#, Java), inventories existing static-analysis tools, and installs only what's missing. Scaffolds new JS projects with ES modules, prettier, oxlint, vitest, and gitignore. Also installs capability tools (semgrep, Playwright, adr, gh, docker scanners) that other skills depend on.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dev-team:project-init [--yes][--yes]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
One command to get a repository ready for the dev-team toolchain, whatever
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
--yes: Run unattended — auto-confirm each gate below with its safe
default and never wait for input. /setup --yes passes this through.--yes semanticsAffirmative (auto-confirm, no prompt):
Conservative (skip with a printed note — never mutate the repo by surprise):
## graphify CLAUDE.md section + git hooks). 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.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 |
--yes, do not prompt — never
guess a stack: report the supported stacks and exit gracefully, exactly as
the "something else" branch.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:
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).package.json devDependencies,
requirements-dev.txt/the pyproject.toml dev group, Maven/Gradle
plugin blocks.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.
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):
eslint.config.js,
pyproject.toml sections, .editorconfig, …) are never overwritten —
this column doubles as the report of what already exists and is left
alone.The mode follows from what detection found:
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:
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:
python3 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.
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.
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):
npm install -g @colbymchenry/codegraph) and runs codegraph init .; Repowise installs and
runs a --index-only index.graphify extract . (and graphify update .) run keyless, exit 0, and
produce the graph.json that graphify query/path/explain traverse. A
model/API key is required only for the semantic-enrichment layer:
inferred edges (extract --mode deep) and human-readable community names
(graphify label; without it communities stay Community N placeholders).
Graphify is offered as its own opt-in prompt after the keyless pair —
separate not because of a key, but because its integration is repo-level
(it writes a ## graphify CLAUDE.md section + git hooks; see the sub-section
below). On accept, always build the keyless AST graph; then, only when a
provider key is present, additionally offer semantic enrichment. When
Graphify is absent the agents that use it fall back gracefully (see
knowledge/codegraph-vs-graphify.md).Detect which are already present (so re-runs are idempotent and each offer scopes to the missing set):
command -v codegraph succeeds and .codegraph/ exists..repowise/ exists.command -v graphify succeeds and graphify-out/graph.json exists.Also read .claude/init-state.json: honor any prior explicit decline
(e.g. codegraph.install_declined == true) — a declined tool is excluded from
the "missing" set rather than silently re-offered, and the existing unstick
instruction still applies (remove the <tool> key from .claude/init-state.json to re-prompt).
The keyless group prompt. Compute the missing set = the keyless tools (CodeGraph, Repowise) that are neither already present nor previously declined.
If the missing set is empty: print
Code-lookup tools: keyless pair present (or previously declined) — nothing to install.
and continue. No prompt.
Otherwise, first show the user the "When to use which" section of
${CLAUDE_PLUGIN_ROOT}/knowledge/codegraph-vs-graphify.md, then prompt
once, listing the missing tools by name (this is an explicit y/n, and
the recommended default is yes when anything is missing):
Install the code-lookup tools <missing list> to enable faster, verified
code navigation for the review and analysis agents? [Y/n]
- CodeGraph — personal, user-level MCP; nothing committed to the repo.
Keyless: `npm install -g @colbymchenry/codegraph` + `codegraph init .`.
- Repowise — local keyless index under .repowise/ (gitignored); MCP server.
Keyless: `--index-only`, no API key requested.
Under --yes, treat the keyless-pair prompt as yes and install the whole
missing set without waiting (its recommended default is already yes).
.claude/init-state.json.
.claude/init-state.json, and report
the group as partially installed — do not claim both succeeded..claude/init-state.json, and print a terminal-visible
confirmation so the operator knows the choice was durable and reversible:
Code-lookup tools: skipped — agents fall back to Read/Grep/Glob (re-run /project-init to be offered again).The Graphify opt-in. After the keyless pair, offer Graphify whenever it is in the missing set (regardless of key presence — its AST graph builds keyless):
Under --yes, skip Graphify for this run — it writes to the repo, so it
stays opt-in even unattended. Print the skip note from the Arguments section
and do not record a durable decline. Do not run the prompt below.
Skip if already present or previously declined — same missing-set rule as above.
Prompt once (recommended default no, because — unlike the keyless pair — Graphify writes to this repo):
Also install Graphify for architecture/onboarding-level code intelligence? (y/N)
- Graphify — repo-level: writes a `## graphify` section into this repo's
CLAUDE.md and installs git hooks (guarded against the known
over-delete bug — see the Graphify sub-section).
Its AST structural graph builds WITHOUT an API key.
On yes: run the Graphify sub-section below (install + guarded native
integration + keyless graphify extract .), recording the accept in
.claude/init-state.json.
Semantic enrichment (key-gated add-on). After the keyless graph is
built, detect a provider key — ANTHROPIC_API_KEY, GOOGLE_API_KEY,
MOONSHOT_API_KEY, OPENAI_API_KEY (among the set graphify's own error
lists):
graphify label (community naming) and/or
extract --mode deep (inferred edges) on top of the keyless graph. Its
build stays non-fatal (partial-failure rule) if the key is rejected at
build time.Graphify: keyless AST graph built — set a provider key (e.g. ANTHROPIC_API_KEY) and re-run /project-init for semantic enrichment (community names + inferred edges). Merge
{"graphify": {"enrichment_skipped_no_key": true}} into
.claude/init-state.json.On no: install nothing, record {"graphify": {"install_declined": true}}.
The per-tool mechanics below are unchanged; Step 4c only decides whether each runs. Each remains user-scoped/gitignored exactly as before, except Graphify's documented repo-level native integration — which is written on any Graphify accept (it does not require a key).
CodeGraph (https://github.com/colbymchenry/codegraph) is a third-party
SQLite knowledge graph of every symbol, edge, and file in the workspace.
It is user-level tooling only — nothing it produces or registers is
ever written into a repo-tracked file. .codegraph/codegraph.db stays
gitignored and machine-local, exactly as it already does.
Classify state (run both, record results as installed and initialized):
command -v codegraph > /dev/null 2>&1 && echo "installed" || echo "not-installed"
[ -d "${PWD}/.codegraph" ] && echo "initialized" || echo "not-initialized"
Read .claude/init-state.json if it exists (top-level codegraph key holds
the four state booleans: install_accepted, install_declined,
init_accepted, init_declined).
Branch on (installed, initialized):
| installed | initialized | Action |
|---|---|---|
| any | true | Print "CodeGraph: initialized ✓" and continue. State file untouched. |
| true | false | Init prompt branch (below). |
| false | false | Install prompt branch (below). |
Stale-state override. Before consulting the recorded state, apply these
rules: install_declined is ignored when installed=true (the user has
since installed CodeGraph); init_declined is ignored when
initialized=true (the project got initialized by other means). The live
filesystem/PATH check supersedes the recorded preference.
Install prompt branch (installed=false, initialized=false):
.codegraph.install_declined == true: print
CodeGraph: previously declined install (remove the codegraph key from .claude/init-state.json to re-prompt)
and continue.Install CodeGraph for code intelligence? (y/N)
On y/Y: install the CodeGraph CLI (machine-level, keyless — nothing is
committed to the repo):
npm install -g @colbymchenry/codegraph
{"codegraph": {"install_accepted": true}} into
.claude/init-state.json and fall through to the init step below
(codegraph init .) so the index is built in this same run — this is
what issue #1134 requires (install and build, not just instructions).CodeGraph install failed — install it manually: https://github.com/colbymchenry/codegraph#installation,
merge {"codegraph": {"install_failed": true}}, and continue. Per the
group's partial-failure rule, report the tool as failed rather than
aborting the rest of setup.On any other response (including empty): merge
{"codegraph": {"install_declined": true}} and continue silently.
Init prompt branch (installed=true, initialized=false):
.codegraph.init_declined == true: print
CodeGraph: previously declined init (remove the codegraph key from .claude/init-state.json to re-prompt)
and continue.CodeGraph is installed but not initialized in this project. Initialize now? (y/N)
y/Y:
Running 'codegraph init .' in this project...codegraph init . — non-interactive (no -i; issue #1134),
targeting the current working directory. Surface its stdout/stderr to
the user.CodeGraph: initialized ✓, merge
{"codegraph": {"init_accepted": true}} into
.claude/init-state.json, then register the MCP server (below).CodeGraph init failed (exit code N). See output above. Continuing without CodeGraph.
Do NOT modify .claude/init-state.json.{"codegraph": {"init_declined": true}}
and continue silently.Register the MCP server at user scope (never a repo file). After a
successful init, CodeGraph must be registered the same way any personal MCP
server is added for this Claude Code installation — not written into a
project's .mcp.json, and no .codegraph/ directory is ever committed.
Print the manual command for the user to run themselves at user scope:
claude mcp add codegraph -- codegraph serve --mcp
Note the exact CLI flag for user-scope registration may vary by Claude Code
version — point the user at claude mcp add --help if the command above is
rejected. Do not attempt to write .mcp.json in the project root, and do
not run git add/git commit for anything under .codegraph/.
.claude/init-state.json uses a top-level codegraph key so future plugins
can claim sibling keys without collision. Always merge into existing JSON
rather than overwriting it.
Repowise (repowise on PyPI) is a codebase-documentation engine that indexes
the repo and exposes it as an MCP server
(mcp__plugin_repowise_repowise__{get_context,get_symbol,search_codebase,get_risk,get_why}).
It installs and indexes without any LLM API key and stores its index under
.repowise/.
Run this tool's install/index through the repowise-setup skill (or the
index-codebase skill), which handles the install (uv/pipx/pip), adds
.repowise/ to git's global ignore so the index never clutters the repo,
and runs a keyless index (--index-only, no provider key requested).
Install steps (executed only when the all-or-none group is accepted):
uv tool install repowise, else pipx install repowise,
else python3 -m pip install --user repowise.--index-only mode so no API key
is requested; the index lands under .repowise/ (gitignored).claude mcp add --help for the exact invocation. Server-name caveat:
the agents' grants assume the server name plugin_repowise_repowise; if a
different name is used the grants are inert and agents fall back to
Read/Grep/Glob.{"repowise": {"install_accepted": true}} into
.claude/init-state.json. On failure, surface the error and merge
{"repowise": {"install_failed": true}} — do not claim the group fully
installed (see the partial-failure rule above).Detection probe (used by the group's "already present" check and re-runs):
command -v repowise > /dev/null 2>&1 && echo "installed" || echo "not-installed"
[ -d "${PWD}/.repowise" ] && echo "indexed" || echo "not-indexed"
Graphify (graphifyy on PyPI) is a multi-modal knowledge graph tool
(code + docs + schemas + infra + images/video). Unlike CodeGraph it is a
repo-level native integration — its installer writes a /graphify
skill, PreToolUse nudge hooks into .claude/settings.json, and a
## graphify section into the project's own CLAUDE.md.
This sub-section runs only after the Graphify opt-in in Step 4c accepts — that is, the user said yes. Its integration is repo-level, so none of the file writes below happen unless that opt-in was accepted; no model/API key is required to reach or complete this sub-section — the AST build is keyless.
Install (fallback chain):
command -v uv > /dev/null 2>&1 && uv tool install graphifyy \
|| command -v pipx > /dev/null 2>&1 && pipx install graphifyy \
|| python3 -m pip install --user graphifyy
Native integration, with the CLAUDE.md corruption guard. Graphify's
install --project updater matches the literal ## graphify header and
replaces everything between it and the next ## heading — a known bug can
over-delete, taking unrelated pre-existing content with it. Guard every run:
Snapshot the project's CLAUDE.md before installing — a plain file
copy (e.g. cp CLAUDE.md /tmp/claude-md-pre-graphify.bak, or a
project-local temp path), regardless of whether the repo is git-tracked.
git stash is unsafe mid-flow and must not be used.
Run the installer:
graphify install --project
graphify hook install
Diff the snapshot against the post-install CLAUDE.md. If any line
present in the snapshot is missing from the new file, treat it as the
known corruption bug. (scripts/lib/claude_md_guard.py implements this
snapshot/diff/restore logic in isolation and is unit-tested at
tests/scripts/test_claude_md_guard.py — reuse its
run_install_with_guard function rather than re-deriving the diff by
hand.)
On detected corruption: restore the snapshot, then append the
canonical ## graphify section text at EOF yourself. Source the
canonical text either by capturing graphify's own generated section from
a clean scratch-dir install first, or by reusing the fixed template that
matches this repo's own root CLAUDE.md ## graphify section (see
/home/user/agentic-dev-team/CLAUDE.md for the canonical section this
repo already carries).
On no corruption detected: leave the installer's output as-is — nothing further to do.
Build the graph — keyless AST pass (issue #1224). Graphify's AST
structural graph builds with no model/API key: graphify extract . runs
the AST pass, skips the semantic pass gracefully when no key is present, and
exits 0 with a valid graph.json. This is the graph the agents actually
traverse (graphify query/path/explain).
Idempotent: if graphify-out/graph.json already exists, skip extraction
and offer the incremental, keyless refresh instead:
graphify update .
Otherwise build it (keyless):
graphify extract .
This writes graphify-out/graph.json (gitignored) plus GRAPH_REPORT.md.
Without a provider key it structurally clusters communities but leaves them
unlabeled (Community N) and skips inferred edges — the structure is intact.
Non-fatal: if extraction fails, print the error, merge
{"graphify": {"build_failed": true}} into .claude/init-state.json, and
continue — never abort the rest of setup, and never claim the group fully
installed (the partial-failure rule). Agents that consume graphify fall back
to Read/Grep/Glob when graphify-out/ is absent (see
knowledge/codegraph-vs-graphify.md).
Semantic enrichment (key-gated add-on). Only when a provider key is present
(per Step 4c step 4), enrich the keyless graph: graphify label names the
structural communities, and graphify extract . --mode deep adds INFERRED
semantic edges. Both stay non-fatal — if the key is rejected at build time the
keyless graph stands as-is. With no key, skip this step entirely.
Gitignore advice. graphify hook install creates machine-specific
generated git hooks. Tell the user to gitignore them the same way this
repo's own root .gitignore does for its own graphify hooks:
graphify-out/
.husky/post-commit
.husky/post-checkout
(Or .git/hooks/post-* if the target repo does not use husky.)
Run each configured lane's detection probe exactly as the lane registry
defines it, and report per-lane status — including which provider each
slot bound — so the user knows /build's self-heal pass will find the
tools:
| Lane | Probe |
|---|---|
| Python | command -v ruff, command -v mypy |
| JS/TS | npx --no-install oxlint --version (bound alternatives verify the same way: npx --no-install biome --version, npx --no-install eslint --version) |
| C# | command -v dotnet |
| Java | .pmd/pmd-bin-*/bin/pmd launcher first, then command -v pmd |
Then probe every capability tool that Step 4b installed, using its verify
command from references/capability-tools.md:
| Capability | Probe |
|---|---|
| semgrep | semgrep --version |
| Playwright | npx --no-install playwright --version |
| adr | adr help |
| gh | gh --version |
| docker scanners | hadolint --version, trivy --version, grype --version |
| codegraph | command -v codegraph, .codegraph/ present |
| graphify | graphify --version |
A capability tool that was offered but not confirmed, or whose signal never fired, is simply not probed — it is not a failure.
After every configured lane probes green, give the user:
Scaffold a new JavaScript project with opinionated defaults for ES modules, functional development, and modern tooling. Goal: zero to working/linted/tested in under a minute, with every config file explained and customizable.
Defaults:
"type": "module")const, no mutationlint/lint:fix; ESLint flat config with functional rules stays available as the deep pass (lint:deep) for plugin-only rules.gitignore: node_modules, dist, build, coverage, .env, .env.*, OS filesThis scaffold is the base tooling layer. It does not replace
framework-specific CLIs (npx sv create, ng new, npm create vite@latest). For a full framework scaffold, run the framework CLI first,
then layer on these configs.
Present the defaults above as the three-column plan's missing and will
add column and ask: "Want to change anything, or should I go ahead?"
Include Playwright in the summary only if the user mentions a frontend
project (React, Svelte, Angular, Vue, Next.js, Nuxt, SvelteKit, Astro, UI,
web app, dashboard). Wait for confirmation before writing files. Under
--yes, proceed with these defaults without the customization prompt — the
scaffold only writes into an empty/near-empty directory, so nothing existing
is overwritten.
npm init -y
Read the generated package.json, then edit to:
"type": "module""main" for non-libraries){
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"lint": "oxlint .",
"lint:fix": "oxlint --fix .",
"lint:deep": "eslint .",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky"
},
"lint-staged": {
"*.{js,mjs,cjs}": ["prettier --write", "oxlint --fix"],
"*.{json,md,yaml,yml}": ["prettier --write"]
}
}
lint-staged runs Prettier (and oxlint --fix on JS) against only the staged
files on each commit, so formatting/lint drift is corrected automatically before
it lands — without scanning the whole tree. lint:deep runs the full ESLint
pass for the framework-plugin rules oxlint lacks.
Frontend projects also add: "test:e2e": "playwright test".
npm install -D eslint prettier vitest @eslint/js eslint-config-prettier husky lint-staged oxlint
If this (or the Playwright install below) fails with npm error code ERESOLVE, the peer conflict is pre-existing in the repo's tree, not with the
tooling being added — retry the failing command once with --legacy-peer-deps
and note to the user that you did so, rather than aborting.
eslint-config-prettier disables ESLint rules that conflict with Prettier. Do NOT install eslint-plugin-prettier — run Prettier as a separate step (npm run format:check), not through ESLint.
Frontend projects also:
npm install -D @playwright/test
npx playwright install
Templates: references/configs.md. Required files:
eslint.config.js — flat config with functional rules (no classes, prefer const, no var, no param reassign)prettier.config.js — 2-space, single quotes, trailing commas, 100-char width.editorconfig — 2-space, UTF-8, LF, trim trailing whitespace, final newline.gitignore — node_modules, dist, build, coverage, .env, .env.*, OS files (DS_Store, Thumbs.db)vitest.config.js — minimal config pointing at test filesplaywright.config.js — chromium, sensible defaultssrc/index.js — single exported pure function with JSDoc (e.g., greet or add)
src/index.test.js — one passing vitest test for the starter function
Frontend projects also create e2e/example.spec.js — one Playwright placeholder.
git init # skip if already a git repo
npx husky init
Create both hooks (templates in references/configs.md):
echo 'npx lint-staged' > .husky/pre-commit
echo 'npm test' > .husky/pre-push
npx husky init writes a default pre-commit; the command above overwrites it.
Frontend projects also run the e2e suite on push:
echo 'npm test
npm run test:e2e' > .husky/pre-push
The pre-commit hook auto-fixes only the staged files (prettier --write +
oxlint --fix) so the commit loop stays fast and clean; the pre-push hook runs
the test suite to gate what goes upstream. Because lint-staged formats and lints
on commit, the redundant npm run format:check and npm run lint steps are no
longer needed on pre-push.
npm run lint
npm run format:check
npm test
If any command fails, fix it before reporting success. Show the user the test output, then finish with the shared Step 5 probes and Step 6 summary above.
If the user changes the scaffold defaults:
| Request | Update |
|---|---|
| Different indent size | prettier config, editorconfig, eslint indent rule |
| Tabs instead of spaces | prettier (useTabs: true), editorconfig (indent_style = tab) |
| Double quotes | prettier (singleQuote: false) |
| Different print width | prettier config |
| Semicolons | prettier (semi: true/false) |
| Yarn / pnpm | substitute the package manager in all install commands; adjust scripts if needed |
| TypeScript | the scaffold's starter files are JS-only — run the framework/TS CLI first, then re-run this skill for the toolchain layer |
| Additional ESLint plugins | install and add to the flat config array |
npx claudepluginhub bdfinst/agentic-dev-team --plugin dev-teamDetects your project stack and interactively configures metaswarm, writes instruction files (AGENTS.md/CLAUDE.md/GEMINI.md), coverage thresholds, and command shims for pytest, vitest, jest, go, cargo.
Bootstraps new projects interactively (Node/TS scripted, others manual) or adds enforcement tooling (TDD, secret scanning, file limits, git hooks, CLAUDE.md) to existing projects.
Generates CLAUDE.md, auto-format hooks, and test infrastructure for new or existing projects. Detects empty directories and offers scaffolding. Supports monorepos and multi-repo workspaces.