| name | init-dev-team |
| description | Install required tools for the dev-team plugin. OS-aware (macOS, Linux, Windows Git Bash): installs jq and python3 as hard dependencies, then prompts for language selection (JS/TS, Java, C#) to install the matching mutation testing tool (Stryker, pitest, Stryker.NET). Run this when the mutation gate reports a missing tool. |
| user-invocable | true |
| allowed-tools | Read, Bash, Write |
Init Dev Team
Role: worker. Installs tools required by the dev-team plugin, with a
focus on the mutation gate. Run after the plugin is installed, or when the
mutation gate reports a missing dependency.
Arguments: none — interactive prompts drive selection.
You have been invoked with the /init-dev-team command.
Worker constraints
- Install prerequisites and write config only where the user confirms.
- Be OS-aware; do not assume a package manager.
- Be concise. Report what was installed/skipped, no narration.
Step 1 — Detect OS
Run the following and record the result:
uname -s
Darwin → macOS (use brew)
Linux → Linux (detect package manager below)
MINGW* or MSYS* (e.g. MINGW64_NT-10.0-22621) → Windows running Git Bash
(detect Windows package manager below)
- Other → note the platform; provide manual instructions and continue
Windows note: Claude Code on Windows runs in Git Bash (MINGW) or WSL.
WSL reports Linux and is fully handled by the Linux steps. The Windows
steps below apply to native Git Bash only. If you are using WSL, follow
the Linux steps instead.
For Linux, detect the available package manager:
command -v apt-get && echo apt
command -v dnf && echo dnf
command -v yum && echo yum
command -v pacman && echo pacman
Use the first one found.
For Windows (Git Bash), detect the available package manager:
command -v winget && echo winget
command -v choco && echo choco
command -v scoop && echo scoop
Use the first one found. If none are found, tell the user:
"No Windows package manager detected. Install winget (built into Windows 10/11
via the App Installer), Chocolatey (https://chocolatey.org), or Scoop
(https://scoop.sh), then re-run /init-dev-team."
Step 2 — Install hard dependencies (jq and python3)
These are required by the mutation gate regardless of language.
jq
Check if already installed:
command -v jq && jq --version
If missing, install:
| OS | Command |
|---|
| macOS | brew install jq |
| Linux (apt) | sudo apt-get install -y jq |
| Linux (dnf/yum) | sudo dnf install -y jq or sudo yum install -y jq |
| Linux (pacman) | sudo pacman -S --noconfirm jq |
| Windows (winget) | winget install jqlang.jq |
| Windows (choco) | choco install jq |
| Windows (scoop) | scoop install jq |
| Unknown | Tell the user: "Install jq manually from https://jqlang.github.io/jq/ and re-run /init-dev-team." |
python3
Check if already installed:
command -v python3 && python3 --version
If missing, install:
| OS | Command |
|---|
| macOS | brew install python3 |
| Linux (apt) | sudo apt-get install -y python3 |
| Linux (dnf/yum) | sudo dnf install -y python3 or sudo yum install -y python3 |
| Linux (pacman) | sudo pacman -S --noconfirm python |
| Windows (winget) | winget install Python.Python.3 |
| Windows (choco) | choco install python |
| Windows (scoop) | scoop install python |
| Unknown | Tell the user: "Install Python 3 manually from https://python.org and re-run /init-dev-team." |
Windows python3 alias: Windows installers often register the binary as
python, not python3. After installing, check:
command -v python3 || python --version
If only python is found, create a Git Bash alias so the mutation gate can
find it:
echo "alias python3='python'" >> ~/.bashrc && source ~/.bashrc
Verify with python3 --version before proceeding.
If either installation fails, stop and tell the user: "Could not install
<tool>. Please install it manually and re-run /init-dev-team."
Step 2.5 — Offer CodeGraph
CodeGraph (https://github.com/colbymchenry/codegraph) is a third-party SQLite
knowledge graph of every symbol, edge, and file in the workspace. When present,
the plugin's codegraph-nudge hook recommends codegraph_context /
codegraph_explore over multi-file Read/Grep/Glob exploration. This step
detects current state and offers the right next action.
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 to Step 3. 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)
- If
.codegraph.install_declined == true: print
CodeGraph: previously declined install (remove the codegraph key from .claude/init-state.json to re-prompt)
and continue to Step 3.
- Otherwise prompt:
Install CodeGraph for code intelligence? (y/N)
- On
y or Y: print CodeGraph install instructions: https://github.com/colbymchenry/codegraph#installation.
Merge {"codegraph": {"install_accepted": true}} into .claude/init-state.json.
- On any other response (including empty): merge
{"codegraph": {"install_declined": true}} and continue silently.
Init prompt branch (installed=true, initialized=false)
- If
.codegraph.init_declined == true: print
CodeGraph: previously declined init (remove the codegraph key from .claude/init-state.json to re-prompt)
and continue.
- Otherwise prompt:
CodeGraph is installed but not initialized in this project. Initialize now? (y/N)
- On
y or Y:
- Print:
Running 'codegraph init -i' in this project...
- Execute
codegraph init -i with the current working directory as cwd.
Surface its stdout/stderr to the user.
- On exit 0: print
CodeGraph: initialized ✓, merge
{"codegraph": {"init_accepted": true}} into .claude/init-state.json,
then run the Share CodeGraph with the team step below.
- On non-zero exit N: print
CodeGraph init failed (exit code N). See output above. Continuing without CodeGraph.
Do NOT modify .claude/init-state.json.
- On any other response: merge
{"codegraph": {"init_declined": true}}
and continue silently.
Share CodeGraph with the team (after a successful init)
The CodeGraph database (.codegraph/codegraph.db) is derived from source and
machine-local — .codegraph/.gitignore excludes *.db, so it is never
committed. The team shares CodeGraph by committing two things so every
clone bootstraps its own local index automatically (no per-developer
codegraph init):
- The committed
.codegraph/ directory (its .gitignore). This is the
repo's opt-in signal. On a fresh clone the plugin's codegraph-bootstrap.sh
SessionStart hook sees .codegraph/ but no local *.db and rebuilds the
index automatically.
- A project-root
.mcp.json registering the CodeGraph MCP server, so
every teammate's Claude Code session auto-starts codegraph serve --mcp
(its file-watcher + connect-time catch-up keep the index current).
Write/merge .mcp.json at the project root without clobbering any existing
server entries:
MCP_BLOCK='{"mcpServers":{"codegraph":{"type":"stdio","command":"codegraph","args":["serve","--mcp"]}}}'
if [ -f .mcp.json ]; then
tmp="$(mktemp)"
jq --argjson add "$MCP_BLOCK" '. * $add' .mcp.json > "$tmp" && mv -f "$tmp" .mcp.json
else
printf '%s\n' "$MCP_BLOCK" | jq . > .mcp.json
fi
Then print: CodeGraph: wrote .mcp.json — commit it with .codegraph/.gitignore so teammates auto-bootstrap CodeGraph on clone.
Do not run git add/git commit yourself; leave staging to the user.
.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.
Step 3 — Select languages
Ask the user which language ecosystems they are working with. Allow multiple
selections:
"Which languages do you need mutation testing for? (Select all that apply)"
- JS/TS — Stryker (
@stryker-mutator/core)
- Java / Kotlin — pitest (
pitest-maven or info.solidsoft.gradle.pitest)
- C# / .NET — Stryker.NET (
dotnet-stryker)
- All of the above
- None — just install jq and python3
Parse the user's response. If they choose 4, treat it as selecting 1, 2, and 3.
Step 4 — Install per-language mutation tools
Run only the sections for the languages the user selected.
JS/TS — Stryker
Prerequisites check:
command -v node && node --version
command -v npm && npm --version
If node or npm is not found, tell the user:
"Node.js is required for Stryker. Install it from https://nodejs.org and
re-run /init-dev-team." Do not proceed with this language section.
Bootstrap project if package.json is missing:
test -f package.json && echo "package.json found" || echo "no-package"
If the result is no-package:
- Print:
No package.json found. Running /dev-team:js-project-init first to scaffold the project.
- Invoke the
/dev-team:js-project-init skill. It will scaffold a
functional ES-module project with prettier, eslint, editorconfig, and
vitest (see the skill's own documentation for the full default set).
- After the skill returns:
- If
package.json now exists → proceed to "Check if already installed".
- If
package.json still does not exist (user aborted js-project-init):
print Stryker skipped — no package.json. Re-run /init-dev-team after scaffolding your JS project.
and skip the rest of the JS/TS section.
- If the skill reported an explicit failure: print
Stryker skipped — js-project-init failed. See errors above and re-run /init-dev-team after resolving them.
and skip the rest of the JS/TS section.
If the result is package.json found, proceed directly to "Check if already installed".
Check if already installed (project-local):
test -f node_modules/.bin/stryker && echo "installed" || echo "not found"
If not installed, add Stryker as a dev dependency:
npm install --save-dev @stryker-mutator/core
Then detect the test runner and install the matching Stryker plugin:
cat package.json 2>/dev/null | grep -E '"vitest"|"jest"|"mocha"|"jasmine"' | head -5
Install the appropriate runner plugin:
| Detected runner | Install command |
|---|
| vitest | npm install --save-dev @stryker-mutator/vitest-runner |
| jest | npm install --save-dev @stryker-mutator/jest-runner |
| mocha | npm install --save-dev @stryker-mutator/mocha-runner |
| jasmine | npm install --save-dev @stryker-mutator/jasmine-runner |
| none detected | Install vitest runner as default: npm install --save-dev @stryker-mutator/vitest-runner and note to the user they may need to swap this for their runner |
Initialize Stryker config if not already present:
test -f stryker.config.js -o -f stryker.config.mjs -o -f stryker.config.ts \
-o -f stryker.config.cjs -o -f .strykerrc.json && echo "config exists" || echo "no config"
If no config exists, run:
npx stryker init
This generates a stryker.config.mjs interactively. Tell the user it will ask
a few questions; they should accept defaults unless they have a specific setup.
Verify:
npx stryker --version
Java / Kotlin — pitest
Prerequisites check:
command -v mvn && echo "maven found"
command -v gradle && echo "gradle found"
If neither is found, tell the user:
"Maven or Gradle is required for pitest. Install one from
https://maven.apache.org or https://gradle.org and re-run /init-dev-team."
Detect build tool:
test -f pom.xml && echo "maven"
test -f build.gradle -o -f build.gradle.kts && echo "gradle"
Maven — check if pitest-maven already configured:
grep -q 'pitest-maven' pom.xml 2>/dev/null && echo "configured" || echo "not configured"
If not configured, add the pitest-maven plugin to pom.xml. Find the
<build><plugins> section and insert:
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.17.4</version>
<configuration>
<outputFormats>
<param>XML</param>
</outputFormats>
<timestampedReports>false</timestampedReports>
</configuration>
</plugin>
Tell the user: "Added pitest-maven plugin to pom.xml. Run
mvn pitest:mutationCoverage to verify."
Gradle — check if pitest plugin already applied:
grep -q 'pitest' build.gradle 2>/dev/null || grep -q 'pitest' build.gradle.kts 2>/dev/null \
&& echo "configured" || echo "not configured"
If not configured, tell the user to add the following to build.gradle or
build.gradle.kts manually (Gradle plugins cannot be added programmatically):
For build.gradle:
plugins {
id 'info.solidsoft.pitest' version '1.15.0'
}
pitest {
outputFormats = ['XML']
timestampedReports = false
}
For build.gradle.kts:
plugins {
id("info.solidsoft.pitest") version "1.15.0"
}
configure<com.info.solidsoft.pitest.PitestPluginExtension> {
outputFormats.set(setOf("XML"))
timestampedReports.set(false)
}
Verify (Maven only — Gradle requires manual add):
mvn pitest:mutationCoverage -DtimestampedReports=false -DoutputFormats=XML --help 2>&1 | head -5
C# / .NET — Stryker.NET
Prerequisites check:
command -v dotnet && dotnet --version
If dotnet is not found, tell the user:
".NET SDK is required for Stryker.NET. Install it from https://dotnet.microsoft.com
and re-run /init-dev-team."
Check if dotnet-stryker already installed:
dotnet tool list --global 2>/dev/null | grep stryker
dotnet tool list --local 2>/dev/null | grep stryker
If not installed globally or locally, install as a local tool:
Create or update .config/dotnet-tools.json:
test -f .config/dotnet-tools.json || dotnet new tool-manifest
dotnet tool install dotnet-stryker
If the user prefers global install (e.g., using Stryker across many projects),
offer:
dotnet tool install --global dotnet-stryker
Verify:
dotnet stryker --version 2>/dev/null || dotnet tool run dotnet-stryker --version
Step 5 — Summary
Print a summary of what was installed:
dev-team: init complete
Hard dependencies:
jq: ✓ <version>
python3: ✓ <version>
Mutation testing:
JS/TS (Stryker): ✓ <version> [or: ✗ skipped | ✗ failed]
Java (pitest-maven): ✓ configured [or: ✗ skipped | ✗ manual steps needed]
C# (Stryker.NET): ✓ <version> [or: ✗ skipped | ✗ failed]
The mutation gate will now block zero-kill tests after each RED→GREEN transition.
Run a test suite to verify: when tests go from failing to passing, the gate
should analyze them within 60 seconds.
If any step failed, add a "Next steps" section with the specific manual actions
needed.