quality-tools
When to use
Use this skill whenever running or configuring code quality tools:
- PHP: PHPStan (static analysis), Rector (automated refactoring), ECS (coding standards)
- JS/TS: Biome (linting + formatting), TypeScript compiler (type checking), Jest/Vitest (tests)
Modes
This skill is a router head. The cross-mode material — execution policy,
language detection, environment, output, gotchas — lives below. The per-tool
procedure bodies live in references/; load exactly the mode the detected
stack calls for.
| Detected stack |
Mode body |
Covers |
PHP (.php changed) |
references/php-tools.md |
Tool detection, PHPStan / ECS / Rector commands and flags, combined pipeline, config files, baseline policy, PHPStan error handling, testing framework, git-aware execution |
JS/TS (.js / .ts / .tsx changed) |
references/js-ts-tools.md |
Detection, Biome, TypeScript type checking, Jest / Vitest, the JS/TS workflow sequence |
Both stacks changed → load both mode bodies and run both pipelines.
Execution policy — on demand only, never proactive
NEVER RUN QUALITY TOOLS PROACTIVELY WHEN quality.local_auto_run IS
false OR MISSING (THE DEFAULT). DO NOT ASK WHETHER TO RUN THEM.
THE USER RUNS THEM MANUALLY. REMOTE CI IS THE AUTHORITATIVE GATE.
Toolchains differ per language and project and are often unknown to the
agent — discovering and running them burns time and tokens. Under the
default, exactly three triggers justify running a quality tool:
- Explicit ask this turn — the user says so or invokes
/fix quality.
- Concrete CI failure — the remote pipeline reports a failing
check; run exactly that failing check to reproduce and fix it
(
/fix:ci is the canonical flow).
- New-gate carve-out — the change itself introduces a NEW CI gate,
smoke test, or test file; it must run once locally to be proven.
quality.local_auto_run: true restores the legacy autonomous behaviour
(run the pipeline when work is ready for verification). When runs are
suppressed, the completion message says "quality gates delegated to
remote CI" — never that the tools passed.
Language detection
Detect which tools to run based on what files were changed:
# Check changed file extensions (diff against base branch)
git diff --name-only origin/main..HEAD | grep -E '\.(php)$' # → PHP tools
git diff --name-only origin/main..HEAD | grep -E '\.(js|ts|tsx)$' # → JS/TS tools
If both PHP and JS/TS files changed → run both pipelines.
Procedure
- Confirm a run is justified — see Execution policy above. No trigger, no run.
- Detect the stack from the changed files — see Language detection above.
2b. Inspect the project's own quality config before running anything. Read
the config files the detected stack actually ships (
phpstan.neon,
ecs.php, rector.php, biome.json, tsconfig.json, the scripts block
of package.json) and the task/make wrapper if one exists. Never assume a
default ruleset, a default baseline, or a default command — the mode body
names where to look per stack. Running a tool against assumed config
produces findings the project never asked for.
- Load the matching mode body from the table in Modes and follow its
procedure. PHP →
references/php-tools.md
§ Procedure: Run quality checks. JS/TS →
references/js-ts-tools.md
§ JS/TS Quality Workflow.
- Both stacks changed → run both mode procedures; neither result excuses the
other.
- Report per Output format below.
Related rules and guidelines
verify-before-complete rule — no pass claims without fresh output; suppressed runs are surfaced as "delegated to remote CI", never claimed
php-coding rule → PHPStan section — inline ignores, PHPDoc rules
contexts/execution/verification-mechanics.md — Gate zero (local_auto_run) + timing when true (quality tools ONCE at the end, not after each edit)
testing-anti-patterns and
process-anti-patterns.md —
test-side rationalizations these tools cannot catch (e.g. "CI is red,
patch first, test later").
Execution environment
PHP tools
All PHP commands run inside the Docker container (make console or docker compose exec).
JS/TS tools
JS/TS commands run on the host or in a Node container, depending on the project setup:
- Check if a
Makefile / Taskfile.yml has targets for linting/testing.
- Check if
docker-compose.yml has a Node service.
- If neither → run on the host directly.
Output format
- Tool exit code and error count summary
- Fixed issues or remaining errors to address
Auto-trigger keywords
- quality check
- quality fix
- PHPStan
- Rector
- ECS
- code style
- lint
- Biome
- type check
- tscheck
Gotcha
- Always check exit code first — if 0, don't read output (saves tokens).
- Rector + ECS can introduce PHPStan errors — always re-run PHPStan after fixing.
- A project-specific
quality:* wrapper may expose different flags than the native tools — check the project's wrapper before assuming flags.
- Docker commands need
-T flag to avoid TTY issues in non-interactive mode.
Do NOT
- Do NOT run
vendor/bin/phpstan or vendor/bin/ecs directly — use the wrapper.
- Do NOT manually edit
phpstan-baseline.neon — it's auto-managed.
- Do NOT skip type checking (
tsc --noEmit) for TypeScript projects.
- Do NOT run Biome without
--write if the intent is to fix (otherwise it's dry-run only).
- Do NOT mix ESLint + Biome in the same project — check which one is active.
1---2name: quality-tools3description: Use when PHPStan, Rector, or ECS output appears — "phpstan says mixed", type errors, "fix code style", "run rector" — even when Eloquent/Laravel/model code is also mentioned.4---56# quality-tools78## When to use910Use this skill whenever running or configuring code quality tools:1112- **PHP**: PHPStan (static analysis), Rector (automated refactoring), ECS (coding standards)13- **JS/TS**: Biome (linting + formatting), TypeScript compiler (type checking), Jest/Vitest (tests)1415## Modes1617This skill is a router head. The cross-mode material — execution policy,18language detection, environment, output, gotchas — lives below. The per-tool19procedure bodies live in `references/`; load exactly the mode the detected20stack calls for.2122| Detected stack | Mode body | Covers |23|---|---|---|24| PHP (`.php` changed) | [`references/php-tools.md`](references/php-tools.md) | Tool detection, PHPStan / ECS / Rector commands and flags, combined pipeline, config files, baseline policy, PHPStan error handling, testing framework, git-aware execution |25| JS/TS (`.js` / `.ts` / `.tsx` changed) | [`references/js-ts-tools.md`](references/js-ts-tools.md) | Detection, Biome, TypeScript type checking, Jest / Vitest, the JS/TS workflow sequence |2627Both stacks changed → load both mode bodies and run both pipelines.2829## Execution policy — on demand only, never proactive3031```32NEVER RUN QUALITY TOOLS PROACTIVELY WHEN quality.local_auto_run IS33false OR MISSING (THE DEFAULT). DO NOT ASK WHETHER TO RUN THEM.34THE USER RUNS THEM MANUALLY. REMOTE CI IS THE AUTHORITATIVE GATE.35```3637Toolchains differ per language and project and are often unknown to the38agent — discovering and running them burns time and tokens. Under the39default, exactly three triggers justify running a quality tool:40411. **Explicit ask this turn** — the user says so or invokes `/fix quality`.422. **Concrete CI failure** — the remote pipeline reports a failing43 check; run exactly that failing check to reproduce and fix it44 (`/fix:ci` is the canonical flow).453. **New-gate carve-out** — the change itself introduces a NEW CI gate,46 smoke test, or test file; it must run once locally to be proven.4748`quality.local_auto_run: true` restores the legacy autonomous behaviour49(run the pipeline when work is ready for verification). When runs are50suppressed, the completion message says *"quality gates delegated to51remote CI"* — never that the tools passed.5253## Language detection5455Detect which tools to run based on **what files were changed**:5657```bash58# Check changed file extensions (diff against base branch)59git diff --name-only origin/main..HEAD | grep -E '\.(php)$' # → PHP tools60git diff --name-only origin/main..HEAD | grep -E '\.(js|ts|tsx)$' # → JS/TS tools61```6263If both PHP and JS/TS files changed → run **both** pipelines.6465## Procedure66671. Confirm a run is justified — see Execution policy above. No trigger, no run.682. Detect the stack from the changed files — see Language detection above.692b. **Inspect the project's own quality config before running anything.** Read70 the config files the detected stack actually ships (`phpstan.neon`,71 `ecs.php`, `rector.php`, `biome.json`, `tsconfig.json`, the `scripts` block72 of `package.json`) and the task/make wrapper if one exists. Never assume a73 default ruleset, a default baseline, or a default command — the mode body74 names where to look per stack. Running a tool against assumed config75 produces findings the project never asked for.763. Load the matching mode body from the table in Modes and follow its77 procedure. PHP → [`references/php-tools.md`](references/php-tools.md)78 § Procedure: Run quality checks. JS/TS →79 [`references/js-ts-tools.md`](references/js-ts-tools.md)80 § JS/TS Quality Workflow.814. Both stacks changed → run both mode procedures; neither result excuses the82 other.835. Report per Output format below.8485## Related rules and guidelines8687- `verify-before-complete` rule — no pass claims without fresh output; suppressed runs are surfaced as "delegated to remote CI", never claimed88- `php-coding` rule → PHPStan section — inline ignores, PHPDoc rules89- `contexts/execution/verification-mechanics.md` — Gate zero (`local_auto_run`) + timing when `true` (quality tools ONCE at the end, not after each edit)90- [`testing-anti-patterns`](../testing-anti-patterns/SKILL.md) and91 [`process-anti-patterns.md`](../testing-anti-patterns/process-anti-patterns.md) —92 test-side rationalizations these tools cannot catch (e.g. "CI is red,93 patch first, test later").9495---9697## Execution environment9899### PHP tools100101All PHP commands run **inside the Docker container** (`make console` or `docker compose exec`).102103### JS/TS tools104105JS/TS commands run on the **host** or in a **Node container**, depending on the project setup:1061071. Check if a `Makefile` / `Taskfile.yml` has targets for linting/testing.1082. Check if `docker-compose.yml` has a Node service.1093. If neither → run on the host directly.110111## Output format1121131. Tool exit code and error count summary1142. Fixed issues or remaining errors to address115116## Auto-trigger keywords117118- quality check119- quality fix120- PHPStan121- Rector122- ECS123- code style124- lint125- Biome126- type check127- tscheck128129## Gotcha130131- Always check exit code first — if 0, don't read output (saves tokens).132- Rector + ECS can introduce PHPStan errors — always re-run PHPStan after fixing.133- A project-specific `quality:*` wrapper may expose different flags than the native tools — check the project's wrapper before assuming flags.134- Docker commands need `-T` flag to avoid TTY issues in non-interactive mode.135136## Do NOT137138- Do NOT run `vendor/bin/phpstan` or `vendor/bin/ecs` directly — use the wrapper.139- Do NOT manually edit `phpstan-baseline.neon` — it's auto-managed.140- Do NOT skip type checking (`tsc --noEmit`) for TypeScript projects.141- Do NOT run Biome without `--write` if the intent is to fix (otherwise it's dry-run only).142- Do NOT mix ESLint + Biome in the same project — check which one is active.