From looper
Configure Looper quality gates for your project through guided detection and Q&A
How this skill is triggered — by the user, by Claude, or both
Slash command
/looper:looper-configThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate a `.claude/looper.json` configuration by detecting the project's tech stack and guiding the user through targeted refinement.
Generate a .claude/looper.json configuration by detecting the project's tech stack and guiding the user through targeted refinement.
/looper:looper-configlooper.jsonExecute these four phases in order. Never skip DETECT or PROPOSE. Always wait for user confirmation before writing files.
Scan the project root for stack indicators. Use Glob and Read tools - do not guess.
Check these files (existence only unless noted):
| File | Indicates | Also read |
|---|---|---|
package.json | Node/npm | Read scripts and devDependencies keys |
tsconfig.json | TypeScript | - |
deno.json or deno.jsonc | Deno | - |
pyproject.toml | Python | Read for [tool.ruff], [tool.mypy], [tool.pytest] |
setup.py or requirements.txt | Python | - |
go.mod | Go | - |
Cargo.toml | Rust | - |
Makefile | Make-based builds | Scan for test: target |
node_modules/.bin/eslint | ESLint installed | - |
node_modules/.bin/prettier | Prettier installed | - |
node_modules/.bin/biome | Biome installed | - |
node_modules/.bin/vitest | Vitest installed | - |
.eslintrc* or eslint.config.* | ESLint configured | - |
.prettierrc* | Prettier configured | - |
jest.config.* | Jest configured | - |
vitest.config.* | Vitest configured | - |
mypy.ini or pyrightconfig.json | Python type checker | - |
ruff.toml or .ruff.toml | Ruff linter | - |
.golangci.yml | golangci-lint configured | - |
From package.json, extract:
scripts.test - test commandscripts.lint - lint commandscripts.format or scripts.prettier - format commandscripts.typecheck or scripts.check - type check commanddevDependencies - installed tool names (eslint, prettier, biome, jest, vitest, mocha)ESLint version detection:
eslint.config.* (flat config) is found, use npx eslint . without --ext flag (deprecated in ESLint v9+).eslintrc* (legacy config) is found, use npx eslint . --ext .ts,.tsx (or appropriate extensions)Conflicting tools:
scripts.test actually invokesCheck for existing config:
.claude/looper.json already exists, read it and offer to update rather than replaceRun all detection checks in parallel where possible.
Map detected tools to the closest preset from references/stack-presets.md. Then present the proposal.
Output format (print this, do not use AskUserQuestion):
List what was detected (runtime, test runner, linter, formatter, type checker), then show the proposed gates and checks in a compact table with name, weight, required/optional, and command. Show the matching preset name from references/stack-presets.md so the user understands the basis. End with Settings: max_iterations=10.
Then ask:
Does this look right? Tell me what to change, or say "looks good" to continue.
Wait for the user's response. If they request changes, apply them and re-propose. If they approve, move to REFINE.
Ask targeted follow-up questions using AskUserQuestion. Only ask about things that matter and can't be auto-detected. Skip questions where the default is clearly appropriate.
Round 1 - Basics (always ask):
Use AskUserQuestion with these questions:
Round 2 - Advanced (ask only if the user seems interested in customization):
If the user selects custom context, ask them to type their context lines. If they select custom discovery, ask what commands to run.
Do NOT ask about:
enabled field (everything is enabled by default)These are advanced options users can edit manually later.
looper.json to the user in a code blockjq empty .claude/looper.json/plugin install looper@claude-plugins-official once the marketplace listing is liveNever guess commands. Only propose commands for tools that were positively detected in DETECT. If you're unsure whether a tool is installed, use skip_if_missing.
Use skip_if_missing for all tool-dependent gates. This makes the config portable - it works even if tools are later removed or not yet installed.
Default weights must sum to 100. Redistribute proportionally if a category is missing. For example, if there's no formatter: typecheck=35, lint=25, test=40.
Default to required=true for all gates except coverage and formatting. These two are commonly optional because they can be noisy.
Always include checks for the detected formatter and linter. These give Claude fast per-file feedback without waiting for the Stop hook.
Show config before writing. Never write .claude/looper.json without explicit user confirmation.
Validate after writing. Run jq empty on the generated file to catch JSON syntax errors.
Respect existing config. If .claude/looper.json already exists, show the user what would change and offer to merge rather than overwrite.
skip_if_missing instead of hoping the tool existsmax_iterations below 3 - too few passes to be usefulrequired: false - the loop needs at least one required gate to drive iterationnpx for Node tools, bare commands for system toolsrun_when patterns unless the user specifically asks - it's an advanced feature that can cause gates to be silently skippedpattern field - without it, every file edit triggers every checknpx claudepluginhub srdjan/looperGuides completion of development work by verifying tests, detecting environment, and presenting structured options for merge, PR, or cleanup.
Enforces test-driven development: write failing test first, then minimal code to pass. Use when implementing features or bugfixes.
Guides creation and editing of skills using test-driven development with pressure scenarios and subagents to verify agent compliance.