From metaswarm
Interactively sets up metaswarm: detects project stack via markers (Node/JS/TS, Python, Go, Rust, Java, Ruby), asks questions, writes CLAUDE.md, coverage thresholds, and command shims.
npx claudepluginhub dsifry/metaswarmThis skill uses the workspace's default tool permissions.
Interactive, Claude-guided setup for metaswarm. Detects your stack, asks targeted questions, writes project-local files, and creates command shims. Replaces both `npx metaswarm init` and the old `/metaswarm-setup` command.
bin/estimate-cost.shbin/external-tools-verify.shbin/pr-comments-check.shbin/pr-comments-filter.shknowledge/README.mdknowledge/anti-patterns.jsonlknowledge/api-behaviors.jsonlknowledge/codebase-facts.jsonlknowledge/decisions.jsonlknowledge/facts.jsonlknowledge/gotchas.jsonlknowledge/patterns.jsonlscripts/beads-fetch-conversation-history.tsscripts/beads-fetch-pr-comments.tstemplates/AGENTS-append.mdtemplates/AGENTS.mdtemplates/CLAUDE-append.mdtemplates/CLAUDE.mdtemplates/GEMINI-append.mdtemplates/GEMINI.mdScans codebase for package managers, tests, CI/CD, deployment, and docs; infers configs with confidence scores; asks only unknowns; generates SDLC files like README and ARCHITECTURE.md. For initial setup.
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.
Bootstraps repo infrastructure and AI harness: detects languages/tools, installs missing ones, configures CI/CD/pre-commit hooks, discovers constraints from code/git, generates AGENTS.md/learnings, sets hookify rules. Audits existing harnesses for staleness.
Share bugs, ideas, or general feedback.
Interactive, Claude-guided setup for metaswarm. Detects your stack, asks targeted questions, writes project-local files, and creates command shims. Replaces both npx metaswarm init and the old /metaswarm-setup command.
After Phase 2 (user questions), determine the correct coverage command from the detection results, then run this Bash command:
bash "${CLAUDE_PLUGIN_ROOT}/lib/setup-mandatory-files.sh" "$(pwd)" <threshold> "<coverage-command>"
Where:
<threshold> is the user's chosen percentage (e.g., 100)<coverage-command> is the enforcement command for their test runner:
"pytest --cov --cov-fail-under=<threshold>""pnpm vitest run --coverage""npx jest --coverage""go test -coverprofile=coverage.out ./...""cargo tarpaulin --fail-under <threshold>"The script handles:
.coverage-thresholds.json — writes at project root with correct thresholds and command.claude/commands/ — writes start-task.md, prime.md, review-design.md, self-reflect.md, pr-shepherd.md, brainstorm.mdThe script outputs JSON with what was created/skipped/errored. Check that "status": "ok".
If the script is not available or fails, fall back to writing these files manually with the Write tool. Do NOT skip them.
Use Glob to check if .metaswarm/project-profile.json exists.
Scan the project directory silently using Glob and Read. Do NOT ask the user for any of this information. Detect everything, then present results.
Check for marker files at the project root:
| Marker File | Language |
|---|---|
package.json | Node.js / JavaScript |
tsconfig.json | TypeScript (refines Node.js to TypeScript) |
pyproject.toml OR setup.py OR requirements.txt | Python |
go.mod | Go |
Cargo.toml | Rust |
pom.xml OR build.gradle OR build.gradle.kts | Java |
Gemfile | Ruby |
Makefile (alone, no other markers) | Unknown (ask user) |
If tsconfig.json exists alongside package.json, the language is "TypeScript".
If multiple languages are detected, note all of them but use the primary one (most infrastructure) for command generation.
If no language detected: Use AskUserQuestion to ask the user what language/stack they are using before proceeding.
Node.js/TypeScript — Read package.json and check dependencies + devDependencies:
| Dependency | Framework |
|---|---|
next | Next.js |
nuxt OR nuxt3 | Nuxt |
@angular/core | Angular |
svelte OR @sveltejs/kit | SvelteKit |
react (without next/nuxt) | React |
vue (without nuxt) | Vue |
express | Express |
fastify | Fastify |
hono | Hono |
@nestjs/core | NestJS |
Python — Check pyproject.toml or requirements.txt for: fastapi, django, flask.
Go — Read go.mod for: github.com/gin-gonic/gin (Gin), github.com/labstack/echo (Echo), github.com/gofiber/fiber (Fiber).
If no framework detected, set to null.
| Lock File | Package Manager |
|---|---|
pnpm-lock.yaml | pnpm |
yarn.lock | yarn |
bun.lockb | bun |
package-lock.json | npm |
Default to npm if no lock file found. For non-Node.js, set to null.
Node.js/TypeScript (first match wins):
vitest.config.* or vitest in devDependencies -> vitestjest.config.* or jest in devDependencies -> jestmocha in devDependencies -> mochaPython: Check for [tool.pytest] in pyproject.toml or pytest in dependencies -> pytest (default for Python).
Go: go test (built-in). Rust: cargo test (built-in). Java/Maven: mvn test. Java/Gradle: gradle test.
| Marker | Linter |
|---|---|
.eslintrc* OR eslint.config.* OR eslint in devDependencies | eslint |
biome.json OR @biomejs/biome in devDependencies | biome |
[tool.ruff] in pyproject.toml OR ruff.toml | ruff |
.golangci.yml OR .golangci.yaml | golangci-lint |
.clippy.toml or clippy in Cargo.toml | clippy |
| Marker | Formatter |
|---|---|
.prettierrc* OR prettier in devDependencies | prettier |
biome.json (also formats) | biome |
black in Python deps | black |
[tool.ruff.format] in pyproject.toml | ruff format |
rustfmt.toml OR .rustfmt.toml | rustfmt |
If biome detected as both linter and formatter, report once as "Biome (lint + format)".
| Marker | Type Checker |
|---|---|
tsconfig.json | tsc |
mypy in Python deps OR [tool.mypy] in pyproject.toml | mypy |
pyright in Python deps OR pyrightconfig.json | pyright |
Go (go vet) and Rust (cargo check) have built-in type checking — note but do not list separately.
| Marker | CI System |
|---|---|
.github/workflows/*.yml | GitHub Actions |
.gitlab-ci.yml | GitLab CI |
Jenkinsfile | Jenkins |
.circleci/config.yml | CircleCI |
| Marker | Hook System |
|---|---|
.husky/ | Husky |
.pre-commit-config.yaml | pre-commit |
.lefthook.yml | Lefthook |
After all detection, present findings:
I detected the following about your project:
Language: {language}
Framework: {framework or "None detected"}
Package manager: {package_manager or "N/A"}
Test runner: {test_runner or "None detected"}
Linter: {linter or "None detected"}
Formatter: {formatter or "None detected"}
Type checker: {type_checker or "None detected"}
CI: {ci or "None detected"}
Git hooks: {git_hooks or "None detected"}
Use AskUserQuestion to ask ONLY questions relevant based on detection. 3-5 questions maximum.
Always ask:
Ask only if relevant:
External AI tools — Ask only for non-trivial projects: "Set up external AI tools (Codex/Gemini) for cost savings on implementation?" Options: "Yes" / "No"
Visual review — Ask only if a web framework was detected (Next.js, Nuxt, React, Vue, Angular, SvelteKit, Django, Flask): "Enable visual screenshot review for UI changes?" Options: "Yes" / "No"
CI pipeline — Ask only if NO CI detected: "Create a GitHub Actions CI pipeline?" Options: "Yes (Recommended)" / "No"
Git hooks — Ask only if NO hooks detected: "Set up git hooks for pre-push quality checks?" Options: "Yes (Recommended)" / "No"
This is the FIRST thing to do after Phase 2. Determine the coverage command, then run:
bash "${CLAUDE_PLUGIN_ROOT}/lib/setup-mandatory-files.sh" "$(pwd)" <threshold> "<coverage-command>"
Example for Python with pytest at 100%:
bash "${CLAUDE_PLUGIN_ROOT}/lib/setup-mandatory-files.sh" "$(pwd)" 100 "pytest --cov --cov-fail-under=100"
Check the JSON output. If "status": "ok", the 3 mandatory files are done. Report to the user what was created.
If the script fails or is not found, write the files manually (see CRITICAL-REQUIREMENTS above for what they are).
If CLAUDE.md was newly written (not appended), use Edit to replace the TODO placeholders:
npm test / npm run test:coverage with the detected test/coverage commandsTypeScript strict mode / ESLint + Prettier with the detected language tools<!-- TODO: ... --> comment linesIf CLAUDE.md was appended to (existing file), this step is not needed.
Read each file from ./knowledge/:
patterns.jsonl, gotchas.jsonl, decisions.jsonl, api-behaviors.jsonl, codebase-facts.jsonl, anti-patterns.jsonl, facts.jsonlWrite them to .beads/knowledge/ in the project. Skip any that already exist.
Read each file from ./bin/:
estimate-cost.sh, external-tools-verify.sh, pr-comments-check.sh, pr-comments-filter.shWrite them to bin/ in the project. Make executable with chmod +x. Skip any that already exist.
Read each file from ./scripts/:
beads-fetch-pr-comments.ts, beads-fetch-conversation-history.tsWrite them to scripts/ in the project. Skip any that already exist.
Note: The former beads-self-reflect.ts script is no longer bundled — the standalone beads plugin (v0.63.3+) provides bd compact for semantic summarization natively.
Node.js dependency warning: If Node.js was NOT detected as the project language, print:
"Note: scripts/*.ts require Node.js (npx tsx) to run. Some advanced features (PR comment fetching, conversation history) will work once Node.js is available. Core metaswarm functionality does not require Node.js."
| Condition | Source | Destination |
|---|---|---|
| User chose YES for CI | ./templates/ci.yml | .github/workflows/ci.yml |
| User chose YES for git hooks AND Husky detected or Node.js project | ./templates/pre-push | .husky/pre-push (chmod +x) |
| User chose YES for external tools | ./templates/external-tools.yaml | .metaswarm/external-tools.yaml |
| Always | ./templates/.env.example | .env.example |
| Always | ./templates/SERVICE-INVENTORY.md | SERVICE-INVENTORY.md |
| Always | ./templates/gitignore | Merge into existing .gitignore (append missing entries, never duplicate) |
For .gitignore, read the existing file (if any), then append language-specific entries that are not already present. Always ensure .env, .DS_Store, and *.log are included.
Write .metaswarm/project-profile.json with all detection results and user choices:
{
"metaswarm_version": "1.0.0",
"distribution": "plugin",
"installed_at": "{current ISO 8601 timestamp}",
"updated_at": "{current ISO 8601 timestamp}",
"detection": {
"language": "{detected language}",
"framework": "{detected framework or null}",
"test_runner": "{detected test runner}",
"linter": "{detected linter or null}",
"formatter": "{detected formatter or null}",
"package_manager": "{detected package manager or null}",
"type_checker": "{detected type checker or null}",
"ci": "{detected CI system or null}",
"git_hooks": "{detected hook system or null}"
},
"choices": {
"coverage_threshold": 100,
"external_tools": false,
"visual_review": false,
"ci_pipeline": false,
"git_hooks": false
},
"commands": {
"test": "{resolved test command}",
"coverage": "{resolved coverage command}",
"lint": "{resolved lint command or null}",
"typecheck": "{resolved typecheck command or null}",
"format_check": "{resolved format check command or null}"
}
}
Fill all values from detection and user answers. Use null for anything not detected.
Command resolution reference:
| Test Runner | Pkg Mgr | Test Command | Coverage Command |
|---|---|---|---|
| vitest | pnpm | pnpm vitest run | pnpm vitest run --coverage |
| vitest | npm | npx vitest run | npx vitest run --coverage |
| vitest | yarn | yarn vitest run | yarn vitest run --coverage |
| jest | pnpm | pnpm jest | pnpm jest --coverage |
| jest | npm | npx jest | npx jest --coverage |
| jest | yarn | yarn jest | yarn jest --coverage |
| mocha | any | npx mocha | npx nyc mocha |
| pytest | -- | pytest | pytest --cov --cov-fail-under={threshold} |
| go test | -- | go test ./... | go test -coverprofile=coverage.out ./... |
| cargo test | -- | cargo test | cargo tarpaulin --fail-under {threshold} |
| mvn test | -- | mvn test | mvn test jacoco:report |
| gradle test | -- | gradle test | gradle test jacocoTestReport |
command -v codex, command -v gemini)--version.metaswarm/external-tools.yaml — set enabled: true for installed tools, enabled: false for missing onesnpx playwright install chromium via BashNode.js/TypeScript: Install Husky if not present, run npx husky init, write pre-push hook.
Python: Suggest pip install pre-commit and offer to create .pre-commit-config.yaml.
Other: Suggest appropriate hook tools for the ecosystem.
Present a final summary:
Setup complete! Here's what was configured:
Project: {name}
Language: {language}
Framework: {framework or "None"}
Test runner: {test_runner} -> `{test command}`
Coverage: {threshold}% -> `{coverage command}`
Linter: {linter or "None"}
Formatter: {formatter or "None"}
CI: {ci or "None"}
Git hooks: {hooks or "None"}
External tools: {Enabled/Disabled}
Visual review: {Enabled/Disabled}
Mandatory files:
✔ CLAUDE.md — {written new / appended metaswarm section / already had it}
✔ .coverage-thresholds.json — {threshold}% coverage, enforcement: `{command}`
✔ .claude/commands/ — 6 shims: start-task, prime, review-design, self-reflect, pr-shepherd, brainstorm
Other files written:
{list every other file written or modified with its path}
You're all set! Run /start-task to begin working.
Command naming: When recommending commands to the user, always use the short shim names (/start-task, /prime, /brainstorm, etc.), NOT the namespaced plugin names (/metaswarm:start-task). The shims you just created in .claude/commands/ make the short names work. The short names are easier to type and remember.
Offer 1-2 relevant tips based on configuration:
/external-tools-health to check tool status."./templates/ci.yml."If /start-task is invoked and .metaswarm/project-profile.json does not exist, the start skill should auto-route here. This skill will run the full setup flow, then hand back to /start-task to continue with the user's original request.
Before saying "setup complete", run this Bash command to verify the 3 mandatory files:
echo "CLAUDE.md:"; grep -c "metaswarm" CLAUDE.md 2>/dev/null || echo "MISSING"; echo "coverage:"; ls .coverage-thresholds.json 2>/dev/null || echo "MISSING"; echo "shims:"; ls .claude/commands/start-task.md .claude/commands/prime.md .claude/commands/brainstorm.md 2>/dev/null || echo "MISSING"
If any output says "MISSING", go back and run the setup-mandatory-files.sh script or create the files manually. Do NOT declare success with missing files.
When reporting available commands to the user, use the short names (/start-task, /prime, /brainstorm, etc.) — NOT the namespaced names (/metaswarm:start-task). The command shims make the short names work. Do NOT recommend commands that don't exist (e.g., /metaswarm:start, /metaswarm:status, /metaswarm:architect-agent).