quality-tools

star 7

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.

event4u-app By event4u-app schedule Updated 6/3/2026

model_tier: medium name: quality-tools description: "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." domain: quality execution: type: assisted handler: shell allowed_tools: [] recommended_for_user_types: [developer] workspaces: - engineering packs: - engineering-base

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)

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.

Related rules and guidelines

  • verify-before-complete rule — timing: run quality tools ONCE at the end, not after each edit
  • php-coding rule → PHPStan section — inline ignores, PHPDoc rules
  • verify-before-complete rule — must run quality checks before claiming work is done
  • testing-anti-patterns and process-anti-patterns.md — test-side rationalizations these tools cannot catch (e.g. "CI is red, patch first, test later").

PHP Quality Tools

Tool Detection

Check composer.json to determine which tools are available and how to run them. Use the first matching command style:

composer.json contains Command style Example
A project-specific quality wrapper (exposes quality:* commands) php artisan quality:* or composer quality:* php artisan quality:phpstan
phpstan/phpstan or larastan/larastan vendor/bin/phpstan vendor/bin/phpstan analyse
rector/rector vendor/bin/rector vendor/bin/rector process
symplify/easy-coding-standard vendor/bin/ecs vendor/bin/ecs check --fix

Priority: If a project ships a quality:* wrapper (Artisan or Composer script), always prefer it — wrappers typically add git-aware execution, caching, automatic baseline regeneration, and memory management on top of the native tools.

If none of the above is installed → skip quality checks, inform the user.

All commands run inside the Docker container if Docker is used (docker compose exec or make console).

Commands

PHPStan — Static Analysis

# Native:
vendor/bin/phpstan analyse                          # Analyse all configured paths
vendor/bin/phpstan analyse --memory-limit=512M      # With memory limit
vendor/bin/phpstan analyse --error-format=github    # CI-friendly format

# With a project-specific quality wrapper:
php artisan quality:phpstan          # Laravel
composer quality:phpstan             # Composer

Native flags:

Flag Description
--memory-limit=SIZE Set memory limit (e.g. 512M, 1G)
--debug Activate debug mode
--error-format=FORMAT Output format: table (default), github, gitlab
--pro Toggle PHPStan Pro

Wrapper-only flags (typical of a quality:* wrapper — verify in the project):

Flag Description
--baseline Generate/update phpstan baseline file
--ignore-git Skip Git check, analyse all files
--xdebug Activate Xdebug mode

ECS — Easy Coding Standard

# Native:
vendor/bin/ecs check                  # Dry-run
vendor/bin/ecs check --fix            # Auto-fix

# With a project-specific quality wrapper:
php artisan quality:ecs --fix         # Laravel
composer quality:ecs -- --fix         # Composer

Native flags:

Flag Description
--fix Fix errors automatically
--clear-cache Clear the ECS cache

Wrapper-only flags (typical of a quality:* wrapper — verify in the project):

Flag Description
--ignore-git Skip Git check, check all files
--paths-to-scan[=PATHS] Custom paths, e.g. --paths-to-scan='["./core"]'
--source-branch[=BRANCH] Source branch (default: HEAD)
--target-branch[=BRANCH] Target branch to compare against

Rector — Automated Refactoring

# Native:
vendor/bin/rector process              # Auto-fix
vendor/bin/rector process --dry-run    # Preview changes

# With a project-specific quality wrapper:
php artisan quality:rector --fix       # Laravel
composer quality:rector -- --fix       # Composer

Native flags:

Flag Description
--dry-run Preview changes without applying
--clear-cache Clear the Rector cache

Wrapper-only flags (typical of a quality:* wrapper — verify in the project):

Flag Description
--ignore-git Skip Git check, check all files
--paths-to-scan[=PATHS] Custom paths
--source-branch[=BRANCH] Source branch (default: HEAD)
--target-branch[=BRANCH] Target branch to compare against

Combined Commands

There is no native single command for running all three tools. Run them in sequence:

# Full pipeline (native):
vendor/bin/rector process && vendor/bin/ecs check --fix && vendor/bin/phpstan analyse

# With a project-specific quality wrapper (if it ships these combined commands):
php artisan quality:refactor --fix     # Rector + ECS
php artisan quality:finalize           # Rector + ECS + PHPStan (full pipeline)

Procedure: Run quality checks

  1. Run PHPStan — fix all errors
  2. Run Rector + ECS with auto-fix — fix style + refactoring
  3. Run PHPStan again — verify step 2 didn't introduce new issues

If step 3 finds errors → fix and repeat from step 2.

Detect commands from project (see Tool Detection above).

Configuration

Config files are typically in the project root. Do NOT modify without explicit user permission.

Detect config location:

  • Check project root first: phpstan.neon, ecs.php, rector.php
  • Some projects use phpstan.neon.dist instead of phpstan.neon

Standard config files

File Tool Purpose
phpstan.neon PHPStan Level, paths, extensions, ignoreErrors, disallowed calls
phpstan-baseline.neon PHPStan Baseline for existing errors (auto-managed, do NOT edit)
ecs.php ECS Code style: rule sets, configured rules, skip list
rector.php Rector Refactoring: rule sets, PHP version sets, skip list

Understanding the project's config

Read the actual config files to understand what rules are active:

  • phpstan.neon: Check level, paths, ignoreErrors, includes (baselines, extensions)
  • ecs.php: Check which rule sets are active (PSR-12, PHP-CS-Fixer sets), skip list
  • rector.php: Check PHP version sets, active rule sets, skip list

Common patterns across projects:

  • PHPStan at high levels (8-9) with disallowedFunctionCalls banning var_dump(), dd()
  • ECS with PSR-12 base, trailing commas, Yoda style
  • Rector with PHP version migration sets and naming conventions

Baseline policy

  • NEVER edit phpstan-baseline.neon by hand.
  • NEVER add errors, update counts, or regenerate manually.
  • If the project ships a quality wrapper (exposing quality:* commands), it may regenerate the baseline automatically.

PHPStan error handling

Priority order for dealing with PHPStan errors:

  1. Fix the code — always the first choice. Fix the actual type issue.
  2. Add type hints / PHPDoc — if the code is correct but PHPStan can't infer the type.
  3. Inline ignore (last resort) — only for confirmed false positives:
    // @phpstan-ignore-next-line — false positive: reason here
    

When phpstan.neon changes ARE allowed

Adding ignoreErrors entries to phpstan.neon is allowed when:

  • The error is a structural limitation of the toolchain (e.g., Pest tests bind $this at runtime, PHPStan can't resolve artisan(), get(), etc. on PHPUnit\Framework\TestCase)
  • The pattern applies broadly to a category of files (e.g., all test files), not just one specific line
  • The fix would require abandoning the project's conventions (e.g., rewriting Pest tests as PHPUnit classes)

If unsure whether a phpstan.neon change is appropriate → ask the user before making the change.

NEVER do these

  • Add entries to baseline files (phpstan-baseline.neon)
  • Add ignoreErrors for individual files or specific code issues that should be fixed
  • Use @phpstan-ignore-next-line without a reason comment

See also: php-coding rule → PHPStan section.

Testing framework

  • Always write tests in Pest, not PHPUnit class syntax — unless the user explicitly asks for PHPUnit.
  • Pest tests in tests/Unit/ automatically use UnitTestCase as the base class (configured in tests/Pest.php).
  • PHPStan cannot fully resolve Pest's runtime bindings — this is handled via ignoreErrors patterns in phpstan.neon.

Git-aware execution

By default, all tools only check files changed since the last commit.

Flag Effect
(default) Only changed files (fast, for iterative work)
--ignore-git All files (cache still applies)
--clear-cache Changed files, but ignore cache
--ignore-git --clear-cache Complete fresh run of all files

JS/TS Quality Tools

Detection

Check package.json for available tools:

Indicator Tool
@biomejs/biome in devDependencies Biome — linting + formatting
typescript in devDependencies TypeScript — type checking
jest or vitest in devDependencies Test runner
eslint in devDependencies ESLint — legacy linting (check if Biome replaces it)
prettier in devDependencies Prettier — legacy formatting (check if Biome replaces it)

Biome — Linting + Formatting

Biome replaces ESLint + Prettier in one tool.

Config

  • Config file: biome.json or biome.jsonc
  • Includes formatter settings (indent style, line width, trailing commas)
  • Includes linter rules (recommended + custom overrides)
  • Includes import sorting (via assist.actions.source.organizeImports)

Commands

# Check (dry-run) — shows errors without fixing
npx biome check .

# Fix — auto-fix all fixable issues (formatting + linting + imports)
npx biome check --write .

# Format only
npx biome format --write .

# Lint only
npx biome lint .

Via npm scripts (preferred)

Check package.json scripts — projects typically define:

npm run biome          # Check (dry-run)
npm run biome:fix      # Auto-fix

Always prefer npm scripts over raw npx commands when they exist.

TypeScript — Type Checking

Commands

# Type check without emitting files
npx tsc --noEmit

# Via npm script (preferred)
npm run tscheck

Config

  • Config file: tsconfig.json (may have tsconfig.app.json, tsconfig.node.json for different targets)
  • strict: true should be enabled in all projects
  • Check compilerOptions.paths for import aliases

Jest / Vitest — Testing

Commands

# Run all tests
npm test

# Run specific test file
npx jest path/to/test.spec.ts

# Run with coverage
npx jest --coverage

# Watch mode
npx jest --watch

JS/TS Quality Workflow

After JS/TS code changes, run this sequence:

1. npx biome check --write .     → Auto-fix formatting + linting
2. npx tsc --noEmit              → Verify type safety
3. npm test                      → Run test suite

Or via npm scripts:

1. npm run biome:fix             → Auto-fix
2. npm run tscheck               → Type check
3. npm test                      → Tests

If step 2 finds type errors → fix them in code, then re-run step 1 (Biome may reformat).

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:

  1. Check if a Makefile / Taskfile.yml has targets for linting/testing.
  2. Check if docker-compose.yml has a Node service.
  3. If neither → run on the host directly.

Output format

  1. Tool exit code and error count summary
  2. 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.
Install via CLI
npx skills add https://github.com/event4u-app/agent-config --skill quality-tools
Repository Details
star Stars 7
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator