@ai-kits/wp-ag-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/ANTIGRAVITY-README.md +47 -0
  2. package/CONTRIBUTING.md +122 -0
  3. package/README.md +135 -0
  4. package/STRUCTURE.md +200 -0
  5. package/agents/wordpress-expert.md +36 -0
  6. package/agents/wp-frontend-expert.md +21 -0
  7. package/bin/antigravity-agent.js +159 -0
  8. package/docs/authoring-guide.md +56 -0
  9. package/docs/compatibility-policy.md +18 -0
  10. package/docs/packaging.md +26 -0
  11. package/docs/principles.md +7 -0
  12. package/docs/skill-set-v1.md +21 -0
  13. package/docs/upstream-sync.md +52 -0
  14. package/package.json +47 -0
  15. package/rules/GEMINI.md +273 -0
  16. package/shared/references/.gitkeep +1 -0
  17. package/shared/references/gutenberg-releases.json +155 -0
  18. package/shared/references/wordpress-core-versions.json +208 -0
  19. package/shared/references/wp-gutenberg-version-map.json +886 -0
  20. package/shared/scripts/ai-generate-updates.mjs +458 -0
  21. package/shared/scripts/scaffold-skill.mjs +62 -0
  22. package/shared/scripts/skillpack-build.mjs +165 -0
  23. package/shared/scripts/skillpack-install.mjs +275 -0
  24. package/shared/scripts/update-upstream-indices.mjs +173 -0
  25. package/skills/wordpress-router/SKILL.md +51 -0
  26. package/skills/wordpress-router/references/decision-tree.md +55 -0
  27. package/skills/wp-abilities-api/SKILL.md +95 -0
  28. package/skills/wp-abilities-api/references/php-registration.md +67 -0
  29. package/skills/wp-abilities-api/references/rest-api.md +13 -0
  30. package/skills/wp-block-development/SKILL.md +174 -0
  31. package/skills/wp-block-development/references/attributes-and-serialization.md +22 -0
  32. package/skills/wp-block-development/references/block-json.md +49 -0
  33. package/skills/wp-block-development/references/creating-new-blocks.md +46 -0
  34. package/skills/wp-block-development/references/debugging.md +36 -0
  35. package/skills/wp-block-development/references/deprecations.md +24 -0
  36. package/skills/wp-block-development/references/dynamic-rendering.md +23 -0
  37. package/skills/wp-block-development/references/inner-blocks.md +25 -0
  38. package/skills/wp-block-development/references/registration.md +30 -0
  39. package/skills/wp-block-development/references/supports-and-wrappers.md +18 -0
  40. package/skills/wp-block-development/references/tooling-and-testing.md +21 -0
  41. package/skills/wp-block-development/scripts/list_blocks.mjs +121 -0
  42. package/skills/wp-block-themes/SKILL.md +116 -0
  43. package/skills/wp-block-themes/references/creating-new-block-theme.md +37 -0
  44. package/skills/wp-block-themes/references/debugging.md +24 -0
  45. package/skills/wp-block-themes/references/patterns.md +18 -0
  46. package/skills/wp-block-themes/references/style-variations.md +14 -0
  47. package/skills/wp-block-themes/references/templates-and-parts.md +16 -0
  48. package/skills/wp-block-themes/references/theme-json.md +59 -0
  49. package/skills/wp-block-themes/scripts/detect_block_themes.mjs +117 -0
  50. package/skills/wp-interactivity-api/SKILL.md +179 -0
  51. package/skills/wp-interactivity-api/references/debugging.md +29 -0
  52. package/skills/wp-interactivity-api/references/directives-quickref.md +30 -0
  53. package/skills/wp-interactivity-api/references/server-side-rendering.md +310 -0
  54. package/skills/wp-performance/SKILL.md +146 -0
  55. package/skills/wp-performance/references/autoload-options.md +24 -0
  56. package/skills/wp-performance/references/cron.md +20 -0
  57. package/skills/wp-performance/references/database.md +20 -0
  58. package/skills/wp-performance/references/http-api.md +15 -0
  59. package/skills/wp-performance/references/measurement.md +21 -0
  60. package/skills/wp-performance/references/object-cache.md +24 -0
  61. package/skills/wp-performance/references/query-monitor-headless.md +38 -0
  62. package/skills/wp-performance/references/server-timing.md +22 -0
  63. package/skills/wp-performance/references/wp-cli-doctor.md +24 -0
  64. package/skills/wp-performance/references/wp-cli-profile.md +32 -0
  65. package/skills/wp-performance/scripts/perf_inspect.mjs +128 -0
  66. package/skills/wp-phpstan/SKILL.md +97 -0
  67. package/skills/wp-phpstan/references/configuration.md +52 -0
  68. package/skills/wp-phpstan/references/third-party-classes.md +76 -0
  69. package/skills/wp-phpstan/references/wordpress-annotations.md +124 -0
  70. package/skills/wp-phpstan/scripts/phpstan_inspect.mjs +263 -0
  71. package/skills/wp-playground/SKILL.md +101 -0
  72. package/skills/wp-playground/references/blueprints.md +36 -0
  73. package/skills/wp-playground/references/cli-commands.md +39 -0
  74. package/skills/wp-playground/references/debugging.md +16 -0
  75. package/skills/wp-plugin-development/SKILL.md +112 -0
  76. package/skills/wp-plugin-development/references/data-and-cron.md +19 -0
  77. package/skills/wp-plugin-development/references/debugging.md +19 -0
  78. package/skills/wp-plugin-development/references/lifecycle.md +33 -0
  79. package/skills/wp-plugin-development/references/security.md +29 -0
  80. package/skills/wp-plugin-development/references/settings-api.md +22 -0
  81. package/skills/wp-plugin-development/references/structure.md +16 -0
  82. package/skills/wp-plugin-development/scripts/detect_plugins.mjs +122 -0
  83. package/skills/wp-project-triage/SKILL.md +38 -0
  84. package/skills/wp-project-triage/references/triage.schema.json +143 -0
  85. package/skills/wp-project-triage/scripts/detect_wp_project.mjs +592 -0
  86. package/skills/wp-rest-api/SKILL.md +114 -0
  87. package/skills/wp-rest-api/references/authentication.md +18 -0
  88. package/skills/wp-rest-api/references/custom-content-types.md +20 -0
  89. package/skills/wp-rest-api/references/discovery-and-params.md +20 -0
  90. package/skills/wp-rest-api/references/responses-and-fields.md +30 -0
  91. package/skills/wp-rest-api/references/routes-and-endpoints.md +36 -0
  92. package/skills/wp-rest-api/references/schema.md +22 -0
  93. package/skills/wp-wpcli-and-ops/SKILL.md +123 -0
  94. package/skills/wp-wpcli-and-ops/references/automation.md +30 -0
  95. package/skills/wp-wpcli-and-ops/references/cron-and-cache.md +23 -0
  96. package/skills/wp-wpcli-and-ops/references/debugging.md +17 -0
  97. package/skills/wp-wpcli-and-ops/references/multisite.md +22 -0
  98. package/skills/wp-wpcli-and-ops/references/packages-and-updates.md +22 -0
  99. package/skills/wp-wpcli-and-ops/references/safety.md +30 -0
  100. package/skills/wp-wpcli-and-ops/references/search-replace.md +40 -0
  101. package/skills/wp-wpcli-and-ops/scripts/wpcli_inspect.mjs +90 -0
  102. package/skills/wpds/SKILL.md +58 -0
  103. package/workflows/create-block.md +27 -0
  104. package/workflows/wp-lint.md +27 -0
