Skip to content

feat: initial php-coding plugin (v0.1.0) - #1

Merged
sebastian-iancu merged 15 commits into
mainfrom
feat/initial-plugin
Sep 30, 2026
Merged

sebastian-iancu merged 15 commits into
mainfrom
feat/initial-plugin

Conversation

@sebastian-iancu

Copy link
Copy Markdown
Contributor

Summary

First version of the PHP Coding Plugin (v0.1.0) for Claude Code and Cursor. It teaches AI assistants the PHP rules a clean php-cs-fixer and PHPStan run can still miss, and names the command to run for everything the tools already enforce.

  • One knowledge skill, php-coding. A short index routes each change to a command and one of eleven reference files: style (PER Coding Style 3.1), idioms (types, comparisons, exceptions, enums, 8.4 forms, 8.5 hints), testing (PHPUnit 12), security, public-API compatibility, the PSR interfaces, Guzzle, Monolog, OpenTelemetry, Slim 4, and standalone Symfony components. Every rule links a primary source: php.net, php-fig.org, the library's docs, or its source at a release tag.
  • /php-lint-setup writes the reference php-cs-fixer (@PER-CS plus declare_strict_types) and PHPStan (level 8, phpVersion: 80400) config without overwriting existing files.
  • php-reviewer agent, report-only, loads php-coding and cites a reference for each finding.
  • Hooks for both hosts: session-start names the references that match composer.json; format-on-save runs php-cs-fixer on the edited file when a config and binary exist.
  • Cursor rule mirroring the index, reference lint config, a stdlib-only validator with CI, and twelve eval cases for claude plugin eval.

Pins and versions were read on 2026-09-30 and are listed in AGENTS.md: PHP 8.4 (8.5.11 current), PER 3.1 (the fixer still ships only a 3.0 set), Guzzle 8, Monolog 3, Symfony 8.1, Slim 4.15. Laravel framework code is left to Laravel Boost.

Test plan

  • ./scripts/validate.sh passes. It also checks index links, orphan references, the Cursor rule mirror, and the description length limit.
  • claude plugin validate . passes with no warnings.
  • Router table names only references that exist (enforced by the validator).
  • No reference restates a rule @PER-CS, PHPStan level 8, or composer audit already enforces.
  • Every new rule cites a primary source.
  • Every reference has an eval case. Last full run, one pass per case, no baseline arm: 11 of 12 cases scored 1.0. In the PER 3.1 case the skill fired and the answer passed, but that run did not open style.md.
  • Not run: the no-plugin baseline (claude plugin eval . --trust-plugin), which measures what the plugin adds.
  • Not verified: whether the Cursor hooks fire in a workspace other than this repo. Cursor does not document how plugin hook paths resolve.

Follow-ups

  • The reviewer agent lacks the "Typical triggers include…" sentence and "When to invoke" section the plugin-dev agent guide recommends.
  • format-on-save runs the repository's own .php-cs-fixer.php and fixer binary on every PHP edit. It should be documented, with an opt-out.
  • The php-coding description is at 1,011 of 1,024 characters.

🤖 Generated with Claude Code

sebastian-iancu and others added 15 commits October 1, 2026 01:13
Claude Code and Cursor manifests with identical name, version, description,
and author. The Cursor manifest declares the skills, agents, rules, and hooks
paths. Adds .gitignore (eval results, local notes, tool caches) and
.gitattributes (export-ignore for maintainer files).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@PER-CS plus declare_strict_types, PHPStan level 8 with phpVersion 80400,
and an optional Rector config pinned to PHP 8.4 with no prepared sets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
One knowledge skill: SKILL.md routes each change to the command to run and a
reference to read. References cover style (PER 3.1), idioms (types,
exceptions, 8.4 forms, 8.5 hints), testing (PHPUnit 12), security,
compatibility, the PSR interfaces, Guzzle, Monolog, OpenTelemetry, Slim, and
standalone Symfony components. Each rule cites a primary source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Writes the reference php-cs-fixer and PHPStan config into a repository
without overwriting existing files. Rector only when asked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report-only reviewer for what php-cs-fixer and PHPStan level 8 miss. Loads
php-coding through the Skill tool and cites the reference for each finding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirrors the php-coding index table for **/*.php files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
session-start prints one standards line in a PHP workspace and names the
library references that match composer.json. format-on-save runs
php-cs-fixer on the edited file when a config and a binary exist, reading the
path from the host's stdin payload. Both always exit 0. Claude commands quote
${CLAUDE_PLUGIN_ROOT}; the timeout is 20 seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Eleven claude plugin eval cases. Each grades the answer, checks that
php-coding fired, and checks that the matching reference file was read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stdlib-only validator for manifests and parity, kebab-case names,
frontmatter (including the unquoted colon trap), description length,
reference links and orphans, and the Cursor rule mirror. The workflow runs it
on pushes to main and on pull requests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGENTS.md is the canonical instruction set, imported by .claude/CLAUDE.md.
Adds install, testing, versioning, and authoring guides, the README
component overview, and the 0.1.0 changelog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rewrites second-person phrasing as instructions, per the plugin-dev
skill-development writing style. Verbatim quotes from sources are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
idioms: in_array() and array_search() need strict=true, switch compares
loosely, json_decode() needs JSON_THROW_ON_ERROR, tryFrom() over from() for
input, and #[\Override] and typed class constants from PHP 8.3.
testing: createStub() for doubles that only return values.
compatibility: parameter names are call surface since named arguments.
Each rule cites php.net, the PHPUnit 12.5 manual, or Symfony's BC promise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Third-person descriptions with quoted example requests, front-loaded, and
naming pasted snippets and PHPStan or php-cs-fixer questions. The index
routes the new idioms and testing triggers. php-lint-setup also suggests the
PHPUnit coverage-strictness switches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviews a webhook check with a loose in_array() and an unchecked
json_decode(); grades the findings, the skill trigger, and a read of
idioms.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The grader is a trace regex that accepts Read or Grep of the reference,
not a tool_used check on Read. CHANGELOG lists twelve eval cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sebastian-iancu
sebastian-iancu merged commit c963633 into main Sep 30, 2026
1 check passed
@sebastian-iancu
sebastian-iancu deleted the feat/initial-plugin branch September 30, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant