- name
- setup
- description
- Provision a repo for the dev-team plugin end to end — install the plugin's own prerequisites (jq, python3, per-language mutation tooling — Stryker, pitest, Stryker.NET), then generate dev-team-specific project configuration — project-level CLAUDE.md, the PostToolUse formatting hook, language-specific agent template activation, and a generated `/pr` command — from the stack signal `/dev-team:project-init` establishes. This is NOT where toolchain detection/installation itself lives (that's `/project-init`); `/setup` only consumes it. Use this when onboarding a new project to the dev-team plugin, when the mutation gate reports a missing tool, or when the user says "setup", "bootstrap", "configure this project for dev-team", "install required tools for the dev-team plugin", or "activate agent templates".
- argument-hint
- [--yes] [--dry-run] [--autocompact-pct N] [--no-autocompact]
- user-invocable
- true
- allowed-tools
- Read, Write, Edit, Glob, Grep, Bash
# Project Setup
Role: orchestrator. See frontmatter description for scope; delegates all
stack detection and toolchain install/inventory to `/dev-team:project-init`,
which `/setup` never re-derives.
## Orchestrator constraints
1. Detect and scaffold; delegate generation, do not review code yourself.
2. Install prerequisites and write config only where the user confirms.
3. Do not overwrite existing project config without confirming.
4. Be OS-aware; do not assume a package manager.
5. **Be concise.** Report detected stack, installed prerequisites, and
generated artifacts — no narration.
## Parse Arguments
Arguments: $ARGUMENTS
- `--dry-run`: Report what would be created/installed without writing any
files or installing anything.
- `--yes`: Run unattended — auto-confirm every prompt with its **safe**
default and pass `--yes` through when invoking `/dev-team:project-init`
(Step 4). No step waits for input.
- `--autocompact-pct N`: write `N` (integer 1-100) as the repo's
`CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` (Step 9b) instead of the default `40`.
- `--no-autocompact`: skip Step 9b's settings write and silence the
SessionStart nudge that recommends running `/dev-team:setup`.
### `--yes` semantics (the unattended contract)
When `--yes` is set, take these actions without prompting. **Affirmative** —
auto-confirm and proceed:
- Per-language mutation tooling for the detected stack (Step 6). Already
non-interactive when the stack is definite; `--yes` additionally suppresses
the ambiguous-stack fallback below.
- Agent-template activation for the detected stack (Step 7).
- Project `CLAUDE.md` (Step 8) and `/pr` (Step 10) generation **when the file
is absent**; the downstream `.gitignore` append (Step 11).
- Everything `/dev-team:project-init` auto-confirms under its own `--yes`
(its three-column plan, capability tools whose signal fired, and the keyless
CodeGraph + Repowise pair — see that skill's Arguments section).
**Conservative** — never silently overwrite an existing file or mutate the
repo in a surprising way; take the skip default and print a one-line note:
- **Existing project `CLAUDE.md`** (Step 8) — never overwritten (orchestrator
constraint 3). Skip and note it, exactly as the interactive "merge or skip"
path's skip branch.
- **Coverage-config edits** (Step 6, JS/TS readiness) — `--yes` may install the
additive `@vitest/coverage-v8` devDependency, but does **not** run `--patch`
or hand-edit an existing `jest.config.js` / `vitest.config.*`. Report the
hints as it does interactively; the operator applies those edits.
- **Graphify** — declined for this run inside `/dev-team:project-init` (see
that skill); it writes to the repo, so it stays opt-in even under `--yes`.
- **Unrecognized / ambiguous stack** — `--yes` never guesses a toolchain. Do
the language-neutral steps and report what could not be set up.
- **Concise-response preference** (Step 8a) — `--yes` never guesses a
communication-style preference. Skip the prompt and the `CLAUDE.md`
append entirely; note `concise-preference-skipped-under-yes`. This is
the outcome only when Step 8a's own pre-check found the block absent —
when the block is already present, the pre-check reports
`concise-preference-already-covered` before `--yes` is ever consulted,
regardless of whether `--yes` was passed.
**Precedence.** If both `--yes` and `--dry-run` are passed, `--dry-run` wins:
report only, write and install nothing, and add "`--yes` ignored under
`--dry-run`" to the report.
## Steps
### 1. Detect OS
Run the following and record the result:
```bash
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:
```bash
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:
```bash
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 `/setup`."
### 2. Detect the agentic-dev-team repo and delegate to dev-setup.sh
Before installing anything, check whether this invocation is running inside
the agentic-dev-team plugin-dev repo itself (as opposed to a downstream
project that merely has the plugin installed):
```bash
test -f requirements-dev.txt && test -f plugins/dev-team/.claude-plugin/plugin.json && echo "in-repo" || echo "downstream"
```
- **`in-repo`**: print "Detected the agentic-dev-team repo — running
scripts/dev-setup.sh to bootstrap the plugin-dev toolchain (shellcheck, jq,
python3, Python dev dependencies)." Then run:
```bash
bash scripts/dev-setup.sh
```
Surface its stdout/stderr to the user. `dev-setup.sh` is a separate,
intentionally-kept bash entry point — it works before Claude Code or the
plugin is installed, and is reused as a generic template by
`/new-marketplace` for other marketplace repos (see the note at the top of
`scripts/dev-setup.sh`). This skill calls it rather than reimplementing its
install logic. After it runs, still execute Step 3's jq/python3 checks below
— they are idempotent and confirm dev-setup.sh's work rather than
duplicating installation, so running both is a harmless double-check, not
redundant install logic.
- **`downstream`**: no plugin-dev repo detected — proceed exactly as before
with Step 3 (existing downstream-user behavior, unchanged).
### 3. Install hard dependencies (jq and python3)
These are required by the mutation gate regardless of language.
#### jq
Check if already installed:
```bash
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 `/setup`." |
#### python3
Check if already installed:
```bash
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 `/setup`." |
> **Windows python3 alias:** Windows installers often register the binary as
> `python`, not `python3`. After installing, check:
>
> ```bash
> command -v python3 || python --version
> ```
>
> If only `python` is found, create a Git Bash alias so the mutation gate can
> find it:
>
> ```bash
> 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 `/setup`."
### 4. Invoke `/dev-team:project-init` for stack detection and toolchain
Run `/dev-team:project-init` and let it complete, including its confirmation
gate, before continuing. **Under `--yes`, invoke it as
`/dev-team:project-init --yes`** so its own gates auto-confirm with their safe
defaults rather than blocking (see that skill's Arguments section).
### 5. Record the stack signal for dev-team's own use
`/setup` still needs a small, cheap signal of its own to populate
`.claude/project-stack.json` and to drive Step 6's mutation-tool selection
and Step 7's template selection. `/dev-team:project-init` performs its own
detection in Step 4 but persists no machine-readable artifact for `/setup`
to consume, so this is a deliberate lightweight re-probe using the same
indicator conventions (`skills/project-init/SKILL.md` Step 1 and Step 2) —
`package.json`, `tsconfig.json`, `pyproject.toml`/`requirements*.txt`,
`*.csproj`/`*.sln`, `pom.xml`/`build.gradle*` — plus the handful of framework
dependency checks (`react`, `vue`, `svelte`, `@angular/core`, `next`,
`django`, `flask`, `fastapi`) that project-init's own stack table doesn't
record. It does not repeat project-init's heavier JS/TS ES-module/
TypeScript/require-scan checks or its formatter-selection logic (those stay
entirely project-init's job — its Step 4/Scaffold steps and Step 4b/4c) and
it does not install anything.
Write findings to `.claude/project-stack.json`:
```json
{
"detected": "2026-03-18",
"stacks": ["typescript", "node"],
"frameworks": ["react", "vitest"],
"packageManager": "npm|yarn|pnpm|bun",
"hasDocker": true,
"indicators": {
"package.json": true,
"tsconfig.json": true
}
}
```
### 6. Install per-language mutation tooling
Mutation-tool installation is **strictly relative to the detected stack**.
Do not decide which language sections to run by hand — the mapping is a
deterministic helper, so the wrong-stack probe (e.g. `dotnet` on a JS repo)
cannot fire. Call it once:
```bash
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/mutation_stack_sections.py" .
```
It reads `.claude/project-stack.json`'s `stacks` array (recorded in Step 5)
and prints one JSON object:
```json
{ "sections": ["js"], "stacks": ["typescript", "node"], "ambiguous": false, "note": null }
```
- `sections` — the sections to run, from `js` (JS/TS — Stryker), `java`
(Java/Kotlin — pitest), `csharp` (C#/.NET — Stryker.NET), `python`
(Python — mutmut). The mapping is `typescript`/`node`/`javascript` → `js`,
`java`/`kotlin` → `java`, `csharp`/`dotnet` → `csharp`, `python` →
`python`. **Run every section in `sections` and no others.** More than one
may apply in a polyglot repo.
- `ambiguous` — `true` **only** when the stack signal is genuinely empty or
missing (no `.claude/project-stack.json`, unreadable/invalid, or an empty
`stacks` array). This is the **only** outcome that authorizes the
interactive fallback below.
- `note` — set when a definite stack matched no section (e.g. a Ruby or
Elixir repo — there is no mutation tool wired into this step for that
stack). When `note` is non-null, `sections` is empty and `ambiguous` is
`false`: install **nothing**, probe **nothing** (no `dotnet`, `node`,
`mvn`, or `pip`), print the `note` line verbatim, and skip the rest of
this step.
**Interactive fallback — only when `ambiguous` is `true`.** When a definite
stack was detected (`ambiguous` is `false`), never prompt; honor `sections`
exactly. **Under `--yes`, skip this fallback entirely even when `ambiguous`
is `true`** — never guess a stack: install no mutation tooling and print
`Mutation tooling skipped — no stack detected (run /setup without --yes to choose)`.
Otherwise, only when `ambiguous` is `true` (e.g. `--dry-run` scanning a repo
with no recognizable stack) fall back to asking:
> "Which languages do you need mutation testing for? (Select all that apply)"
>
> 1. **JS/TS** — Stryker (`@stryker-mutator/core`)
> 2. **Java / Kotlin** — pitest (`pitest-maven` or `info.solidsoft.gradle.pitest`)
> 3. **C# / .NET** — Stryker.NET (`dotnet-stryker`)
> 4. **Python** — mutmut
> 5. **All of the above**
> 6. **None — skip mutation tooling**
Parse the response. If they choose 5, treat it as selecting 1, 2, 3, and 4
(i.e. `sections` = `["js", "java", "csharp", "python"]`). If 6, skip the
rest of this step.
Each language subsection below **re-asserts its own gate as its literal
first step** — a section whose key is not in `sections` returns immediately,
before any `command -v` / tool probe. The guard is therefore robust even if
a section is reached out of order.
---
#### JS/TS — Stryker
**Stack gate (first step — hard precondition):** if `js` is not in the
Step 6 helper's `sections`, return immediately. Do **not** run the
prerequisites probe below. Only proceed when `js` is in `sections`.
**Prerequisites check:**
```bash
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 `/setup`." Do not proceed with this language section.
View on GitHub