@@ -0,0 +1,263 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ const TOOL_VERSION = "0.1.0";
5
+
6
+ /**
7
+ * Reads and parses JSON from a file path.
8
+ *
9
+ * Returns null when parsing fails so the caller can provide user-facing
10
+ * guidance without crashing.
11
+ *
12
+ * @param {string} filePath Absolute path to a JSON file.
13
+ * @returns {any|null} Parsed JSON object.
14
+ */
15
+ function readJsonSafe(filePath) {
16
+ try {
17
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Reads a UTF-8 text file.
25
+ *
26
+ * Returns null when reading fails so callers can surface missing configs
27
+ * without crashing.
28
+ *
29
+ * @param {string} filePath Absolute path to a text file.
30
+ * @returns {string|null} File contents.
31
+ */
32
+ function readTextSafe(filePath) {
33
+ try {
34
+ return fs.readFileSync(filePath, "utf8");
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Checks whether a path exists and is a regular file.
42
+ *
43
+ * @param {string} filePath Absolute or relative file path.
44
+ * @returns {boolean} True when the path exists and is a file.
45
+ */
46
+ function isFile(filePath) {
47
+ try {
48
+ return fs.statSync(filePath).isFile();
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Normalizes Composer script entries into a flat list of commands.
56
+ *
57
+ * Composer allows scripts to be strings or arrays. This helper provides a
58
+ * consistent format for analysis.
59
+ *
60
+ * @param {unknown} value Composer script value.
61
+ * @returns {string[]} Command list.
62
+ */
63
+ function normalizeComposerScript(value) {
64
+ if (typeof value === "string") return [value];
65
+ if (Array.isArray(value)) return value.filter((x) => typeof x === "string");
66
+ return [];
67
+ }
68
+
69
+ /**
70
+ * Detects which Composer scripts invoke PHPStan.
71
+ *
72
+ * This helps the agent prefer the repo's own invocation (memory limits,
73
+ * config, bootstrap files) instead of guessing.
74
+ *
75
+ * @param {Record<string, unknown>} scripts Composer scripts block.
76
+ * @returns {Array<{name: string, commands: string[]}>} Matching script entries.
77
+ */
78
+ function findPhpstanScripts(scripts) {
79
+ if (!scripts || typeof scripts !== "object") return [];
80
+
81
+ const matches = [];
82
+
83
+ for (const [name, raw] of Object.entries(scripts)) {
84
+ const commands = normalizeComposerScript(raw);
85
+
86
+ const invokesPhpstan = commands.some((cmd) => {
87
+ if (typeof cmd !== "string") return false;
88
+ return cmd.includes("phpstan") || cmd.includes("vendor/bin/phpstan");
89
+ });
90
+
91
+ if (!invokesPhpstan) continue;
92
+
93
+ matches.push({ name, commands });
94
+ }
95
+
96
+ return matches;
97
+ }
98
+
99
+ /**
100
+ * Chooses a recommended command for running PHPStan in the current repo.
101
+ *
102
+ * The intent is to prefer an existing Composer script (often has correct
103
+ * config, bootstrap, and memory limits), falling back to vendor binaries.
104
+ *
105
+ * @param {Array<{name: string, commands: string[]}>} phpstanScripts Matching Composer scripts.
106
+ * @param {{binaryRelPath: string|null, configRelPath: string|null}} fallbackInfo Fallback discovery.
107
+ * @returns {{command: string|null, rationale: string}} Suggested command and why.
108
+ */
109
+ function suggestCommand(phpstanScripts, fallbackInfo) {
110
+ const preferred = phpstanScripts.find((s) => s.name === "phpstan");
111
+ if (preferred) {
112
+ return {
113
+ command: `composer run ${preferred.name}`,
114
+ rationale: "Uses the repo's Composer script (preferred for consistent config).",
115
+ };
116
+ }
117
+
118
+ if (phpstanScripts.length > 0) {
119
+ return {
120
+ command: `composer run ${phpstanScripts[0].name}`,
121
+ rationale: "Uses the repo's Composer script that invokes PHPStan.",
122
+ };
123
+ }
124
+
125
+ if (!fallbackInfo.binaryRelPath) {
126
+ return {
127
+ command: null,
128
+ rationale: "No PHPStan binary detected under vendor/bin and no Composer script found.",
129
+ };
130
+ }
131
+
132
+ const configArg = fallbackInfo.configRelPath ? ` -c ${fallbackInfo.configRelPath}` : "";
133
+
134
+ return {
135
+ command: `${fallbackInfo.binaryRelPath} analyse${configArg}`,
136
+ rationale: "Falls back to vendor/bin/phpstan with an explicit config when needed.",
137
+ };
138
+ }
139
+
140
+ /**
141
+ * Extracts lightweight hints from a phpstan.neon config.
142
+ *
143
+ * This does not parse NEON. It only checks for common directive tokens so the
144
+ * agent can quickly see whether scan directives are in use.
145
+ *
146
+ * @param {string} configText Raw phpstan config contents.
147
+ * @returns {{mentionsScanDirectories: boolean, mentionsScanFiles: boolean}} Hints.
148
+ */
149
+ function buildConfigHints(configText) {
150
+ const t = configText.toLowerCase();
151
+
152
+ return {
153
+ mentionsScanDirectories: t.includes("scandirectories"),
154
+ mentionsScanFiles: t.includes("scanfiles"),
155
+ };
156
+ }
157
+
158
+ /**
159
+ * Extracts stub-like package references from a PHPStan config.
160
+ *
161
+ * The PHPStan config usually references stubs via vendor paths (for example,
162
+ * "vendor/php-stubs/wordpress-stubs"), so this helper focuses on composer-style
163
+ * "vendor/package" tokens containing "stubs".
164
+ *
165
+ * @param {string} configText Raw phpstan config contents.
166
+ * @returns {string[]} Unique, lowercased composer-style package references.
167
+ */
168
+ function extractStubPackageReferences(configText) {
169
+ const matches = configText
170
+ .toLowerCase()
171
+ .match(/\b[a-z0-9_.-]+\/[a-z0-9_.-]*stubs[a-z0-9_.-]*\b/g);
172
+
173
+ if (!matches) return [];
174
+
175
+ return [...new Set(matches)].sort();
176
+ }
177
+
178
+ /**
179
+ * Builds a JSON report describing the current repository's PHPStan setup.
180
+ *
181
+ * @returns {object} A stable, machine-readable inspection report.
182
+ */
183
+ function buildReport() {
184
+ const repoRoot = process.cwd();
185
+
186
+ const composerPath = path.join(repoRoot, "composer.json");
187
+ const composer = isFile(composerPath) ? readJsonSafe(composerPath) : null;
188
+
189
+ const phpstanConfigFiles = ["phpstan.neon", "phpstan.neon.dist"].filter((f) =>
190
+ isFile(path.join(repoRoot, f))
191
+ );
192
+ const phpstanBaselineFiles = ["phpstan-baseline.neon", "phpstan-baseline.neon.dist"].filter((f) =>
193
+ isFile(path.join(repoRoot, f))
194
+ );
195
+
196
+ let configRelPath = null;
197
+ if (phpstanConfigFiles.includes("phpstan.neon")) configRelPath = "phpstan.neon";
198
+ else if (phpstanConfigFiles.includes("phpstan.neon.dist")) configRelPath = "phpstan.neon.dist";
199
+
200
+ const configAbsPath = configRelPath ? path.join(repoRoot, configRelPath) : null;
201
+ const configText = configAbsPath ? readTextSafe(configAbsPath) : null;
202
+
203
+ const binaryRelPath = isFile(path.join(repoRoot, "vendor", "bin", "phpstan")) ? "vendor/bin/phpstan" : null;
204
+
205
+ const composerScripts = composer?.scripts && typeof composer.scripts === "object" ? composer.scripts : null;
206
+ const phpstanScripts = composerScripts ? findPhpstanScripts(composerScripts) : [];
207
+
208
+ const composerDependencies = [
209
+ ...Object.keys(composer?.require ?? {}),
210
+ ...Object.keys(composer?.["require-dev"] ?? {}),
211
+ ].sort();
212
+ const referencedDependencies = configText ? extractStubPackageReferences(configText) : [];
213
+
214
+ const configHints = configText ? buildConfigHints(configText) : null;
215
+
216
+ const suggested = suggestCommand(phpstanScripts, {
217
+ binaryRelPath,
218
+ configRelPath: configRelPath === "phpstan.neon" ? null : configRelPath,
219
+ });
220
+
221
+ const notes = [];
222
+
223
+ if (!composer) notes.push("No composer.json found; PHPStan is usually installed via Composer.");
224
+ if (phpstanConfigFiles.length === 0) notes.push("No phpstan.neon or phpstan.neon.dist found at repo root.");
225
+ if (!binaryRelPath && phpstanScripts.length === 0) notes.push("No PHPStan entrypoint detected (Composer script or vendor/bin/phpstan).");
226
+
227
+
228
+
229
+ return {
230
+ tool: { name: "phpstan_inspect", version: TOOL_VERSION },
231
+ repoRoot,
232
+ composer: {
233
+ exists: Boolean(composer),
234
+ path: isFile(composerPath) ? "composer.json" : null,
235
+ phpstanScripts,
236
+ dependencies: composerDependencies,
237
+ },
238
+ phpstan: {
239
+ configFiles: phpstanConfigFiles,
240
+ baselineFiles: phpstanBaselineFiles,
241
+ config: {
242
+ primary: configRelPath,
243
+ hints: configHints,
244
+ referencedDependencies,
245
+ },
246
+ binary: {
247
+ vendorBin: binaryRelPath,
248
+ },
249
+ },
250
+ suggested,
251
+ notes,
252
+ };
253
+ }
254
+
255
+ /**
256
+ * CLI entrypoint for printing the inspection report.
257
+ */
258
+ function main() {
259
+ const report = buildReport();
260
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
261
+ }
262
+
263
+ main();
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: wp-playground
3
+ description: "Use for WordPress Playground workflows: fast disposable WP instances in the browser or locally via @wp-playground/cli (server, run-blueprint, build-snapshot), auto-mounting plugins/themes, switching WP/PHP versions, blueprints, and debugging (Xdebug)."
4
+ compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Playground CLI requires Node.js 20.18+; runs WP in WebAssembly with SQLite."
5
+ ---
6
+
7
+ # WordPress Playground
8
+
9
+ ## When to use
10
+
11
+ - Spin up a disposable WordPress to test a plugin/theme without full stack setup.
12
+ - Run or iterate on Playground Blueprints (JSON) locally.
13
+ - Build a reproducible snapshot of a site for sharing or CI.
14
+ - Switch WP/PHP versions quickly to reproduce issues.
15
+ - Debug plugin/theme code with Xdebug in an isolated Playground.
16
+
17
+ ## Inputs required
18
+
19
+ - Host machine readiness: Node.js ≥ 20.18, `npm`/`npx` available.
20
+ - Project path to mount (`--auto-mount` or explicit mount mapping).
21
+ - Desired WP version/PHP version (optional; defaults to latest WP, PHP 8.3).
22
+ - Blueprint location/URL if running a blueprint.
23
+ - Port preference if 9400 conflicts.
24
+ - Whether Xdebug is needed.
25
+
26
+ ## Procedure
27
+
28
+ ### 0) Guardrails
29
+
30
+ - Playground instances are ephemeral and SQLite-backed; **never** point at production data.
31
+ - Confirm Node ≥ 20.18 (`node -v`) before running CLI.
32
+ - If mounting local code, ensure it is clean of secrets; Playground copies files into an in-memory FS.
33
+
34
+ ### 1) Quick local spin-up (auto-mount)
35
+
36
+ ```bash
37
+ cd <plugin-or-theme-root>
38
+ npx @wp-playground/cli@latest server --auto-mount
39
+ ```
40
+ - Opens on http://localhost:9400 by default. Auto-detects plugin/theme and installs it.
41
+ - Add `--wp=<version>` / `--php=<version>` as needed.
42
+ - For classic full installs already present, add `--skip-wordpress-setup` and mount the whole tree.
43
+
44
+ ### 2) Manual mounts or multiple mounts
45
+
46
+ - Use `--mount=/host/path:/vfs/path` (repeatable) when auto-mount is insufficient (multi-plugin, mu-plugins, custom content).
47
+ - Mount before install with `--mount-before-install` for bootstrapping installer flows.
48
+ - Reference: `references/cli-commands.md`
49
+
50
+ ### 3) Run a Blueprint (no server needed)
51
+
52
+ ```bash
53
+ npx @wp-playground/cli@latest run-blueprint --blueprint=<file-or-url>
54
+ ```
55
+ - Use for scripted setup/CI validation. Supports remote URLs and local files.
56
+ - Allow bundled assets in local blueprints with `--blueprint-may-read-adjacent-files` when required.
57
+ - See `references/blueprints.md` for structure and common flags.
58
+
59
+ ### 4) Build a snapshot for sharing
60
+
61
+ ```bash
62
+ npx @wp-playground/cli@latest build-snapshot --blueprint=<file> --outfile=./site.zip
63
+ ```
64
+ - Produces a ZIP you can load in Playground or attach to bug reports.
65
+
66
+ ### 5) Debugging with Xdebug
67
+
68
+ - Start with `--xdebug` (or `--enable-xdebug` depending on CLI release) to expose an IDE key, then connect VS Code/PhpStorm to the host/port shown in CLI output.
69
+ - Combine with `--auto-mount` for plugin/theme debugging.
70
+ - Checklist: `references/debugging.md`
71
+
72
+ ### 6) Version switching
73
+
74
+ - Use `--wp=` to pin WP (e.g., 6.9.0) and `--php=` to test compatibility.
75
+ - If feature depends on Gutenberg trunk, prefer the latest WP release plus plugin if available; Playground images track stable WP plus bundled Gutenberg.
76
+
77
+ ### 7) Browser-only workflows (no CLI)
78
+
79
+ - Launch quick previews with URL fragments or query params:
80
+ - Fragment: `https://playground.wordpress.net/#<base64-or-json-blueprint>`
81
+ - Query: `https://playground.wordpress.net/?blueprint-url=<public-url-or-zip>`
82
+ - Use the live Blueprint Editor (playground.wordpress.net) to author blueprints with schema help; paste JSON and copy a shareable link.
83
+
84
+ ## Verification
85
+
86
+ - Verify mounted code is active (plugin listed/active; theme selected).
87
+ - For blueprints/snapshots, re-run with `--verbosity=debug` to confirm steps executed.
88
+ - Run targeted smoke (e.g., `wp plugin list` inside Playground shell via browser terminal if exposed) or UI click-path.
89
+
90
+ ## Failure modes / debugging
91
+
92
+ - **CLI exits complaining about Node**: upgrade to ≥ 20.18.
93
+ - **Mount not applied**: check path, use absolute path, add `--verbosity=debug`.
94
+ - **Blueprint cannot read local assets**: add `--blueprint-may-read-adjacent-files`.
95
+ - **Port already used**: `--port=<free-port>`.
96
+ - **Slow/locked UI**: disable `--experimental-multi-worker` if enabled; or enable it to improve throughput on CPU-bound runs.
97
+
98
+ ## Escalation
99
+
100
+ - If PHP extensions or native DB access are required, Playground may be unsuitable; fall back to full WP stack or wp-env/Docker.
101
+ - For browser-only embedding or VS Code extension specifics, consult the upstream docs: https://wordpress.github.io/wordpress-playground/
@@ -0,0 +1,36 @@
1
+ ## Blueprint quick reference
2
+
3
+ Blueprints are JSON recipes that describe how Playground should set up WordPress.
4
+
5
+ ### Minimal example
6
+
7
+ ```json
8
+ {
9
+ "$schema": "https://playground.wordpress.net/blueprint-schema.json",
10
+ "steps": [
11
+ { "step": "installTheme", "themeZipUrl": "https://downloads.wordpress.org/theme/twentytwentythree.zip" },
12
+ { "step": "installPlugin", "pluginZipUrl": "https://downloads.wordpress.org/plugin/classic-editor.zip" }
13
+ ]
14
+ }
15
+ ```
16
+
17
+ ### Common steps (non-exhaustive)
18
+
19
+ - `setSiteUrl`, `setHomeUrl`
20
+ - `installTheme`, `installPlugin` (ZIP URLs or local paths when allowed)
21
+ - `activateTheme`, `activatePlugin`
22
+ - `runPHP` (inline PHP)
23
+ - `applyPatches` (filesystem patch)
24
+ - `writeFile` (create/update files)
25
+ - `importFile` (XML/WXR)
26
+ - `wpConfigConstants` (define constants)
27
+ - `preferredVersions` (pick WP/PHP; matches CLI `--wp` / `--php`)
28
+ - `blueprintSteps` that include `extraLibraries` (e.g., Jetpack) and `features.networking` when browser networking is required
29
+
30
+ ### Tips
31
+
32
+ - Use `--blueprint-may-read-adjacent-files` when the blueprint needs local files (e.g., custom plugin ZIP) during `run-blueprint` or `build-snapshot`.
33
+ - For iterative authoring, keep blueprints small and compose via separate files.
34
+ - Validate against the published schema URL above to catch typos.
35
+ - For Gutenberg/nightly testing, set `--wp=<version>` to align with target WP.
36
+ - To share quickly, encode the blueprint as base64 in the Playground URL fragment or host the JSON/ZIP and pass `?blueprint-url=…`.
@@ -0,0 +1,39 @@
1
+ ## Playground CLI command cheatsheet
2
+
3
+ > Requires Node.js 20.18+ and npm/npx.
4
+ > Latest version: 3.0.20 (November 2025)
5
+
6
+ ### What's new in 2025
7
+
8
+ - **PHP 8.3 is now the default** (since July 2025).
9
+ - **New PHP extensions**: ImageMagick, SOAP, and AVIF GD support.
10
+ - **OpCache enabled**: 42% faster response times (185ms → 108ms average).
11
+ - **Multi-worker default**: `--experimental-multi-worker` now defaults to CPU count minus one.
12
+
13
+ ### Install / run server
14
+
15
+ - `npx @wp-playground/cli@latest server [--port=9400] [--auto-mount] [--wp=<ver>] [--php=<ver>] [--verbosity=debug] [--blueprint=<url-or-path>]`
16
+ - Mounts:
17
+ - `--auto-mount` (detect plugin/theme in CWD)
18
+ - `--mount=/abs/host:/vfs/path` (repeatable)
19
+ - `--mount-before-install` (apply mounts before WP install)
20
+
21
+ ### Run a blueprint
22
+
23
+ - `npx @wp-playground/cli@latest run-blueprint --blueprint=<file-or-url> [--blueprint-may-read-adjacent-files] [--wp=<ver>] [--php=<ver>] [--verbosity=debug]`
24
+ - Use for scripted setup; no persistent server.
25
+
26
+ ### Build a snapshot
27
+
28
+ - `npx @wp-playground/cli@latest build-snapshot --blueprint=<file-or-url> --outfile=./site.zip [--verbosity=debug]`
29
+ - Produces a sharable ZIP usable by Playground UI or other CLI commands.
30
+
31
+ ### Debugging flags
32
+
33
+ - `--xdebug` / `--enable-xdebug` (depends on release) to start Xdebug listener.
34
+ - `--experimental-multi-worker` to speed multi-step blueprints; disable if unstable.
35
+
36
+ ### Version control
37
+
38
+ - `--wp=<version>` to pick WordPress version (defaults to latest).
39
+ - `--php=<version>` to pick PHP version (defaults to 8.3 since July 2025).
@@ -0,0 +1,16 @@
1
+ ## Debugging WordPress Playground
2
+
3
+ - Start CLI with Xdebug: `server --auto-mount --xdebug` (or `--enable-xdebug` depending on release). The CLI prints host/port and IDE key to configure your debugger.
4
+ - If breakpoints are not hit, confirm:
5
+ - IDE listens on the port shown by CLI.
6
+ - Path mappings include the mounted VFS path used by Playground.
7
+ - For slow or stuck runs:
8
+ - Add `--verbosity=debug` to see step-level logs.
9
+ - Disable `--experimental-multi-worker` if it was enabled.
10
+ - For mount issues:
11
+ - Prefer absolute paths in `--mount`.
12
+ - Use `--mount-before-install` when installer steps need files present early.
13
+ - To inspect runtime state:
14
+ - Open the Playground browser console; the Service Worker logs network/FS events.
15
+ - Use the “Terminal” tab (if available) to run WP-CLI inside the instance.
16
+
@@ -0,0 +1,112 @@
1
+ ---
2
+ name: wp-plugin-development
3
+ description: "Use when developing WordPress plugins: architecture and hooks, activation/deactivation/uninstall, admin UI and Settings API, data storage, cron/tasks, security (nonces/capabilities/sanitization/escaping), and release packaging."
4
+ compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."
5
+ ---
6
+
7
+ # WP Plugin Development
8
+
9
+ ## When to use
10
+
11
+ Use this skill for plugin work such as:
12
+
13
+ - creating or refactoring plugin structure (bootstrap, includes, namespaces/classes)
14
+ - adding hooks/actions/filters
15
+ - activation/deactivation/uninstall behavior and migrations
16
+ - adding settings pages / options / admin UI (Settings API)
17
+ - security fixes (nonces, capabilities, sanitization/escaping, SQL safety)
18
+ - packaging a release (build artifacts, readme, assets)
19
+
20
+ ## Inputs required
21
+
22
+ - Repo root + target plugin(s) (path to plugin main file if known).
23
+ - Where this plugin runs: single site vs multisite; WP.com conventions if applicable.
24
+ - Target WordPress + PHP versions (affects available APIs and placeholder support in `$wpdb->prepare()`).
25
+
26
+ ## Procedure
27
+
28
+ ### 0) Triage and locate plugin entrypoints
29
+
30
+ 1. Run triage:
31
+ - `node skills/wp-project-triage/scripts/detect_wp_project.mjs`
32
+ 2. Detect plugin headers (deterministic scan):
33
+ - `node skills/wp-plugin-development/scripts/detect_plugins.mjs`
34
+
35
+ If this is a full site repo, pick the specific plugin under `wp-content/plugins/` or `mu-plugins/` before changing code.
36
+
37
+ ### 1) Follow a predictable architecture
38
+
39
+ Guidelines:
40
+
41
+ - Keep a single bootstrap (main plugin file with header).
42
+ - Avoid heavy side effects at file load time; load on hooks.
43
+ - Prefer a dedicated loader/class to register hooks.
44
+ - Keep admin-only code behind `is_admin()` (or admin hooks) to reduce frontend overhead.
45
+
46
+ See:
47
+ - `references/structure.md`
48
+
49
+ ### 2) Hooks and lifecycle (activation/deactivation/uninstall)
50
+
51
+ Activation hooks are fragile; follow guardrails:
52
+
53
+ - register activation/deactivation hooks at top-level, not inside other hooks
54
+ - flush rewrite rules only when needed and only after registering CPTs/rules
55
+ - uninstall should be explicit and safe (`uninstall.php` or `register_uninstall_hook`)
56
+
57
+ See:
58
+ - `references/lifecycle.md`
59
+
60
+ ### 3) Settings and admin UI (Settings API)
61
+
62
+ Prefer Settings API for options:
63
+
64
+ - `register_setting()`, `add_settings_section()`, `add_settings_field()`
65
+ - sanitize via `sanitize_callback`
66
+
67
+ See:
68
+ - `references/settings-api.md`
69
+
70
+ ### 4) Security baseline (always)
71
+
72
+ Before shipping:
73
+
74
+ - Validate/sanitize input early; escape output late.
75
+ - Use nonces to prevent CSRF *and* capability checks for authorization.
76
+ - Avoid directly trusting `$_POST` / `$_GET`; use `wp_unslash()` and specific keys.
77
+ - Use `$wpdb->prepare()` for SQL; avoid building SQL with string concatenation.
78
+
79
+ See:
80
+ - `references/security.md`
81
+
82
+ ### 5) Data storage, cron, migrations (if needed)
83
+
84
+ - Prefer options for small config; custom tables only if necessary.
85
+ - For cron tasks, ensure idempotency and provide manual run paths (WP-CLI or admin).
86
+ - For schema changes, write upgrade routines and store schema version.
87
+
88
+ See:
89
+ - `references/data-and-cron.md`
90
+
91
+ ## Verification
92
+
93
+ - Plugin activates with no fatals/notices.
94
+ - Settings save and read correctly (capability + nonce enforced).
95
+ - Uninstall removes intended data (and nothing else).
96
+ - Run repo lint/tests (PHPUnit/PHPCS if present) and any JS build steps if the plugin ships assets.
97
+
98
+ ## Failure modes / debugging
99
+
100
+ - Activation hook not firing:
101
+ - hook registered incorrectly (not in main file scope), wrong main file path, or plugin is network-activated
102
+ - Settings not saving:
103
+ - settings not registered, wrong option group, missing capability, nonce failure
104
+ - Security regressions:
105
+ - nonce present but missing capability checks; or sanitized input not escaped on output
106
+
107
+ See:
108
+ - `references/debugging.md`
109
+
110
+ ## Escalation
111
+
112
+ For canonical detail, consult the Plugin Handbook and security guidelines before inventing patterns.
@@ -0,0 +1,19 @@
1
+ # Data storage, cron, and upgrades
2
+
3
+ Use this file when adding persistent storage, background jobs, or upgrade routines.
4
+
5
+ ## Data storage
6
+
7
+ - Prefer Options API for small config/state.
8
+ - Use custom tables only when needed; store schema version and provide upgrade paths.
9
+
10
+ ## Cron
11
+
12
+ - Ensure tasks are idempotent (may run late or multiple times).
13
+ - Provide a manual trigger path for debugging (WP-CLI or admin-only action).
14
+
15
+ ## Database safety note
16
+
17
+ If using `$wpdb->prepare()`, avoid building queries with concatenated user input.
18
+ Recent WordPress versions support identifier placeholders (`%i`) but you must not assume it exists without checking capabilities or target versions.
19
+
@@ -0,0 +1,19 @@
1
+ # Debugging quick routes
2
+
3
+ ## Plugin doesn’t load / fatal errors
4
+
5
+ - Confirm correct plugin main file and header.
6
+ - Check PHP error logs and `WP_DEBUG_LOG`.
7
+ - If the repo is a site repo, confirm you edited the correct plugin under `wp-content/plugins/`.
8
+
9
+ ## Activation hook surprises
10
+
11
+ - Hooks must be registered at top-level.
12
+ - Activation runs in a special context; avoid assuming other hooks already ran.
13
+
14
+ ## Settings not saving
15
+
16
+ - Confirm `register_setting()` is called.
17
+ - Confirm the option group matches the form.
18
+ - Confirm capability checks and nonces.
19
+
@@ -0,0 +1,33 @@
1
+ # Activation, deactivation, uninstall
2
+
3
+ Use this file for lifecycle changes and data cleanup.
4
+
5
+ ## Activation / deactivation hooks
6
+
7
+ - `register_activation_hook( __FILE__, 'callback' )`
8
+ - `register_deactivation_hook( __FILE__, 'callback' )`
9
+
10
+ Guardrails:
11
+
12
+ - These hooks must be registered at top-level (not inside other hooks).
13
+ - If you flush rewrite rules, ensure rules are registered first (often via a shared function called both on `init` and activation).
14
+
15
+ Upstream reference:
16
+
17
+ - https://developer.wordpress.org/plugins/plugin-basics/activation-deactivation-hooks/
18
+
19
+ ## Uninstall
20
+
21
+ Preferred approaches:
22
+
23
+ - `uninstall.php` (runs only on uninstall)
24
+ - `register_uninstall_hook()`
25
+
26
+ Guardrails:
27
+
28
+ - Check `WP_UNINSTALL_PLUGIN` before running destructive cleanup.
29
+
30
+ Upstream reference:
31
+
32
+ - https://developer.wordpress.org/plugins/plugin-basics/uninstall-methods/
33
+
@@ -0,0 +1,29 @@
1
+ # Security guardrails (plugin work)
2
+
3
+ Use this file when making security fixes or when handling any input/output.
4
+
5
+ ## Nonces + permissions
6
+
7
+ - Nonces help prevent CSRF, not authorization.
8
+ - Always pair nonces with capability checks (`current_user_can()` or a more specific capability).
9
+
10
+ Upstream reference:
11
+
12
+ - https://developer.wordpress.org/apis/security/nonces/
13
+
14
+ ## Sanitization and escaping
15
+
16
+ Golden rule:
17
+
18
+ - sanitize/validate on input, escape on output.
19
+
20
+ Practical rules:
21
+
22
+ - never process the entire `$_POST` / `$_GET` array; read explicit keys
23
+ - use `wp_unslash()` before sanitizing when needed
24
+ - use prepared statements for SQL; avoid interpolating user input into queries
25
+
26
+ Common review guidance:
27
+
28
+ - https://developer.wordpress.org/plugins/wordpress-org/detailed-plugin-guidelines/
29
+