$npx -y skills add mralaminahamed/wp-dev-skills --skill wp-phpstan-stubsUse when creating a new PHPStan stubs package for a WordPress plugin, theme, or Composer package — scaffolding the full repo structure (composer.json, configs/bootstrap.php, configs/finder.php, bin/generate.sh, bin/release-latest-versions.sh, .github/workflows/release.yml, phpsta
| 1 | # PHPStan Stubs Scaffold |
| 2 | |
| 3 | > **Model note:** File scaffolding from a fixed template — `haiku` handles end-to-end. Only reach for `sonnet` if the source plugin has complex namespace hierarchies needing stub organization decisions. |
| 4 | |
| 5 | Scaffold a complete PHPStan stubs package from scratch, following the `my-org/phpstan-freemius-stubs` standard structure. |
| 6 | |
| 7 | ## When to use |
| 8 | |
| 9 | - "Create stubs for X", "new stubs package", "scaffold phpstan stubs", "add stubs for plugin/composer package". |
| 10 | |
| 11 | **Not for:** Configuring `phpstan.neon` or generating baselines — use the official `wp-phpstan` skill. Adding PHPStan to a plugin that already has stubs installed. |
| 12 | |
| 13 | ## References |
| 14 | |
| 15 | - `references/wp-org-api.md` — WP.org plugin API, version listing, download URLs, cleanup patterns |
| 16 | - `references/packagist-api.md` — Packagist API, version filtering, source/composer.json update pattern |
| 17 | - `references/common-errors.md` — Known errors and fixes (jq `\d`, unzip prompt, find+set-e, git reset, missing source/composer.json) |
| 18 | - `references/github-setup.md` — Repo creation, branch rename trunk→main, topics, secrets, all 11 current repos |
| 19 | |
| 20 | ## Gather Required Info |
| 21 | |
| 22 | Before writing any files, collect (ask user if missing): |
| 23 | |
| 24 | 1. **Plugin/package name** — human-readable (e.g. "SureCart", "Action Scheduler") |
| 25 | 2. **Source type** — one of: |
| 26 | - `wp-plugin` — downloadable from WordPress.org (slug known) |
| 27 | - `composer` — Composer package on Packagist (e.g. `woocommerce/action-scheduler`) |
| 28 | - `paid` — paid plugin, user places source manually |
| 29 | 3. **WP.org slug** (if `wp-plugin`) — e.g. `surecart`, `forminator` |
| 30 | 4. **Packagist package** (if `composer`) — e.g. `woocommerce/action-scheduler` |
| 31 | 5. **Source dir path inside package** — where the plugin/package files land: |
| 32 | - `wp-plugin`: `source/<slug>/` |
| 33 | - `composer`: `source/vendor/<vendor>/<package>/` |
| 34 | - `paid`: `source/<slug>/` |
| 35 | 6. **Packagist name** — `my-org/phpstan-<slug>-stubs` |
| 36 | 7. **GitHub repo name** — `phpstan-<slug>-stubs` |
| 37 | 8. **Versions to release** — for `wp-plugin`/`composer`: minor version series (e.g. `3.4 3.5 3.6`); for `paid`: manual |
| 38 | 9. **GitHub assignee** — default `my-org` |
| 39 | |
| 40 | ## Standard Directory Layout |
| 41 | |
| 42 | ``` |
| 43 | phpstan-<slug>-stubs/ |
| 44 | ├── bin/ |
| 45 | │ ├── generate.sh |
| 46 | │ └── release-latest-versions.sh # (not for paid) |
| 47 | ├── configs/ |
| 48 | │ ├── bootstrap.php |
| 49 | │ └── finder.php |
| 50 | ├── source/ |
| 51 | │ ├── composer.json # only if wp-plugin or paid (no composer deps) |
| 52 | │ └── .gitignore |
| 53 | ├── .github/ |
| 54 | │ └── workflows/ |
| 55 | │ └── release.yml # (not for paid) |
| 56 | ├── .editorconfig |
| 57 | ├── .gitattributes |
| 58 | ├── .gitignore |
| 59 | ├── composer.json |
| 60 | ├── phpstan.neon |
| 61 | └── <slug>-stubs.php # empty placeholder (generated) |
| 62 | <slug>-constants-stubs.php # empty placeholder (generated) |
| 63 | ``` |
| 64 | |
| 65 | ## File Contents |
| 66 | |
| 67 | ### `composer.json` |
| 68 | |
| 69 | ```json |
| 70 | { |
| 71 | "name": "my-org/phpstan-<slug>-stubs", |
| 72 | "description": "<PluginName> function and class declaration stubs for static analysis.", |
| 73 | "type": "library", |
| 74 | "keywords": [ |
| 75 | "<slug>", |
| 76 | "wordpress", |
| 77 | "static analysis", |
| 78 | "phpstan", |
| 79 | "stubs" |
| 80 | ], |
| 81 | "homepage": "https://github.com/my-org/phpstan-<slug>-stubs", |
| 82 | "license": "MIT", |
| 83 | "authors": [ |
| 84 | { |
| 85 | "name": "Al Amin Ahamed", |
| 86 | "homepage": "https://github.com/my-org" |
| 87 | } |
| 88 | ], |
| 89 | "require": { |
| 90 | "php": ">=7.4", |
| 91 | "php-stubs/wordpress-stubs": "^5.3 || ^6.0" |
| 92 | }, |
| 93 | "require-dev": { |
| 94 | "php-stubs/generator": "^0.8.0", |
| 95 | "phpstan/phpstan": "^2.0", |
| 96 | "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", |
| 97 | "squizlabs/php_codesniffer": "^3.7" |
| 98 | }, |
| 99 | "minimum-stability": "stable", |
| 100 | "prefer-stable": true, |
| 101 | "config": { |
| 102 | "allow-plugins": { |
| 103 | "php-stubs/generator": true |