一键导入
class-refactoring
Use when refactor PHP classes to improve structure, readability, and maintainability while preserving behavior
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when refactor PHP classes to improve structure, readability, and maintainability while preserving behavior
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when you need an evidence-first, read-only inventory of every automation in this repo (GitHub Actions, Claude Code hooks/settings, MCP servers, composer scripts, the bundled CLI installer, the skills catalog, scheduler/cron) before changing any of them, classifying each as live, broken, or redundant and recommending keep/merge/cut/fix.
Use when choosing how to run Claude Code autonomously on this project — from a single sequential pipeline to multi-agent DAG orchestration. A reference catalog of loop patterns anchored to this repo's real tooling (resolve-issue, autoresolve-oldest-github-issue, code-review-github, process-code-review, merge-github-pr, /loop), with composer build / composer skill-check as the quality gate between iterations.
Use when a goal is vague speed ("make it faster", "reduce p95", "cut query time") and you need a bounded, measured loop that promotes only verified, correctness-preserving wins instead of guessed micro-tweaks.
Use when measuring performance baselines or detecting regressions before and after a change in a Laravel app — page Core Web Vitals, API latency percentiles, build/test velocity, and DB query timing, stored as git-tracked baselines for team comparison.
Use when a single objective is too large for one pull request and must span multiple sessions or PRs. Turns the objective into a sequenced construction plan of 3-12 one-PR steps, each with a cold-start context brief, dependency edges, and exit criteria, then reviews it adversarially and registers it as Markdown.
Use when run code review for a Bugsnag error and publish results to the linked GitHub PR and the Bugsnag error
| name | class-refactoring |
| description | Use when refactor PHP classes to improve structure, readability, and maintainability while preserving behavior |
| license | MIT |
| metadata | {"author":"Petr Král (pekral.cz)"} |
Improve code structure and quality without changing behavior.
Focus on:
This skill runs in one of two modes, selected by the caller via MODE (default apply):
apply (default) — full refactoring: modify code, author the pre-refactor coverage commit, run fixers / checkers, and chain the After Completion review. Every step below behaves as written unless it is explicitly flagged for MODE=cr.cr (read-only lens — invoked by @skills/code-review/SKILL.md, code-review-github, code-review-jira) — never modify code, never author tests, never stage / commit / push, never run fixers or checkers, and never chain any After Completion review. Scope the analysis to the lines added or modified by the PR diff and return the refactoring opportunities as markdown only, for the CR to fold into its Refactoring (DRY / tech debt) and Refactoring proposals sections. Every "apply / extract / split / consolidate" instruction below is emitted as a written proposal, not applied to code; the Test Coverage Gate becomes a read-only audit (report coverage gaps as findings, do not author tests).@rules/laravel/laravel.mdc, @rules/laravel/architecture.mdc, @rules/laravel/filament.mdc, and @rules/laravel/livewire.mdc
MODE=cr: perform Read and Map read-only to ground the proposals in the real code; Verify is the audit you already run. Do not modify code.
Reading, mapping, and verifying come first; refactoring comes last. This pre-flight is blocking — do not edit a single line of production code until all three steps pass, and never act on an assumption you have not confirmed by reading the code.
Only after Read, Map, and Verify are complete may the Test Coverage Gate and the refactor proceed.
MODE=cr: do not write tests or commits. Run the coverage check read-only and report any target lines below 100% coverage as a refactoring finding (a refactor cannot land safely without them) — then continue the analysis. The steps below that author tests / commits apply toMODE=applyonly.
The gate is blocking. Refactoring may not edit a single line of production code until tests for the target lines reach 100% coverage. Satisfy the Test Coverage Contract defined in @rules/refactoring/general.mdc:
@rules/php/core-standards.mdc Testing section). Every line, branch, and condition must already be at 100%.@skills/create-test/SKILL.md to author them; commit them in a dedicated test(scope): cover <area> before refactor commit per @rules/git/general.mdc Allowed Types. The pre-refactor coverage commit and the refactor commit are always two separate commits — never squash them and never mix new tests into the refactor commit.feat(scope): … / fix(scope): … commit, not the refactor commit).@rules/refactoring/general.mdc (stabilize → identify entry points → introduce Action pattern → split responsibilities → modernize → DRY → concurrency). Never propose a big-bang rewrite.@rules/refactoring/general.mdc, @rules/php/core-standards.mdc, @rules/code-testing/general.mdc, and (for Laravel projects) @rules/laravel/laravel.mdc + @rules/laravel/architecture.mdc + @rules/laravel/filament.mdc + @rules/laravel/livewire.mdc. The refactor rewrites the existing code into the target architecture (Action / Service / Repository / ModelManager / Data Validator / Data Builder / DTO per project rules) and the target code-style (naming, structure, parameter count, nesting, design principles). Anything that would deviate from the rules is rewritten until it complies; do not invent ad-hoc structure outside the rule set.test(scope): … commit after the refactor.@rules/refactoring/general.mdc.interface types that have neither at least two non-test consumers nor at least two non-test implementations back into their concrete class. Test doubles, mocks, and fakes do not count toward either threshold. Implementing a framework or vendor interface (e.g. ShouldQueue, HasLabel, Arrayable) is always allowed. Keep a single-implementation, single-consumer project interface only when there is a documented architectural reason — a published package API surface or a plugin extension point with a written contract. See @rules/php/core-standards.mdc Design Principles.@rules/laravel/architecture.mdc "Business Logic Layers"). When a class file contains business logic that spans more than one of these layers, contains business logic that does not fit any of them, or holds an Eloquent model method that crosses the simple-logic boundary (calls services / repositories / model managers, issues new queries, performs persistence side effects, or coordinates multiple entities), propose a refactoring that splits the responsibilities into dedicated classes from the seven-layer list. Surface every detected violation in the refactoring plan with the target layer for each extracted responsibility.@rules/sql/optimalize.mdc "Batch over per-row operations" — ModelManager batchUpdate / batchInsert, whereIn(...)->delete(), or a single bulk read keyed in memory. Keep per-row work only when an explicit side-effect dependency between iterations cannot be batched.@rules/sql/optimalize.mdc "Performance Non-Regression on Query Changes". Capture the original query's baseline (EXPLAIN / EXPLAIN ANALYZE) before the refactor and compare after. If the refactored query is measurably slower, it is not a clean refactor — stop, document why it is slower and the remaining optimization options (or that none exist and why), and surface the trade-off in the refactoring plan / PR description instead of shipping the regression silently. In MODE=cr, raise a slower query introduced by the diff as a finding with the same reason + options requirement.@rules/laravel/architecture.mdc Data Modification (DRY) section (Data Builder, DTO named constructor, Data Validator, ModelManager, Repository).@rules/php/core-standards.mdc Design Principles or, on Laravel projects, @rules/laravel/architecture.mdc. When two refactoring options preserve behavior equally well, pick the shorter, less layered one ("if you write 200 lines and it could be 50, rewrite it"). Reuse existing helpers / Services / Actions / Repositories before extracting a new class. In MODE=cr, surface every such speculative addition the PR diff introduces as a refactoring proposal rather than a code change.__invoke(), or other callable crosses the threshold, propose extracting a dedicated typed DTO and passing it as a single argument, per @rules/php/core-standards.mdc Structure section (parameter counting rules, exemption list, and required fix are defined there).@rules/laravel/architecture.mdc Pass-through Action rule, an Action whose entire __invoke() body is a single delegating call to one Service / Facade / Model Service method — with no orchestration of its own (no validation delegation, no DTO / data transformation, no coordination of multiple collaborators, no extra business step, no return-value reshaping) — is a redundant indirection layer and must be collapsed during the refactor. Detect every such pass-through Action touched by the refactor and resolve it one of two ways: (1) if the wrapped Service / Facade method is used only once in the codebase, move its logic into the Action and delete the method (the Single-use Service/Facade method rule), so the Action does real work; (2) if the method is reused elsewhere, remove the Action entirely and rewrite the entry point to call the Service / Facade method directly ($action($payload) → $service->method($payload)), updating every call site. In MODE=cr, emit each pass-through Action as a written refactoring proposal (target resolution + every call site that must change) rather than applying the change.@rules/laravel/architecture.mdc Repositories and ModelManagers section).app/Livewire/**/*.php, resources/views/livewire/**/*.blade.php, resources/views/**/*.blade.php), analyze its HTML as a tree of UI concerns per @rules/laravel/livewire.mdc HTML / Blade Layout Splitting. Walk every trigger in that section (repeated markup, >150 Blade lines, self-contained wire:* cluster, self-contained data shape, cross-page reuse, independent loading / empty / error state, distinct named UI concern) and propose an extraction for each match. Pick Livewire children only for blocks with their own state / lifecycle / server interaction; pick Blade components for stateless presentation — wrapping presentational markup in a Livewire component just to enable reuse is itself a refactoring finding. Every extracted component must satisfy the Reusability contract in that rule (typed input, one concern, no business logic, events not parent reach-through, independently renderable, correct tree placement, concern-based name). The layout split is a structural refactor — the Test Coverage Gate above applies in spirit: every rendered branch of the touched view (initial render, wire:loading, @empty, error banner, each @if / @foreach arm) must be exercised by a Livewire / Blade feature test committed before the layout refactor, and the same feature tests must stay green through the refactor commit unchanged. PHP --coverage-clover does not measure .blade.php line-by-line, so the binding gate is feature-test parity, not a numeric coverage percentage on the view file.MODE=cr: this section is apply-mode only — the read-only lens audits coverage per the Test Coverage Gate note and reports gaps as findings; it never authors tests or commits.test(scope): cover <area> before refactor commit per @rules/refactoring/general.mdc Test Coverage Contract.test(scope): … commit after the refactor.MODE=apply:
MODE=cr: refactoring opportunities as markdown only (no code) — for each, the file:line on the PR diff, the structural problem in one sentence, the concrete consolidation step (target layer per @rules/laravel/architecture.mdc), and the rule reference it satisfies. The CR places in-scope items in its Refactoring (DRY / tech debt) section and out-of-scope structural problems in Refactoring proposals.Skip this entire section in
MODE=cr— a read-only lens pushes nothing.
build.xml/phing.xml; fall back to Composer scripts in composer.json)Skip this entire section in
MODE=cr— the CR is the caller, so chaining back into it would recurse. Return the findings to the caller and stop.
@skills/code-review/SKILL.md directly in this skill's context, passing the refactor commit range plus the instruction to return Critical / Moderate / Minor findings with their reproducer fields. Do not dispatch the review as a subagent — run it sequentially in the current context.@skills/process-code-review/SKILL.md (also invoked inline per its own contract).