wordpress-agent-kit 0.4.0 → 0.5.1

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 (132) hide show
  1. package/.agents/skills/blueprint/SKILL.md +418 -0
  2. package/.agents/skills/wordpress-router/SKILL.md +52 -0
  3. package/.agents/skills/wordpress-router/references/decision-tree.md +55 -0
  4. package/.agents/skills/wp-abilities-api/SKILL.md +108 -0
  5. package/.agents/skills/wp-abilities-api/references/delegate-helper-pattern.md +241 -0
  6. package/.agents/skills/wp-abilities-api/references/domain-vs-projection.md +113 -0
  7. package/.agents/skills/wp-abilities-api/references/error-code-vocabulary.md +123 -0
  8. package/.agents/skills/wp-abilities-api/references/grouping-heuristic.md +89 -0
  9. package/.agents/skills/wp-abilities-api/references/input-schema-gotchas.md +265 -0
  10. package/.agents/skills/wp-abilities-api/references/php-registration.md +94 -0
  11. package/.agents/skills/wp-abilities-api/references/plugin-family-patterns.md +233 -0
  12. package/.agents/skills/wp-abilities-api/references/rest-api.md +13 -0
  13. package/.agents/skills/wp-abilities-api/references/shared-core-service.md +184 -0
  14. package/.agents/skills/wp-abilities-audit/SKILL.md +199 -0
  15. package/.agents/skills/wp-abilities-audit/references/audit-schema.md +300 -0
  16. package/.agents/skills/wp-abilities-audit/references/capability-gate-tracing.md +197 -0
  17. package/.agents/skills/wp-abilities-audit/references/controller-enumeration.md +116 -0
  18. package/.agents/skills/wp-abilities-verify/SKILL.md +215 -0
  19. package/.agents/skills/wp-abilities-verify/references/annotation-correctness.md +154 -0
  20. package/.agents/skills/wp-abilities-verify/references/audit-schema-validation.md +131 -0
  21. package/.agents/skills/wp-abilities-verify/references/permission-roundtrip.md +190 -0
  22. package/.agents/skills/wp-abilities-verify/references/runtime-harness.md +462 -0
  23. package/.agents/skills/wp-abilities-verify/references/schema-lints.md +118 -0
  24. package/.agents/skills/wp-abilities-verify/references/static-enumeration.md +126 -0
  25. package/.agents/skills/wp-block-development/SKILL.md +175 -0
  26. package/.agents/skills/wp-block-development/references/attributes-and-serialization.md +22 -0
  27. package/.agents/skills/wp-block-development/references/block-json.md +49 -0
  28. package/.agents/skills/wp-block-development/references/creating-new-blocks.md +46 -0
  29. package/.agents/skills/wp-block-development/references/debugging.md +36 -0
  30. package/.agents/skills/wp-block-development/references/deprecations.md +24 -0
  31. package/.agents/skills/wp-block-development/references/dynamic-rendering.md +23 -0
  32. package/.agents/skills/wp-block-development/references/inner-blocks.md +25 -0
  33. package/.agents/skills/wp-block-development/references/registration.md +30 -0
  34. package/.agents/skills/wp-block-development/references/supports-and-wrappers.md +18 -0
  35. package/.agents/skills/wp-block-development/references/tooling-and-testing.md +21 -0
  36. package/.agents/skills/wp-block-development/scripts/list_blocks.mjs +121 -0
  37. package/.agents/skills/wp-block-themes/SKILL.md +117 -0
  38. package/.agents/skills/wp-block-themes/references/creating-new-block-theme.md +37 -0
  39. package/.agents/skills/wp-block-themes/references/debugging.md +24 -0
  40. package/.agents/skills/wp-block-themes/references/patterns.md +18 -0
  41. package/.agents/skills/wp-block-themes/references/style-variations.md +14 -0
  42. package/.agents/skills/wp-block-themes/references/templates-and-parts.md +16 -0
  43. package/.agents/skills/wp-block-themes/references/theme-json.md +59 -0
  44. package/.agents/skills/wp-block-themes/scripts/detect_block_themes.mjs +117 -0
  45. package/.agents/skills/wp-interactivity-api/SKILL.md +180 -0
  46. package/.agents/skills/wp-interactivity-api/references/debugging.md +29 -0
  47. package/.agents/skills/wp-interactivity-api/references/directives-quickref.md +30 -0
  48. package/.agents/skills/wp-interactivity-api/references/server-side-rendering.md +310 -0
  49. package/.agents/skills/wp-performance/SKILL.md +147 -0
  50. package/.agents/skills/wp-performance/references/autoload-options.md +24 -0
  51. package/.agents/skills/wp-performance/references/cron.md +20 -0
  52. package/.agents/skills/wp-performance/references/database.md +20 -0
  53. package/.agents/skills/wp-performance/references/http-api.md +15 -0
  54. package/.agents/skills/wp-performance/references/measurement.md +21 -0
  55. package/.agents/skills/wp-performance/references/object-cache.md +24 -0
  56. package/.agents/skills/wp-performance/references/query-monitor-headless.md +38 -0
  57. package/.agents/skills/wp-performance/references/server-timing.md +22 -0
  58. package/.agents/skills/wp-performance/references/wp-cli-doctor.md +24 -0
  59. package/.agents/skills/wp-performance/references/wp-cli-profile.md +32 -0
  60. package/.agents/skills/wp-performance/scripts/perf_inspect.mjs +128 -0
  61. package/.agents/skills/wp-phpstan/SKILL.md +98 -0
  62. package/.agents/skills/wp-phpstan/references/configuration.md +52 -0
  63. package/.agents/skills/wp-phpstan/references/third-party-classes.md +76 -0
  64. package/.agents/skills/wp-phpstan/references/wordpress-annotations.md +124 -0
  65. package/.agents/skills/wp-phpstan/scripts/phpstan_inspect.mjs +263 -0
  66. package/.agents/skills/wp-playground/SKILL.md +233 -0
  67. package/.agents/skills/wp-playground/references/blueprints.md +36 -0
  68. package/.agents/skills/wp-playground/references/cli-commands.md +39 -0
  69. package/.agents/skills/wp-playground/references/debugging.md +16 -0
  70. package/.agents/skills/wp-playground/references/e2e-playwright.md +115 -0
  71. package/.agents/skills/wp-plugin-development/SKILL.md +113 -0
  72. package/.agents/skills/wp-plugin-development/references/data-and-cron.md +19 -0
  73. package/.agents/skills/wp-plugin-development/references/debugging.md +19 -0
  74. package/.agents/skills/wp-plugin-development/references/lifecycle.md +33 -0
  75. package/.agents/skills/wp-plugin-development/references/security.md +29 -0
  76. package/.agents/skills/wp-plugin-development/references/settings-api.md +22 -0
  77. package/.agents/skills/wp-plugin-development/references/structure.md +16 -0
  78. package/.agents/skills/wp-plugin-development/scripts/detect_plugins.mjs +122 -0
  79. package/.agents/skills/wp-plugin-directory-guidelines/SKILL.md +133 -0
  80. package/.agents/skills/wp-plugin-directory-guidelines/references/gpl-compliance.md +217 -0
  81. package/.agents/skills/wp-plugin-directory-guidelines/references/guideline-review-checklist.md +592 -0
  82. package/.agents/skills/wp-plugin-directory-guidelines/references/naming-rules.md +121 -0
  83. package/.agents/skills/wp-project-triage/SKILL.md +39 -0
  84. package/.agents/skills/wp-project-triage/references/triage.schema.json +143 -0
  85. package/.agents/skills/wp-project-triage/scripts/detect_wp_project.mjs +610 -0
  86. package/.agents/skills/wp-rest-api/SKILL.md +115 -0
  87. package/.agents/skills/wp-rest-api/references/authentication.md +18 -0
  88. package/.agents/skills/wp-rest-api/references/custom-content-types.md +20 -0
  89. package/.agents/skills/wp-rest-api/references/discovery-and-params.md +20 -0
  90. package/.agents/skills/wp-rest-api/references/responses-and-fields.md +30 -0
  91. package/.agents/skills/wp-rest-api/references/routes-and-endpoints.md +36 -0
  92. package/.agents/skills/wp-rest-api/references/schema.md +22 -0
  93. package/.agents/skills/wp-wpcli-and-ops/SKILL.md +126 -0
  94. package/.agents/skills/wp-wpcli-and-ops/references/automation.md +30 -0
  95. package/.agents/skills/wp-wpcli-and-ops/references/cron-and-cache.md +23 -0
  96. package/.agents/skills/wp-wpcli-and-ops/references/debugging.md +17 -0
  97. package/.agents/skills/wp-wpcli-and-ops/references/multisite.md +22 -0
  98. package/.agents/skills/wp-wpcli-and-ops/references/packages-and-updates.md +22 -0
  99. package/.agents/skills/wp-wpcli-and-ops/references/safety.md +30 -0
  100. package/.agents/skills/wp-wpcli-and-ops/references/search-replace.md +40 -0
  101. package/.agents/skills/wp-wpcli-and-ops/scripts/wpcli_inspect.mjs +90 -0
  102. package/.agents/skills/wp-wpengine/SKILL.md +398 -0
  103. package/.agents/skills/wp-wpengine/references/ci-gate.md +469 -0
  104. package/.agents/skills/wp-wpengine/references/github-actions-deploy.md +736 -0
  105. package/.agents/skills/wp-wpengine/scripts/ci-gate.sh +118 -0
  106. package/.agents/skills/wp-wpengine/scripts/wpe-check.sh +89 -0
  107. package/.agents/skills/wp-wpengine/scripts/wpe-preflight.sh +104 -0
  108. package/.agents/skills/wpds/SKILL.md +59 -0
  109. package/.github/agents/wp-architect.agent.md +1 -2
  110. package/.github/copilot-instructions.md +1 -1
  111. package/.github/instructions/wordpress-workflow.instructions.md +3 -3
  112. package/AGENTS.md +22 -10
  113. package/AGENTS.template.md +20 -10
  114. package/README.md +89 -85
  115. package/dist/cli.js +5 -1
  116. package/dist/commands/clean-skills.js +64 -0
  117. package/dist/commands/setup.js +6 -2
  118. package/dist/commands/sync-skills.js +3 -0
  119. package/dist/lib/api.js +164 -5
  120. package/dist/lib/installer.js +166 -2
  121. package/extensions/wp-agent-kit/index.ts +185 -10
  122. package/package.json +10 -14
  123. package/skills-custom/wp-wpengine/SKILL.md +299 -28
  124. package/skills-custom/wp-wpengine/references/ci-gate.md +469 -0
  125. package/skills-custom/wp-wpengine/references/github-actions-deploy.md +736 -0
  126. package/skills-custom/wp-wpengine/scripts/ci-gate.sh +118 -0
  127. package/skills-custom/wp-wpengine/scripts/wpe-check.sh +89 -0
  128. package/skills-custom/wp-wpengine/scripts/wpe-preflight.sh +104 -0
  129. package/.github/workflows/ci.yml +0 -44
  130. package/.husky/pre-commit +0 -7
  131. package/CLI_REVIEW.md +0 -250
  132. package/biome.json +0 -39
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![License: GPL v2](https://img.shields.io/badge/License-GPL%20v2-blue.svg?style=flat-square)](LICENSE)
4
4
  [![TypeScript](https://img.shields.io/badge/Written%20in-TypeScript-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
5
- [![Version](https://img.shields.io/badge/version-0.4.0-blue?style=flat-square)](package.json)
5
+ [![Version](https://img.shields.io/badge/version-0.5.1-blue?style=flat-square)](package.json)
6
6
  [![Node](https://img.shields.io/badge/node-%3E%3D20.18-green?style=flat-square)](package.json)
7
7
  [![CI](https://img.shields.io/badge/CI-passing-brightgreen?style=flat-square)](.github/workflows/ci.yml)
8
8
 
@@ -26,21 +26,17 @@ npx wp-agent-kit install /path/to/my-plugin --platform github
26
26
  npx wp-agent-kit setup /path/to/my-plugin --auto
27
27
 
28
28
  # 3. (Optional) Verify the triage report
29
- node .github/skills/wp-project-triage/scripts/detect_wp_project.mjs
29
+ node .agents/skills/wp-project-triage/scripts/detect_wp_project.mjs
30
30
  ```
31
31
 
32
32
  **What gets installed:**
33
+
33
34
  ```
34
35
  my-plugin/
35
36
  ├── AGENTS.md # Project-specific agent instructions
36
37
  ├── AGENTS.template.md # Template reference for future updates
37
- ├── .github/
38
- ├── agents/
39
- │ │ └── wp-architect.agent.md # WordPress Architect agent persona
40
- │ ├── instructions/
41
- │ │ └── wordpress-workflow.instructions.md
42
- │ ├── prompts/
43
- │ └── skills/ # 17 WordPress skills + 1 optional
38
+ ├── .agents/
39
+ └── skills/ # 18 WordPress skills (AgentSkills.io convention)
44
40
  │ ├── wp-project-triage/ # Project detection
45
41
  │ ├── wp-plugin-development/ # Plugin architecture
46
42
  │ ├── wp-block-development/ # Gutenberg blocks
@@ -55,6 +51,12 @@ my-plugin/
55
51
  │ ├── wpds/ # Design system
56
52
  │ ├── wordpress-router/ # Repo classification
57
53
  │ └── wp-wpengine/ # (optional) WP Engine hosting + git push
54
+ ├── .github/
55
+ │ ├── agents/
56
+ │ │ └── wp-architect.agent.md # WordPress Architect agent persona
57
+ │ ├── instructions/
58
+ │ │ └── wordpress-workflow.instructions.md
59
+ │ └── prompts/
58
60
  └── .wp-agent-kit-manifest.github.json # Safe-update tracking
59
61
  ```
60
62
 
@@ -65,7 +67,7 @@ my-plugin/
65
67
  npx wp-agent-kit install /path/to/existing-plugin --platform github
66
68
 
67
69
  # 2. Run triage to detect your project's type, tech stack, and tooling
68
- node .github/skills/wp-project-triage/scripts/detect_wp_project.mjs
70
+ node .agents/skills/wp-project-triage/scripts/detect_wp_project.mjs
69
71
 
70
72
  # 3. Configure based on detection (headless)
71
73
  npx wp-agent-kit setup /path/to/existing-plugin --auto
@@ -79,6 +81,7 @@ npx wp-agent-kit setup /path/to/existing-plugin \
79
81
  ```
80
82
 
81
83
  **Key behavior:**
84
+
82
85
  - Your existing `AGENTS.md` is **never overwritten** — only new sections are added
83
86
  - Triage inspects your codebase and returns structured JSON with project kind, signals, and tooling
84
87
  - Setup updates only the tooling/configuration sections of AGENTS.md
@@ -97,6 +100,7 @@ npx wp-agent-kit upgrade --force
97
100
  ```
98
101
 
99
102
  **Safe update behavior:**
103
+
100
104
  - Compares installed files against a manifest of original hashes
101
105
  - Files you haven't modified → automatically updated
102
106
  - Files you modified → **skipped** (preserved)
@@ -114,32 +118,32 @@ npx wp-agent-kit install --no-safe --force
114
118
 
115
119
  ### CLI Commands
116
120
 
117
- | Command | Purpose |
118
- |---------|---------|
119
- | `install [dir]` | Install kit into a project |
120
- | `setup [dir]` | Interactive or headless configuration |
121
+ | Command | Purpose |
122
+ | ------------------- | ---------------------------------------------- |
123
+ | `install [dir]` | Install kit into a project |
124
+ | `setup [dir]` | Interactive or headless configuration |
121
125
  | `sync-skills [ref]` | Pull latest skills from WordPress/agent-skills |
122
- | `upgrade [dir]` | Check or apply version upgrades |
123
- | `playground` | Launch local WordPress Playground |
126
+ | `upgrade [dir]` | Check or apply version upgrades |
127
+ | `playground` | Launch local WordPress Playground |
124
128
 
125
129
  ### Platform Flags
126
130
 
127
- | Platform | Flag | Target Directory |
128
- |----------|------|-----------------|
129
- | GitHub Copilot / VS Code | `--platform github` | `.github/` |
130
- | Cursor IDE | `--platform cursor` | `.cursor/` |
131
- | Claude Code | `--platform claude` | `.claude/` |
132
- | Pi Coding Agent | `--platform pi` | `.pi/agent/` |
133
- | Generic .agent | `--platform agent` | `.agent/` |
131
+ | Platform | Flag | Target Directory |
132
+ | ------------------------ | ------------------- | ---------------- |
133
+ | GitHub Copilot / VS Code | `--platform github` | `.github/` |
134
+ | Cursor IDE | `--platform cursor` | `.cursor/` |
135
+ | Claude Code | `--platform claude` | `.claude/` |
136
+ | Pi Coding Agent | `--platform pi` | `.pi/agent/` |
137
+ | Generic .agent | `--platform agent` | `.agent/` |
134
138
 
135
139
  ### Agent-Friendly Flags (All Commands)
136
140
 
137
- | Flag | Description |
138
- |------|-------------|
139
- | `--json` | Machine-readable JSON output |
140
- | `--dry-run` | Preview changes without applying |
141
- | `--ndjson` | Newline-delimited JSON for streaming |
142
- | `--quiet` | Suppress non-error output |
141
+ | Flag | Description |
142
+ | ----------- | ------------------------------------ |
143
+ | `--json` | Machine-readable JSON output |
144
+ | `--dry-run` | Preview changes without applying |
145
+ | `--ndjson` | Newline-delimited JSON for streaming |
146
+ | `--quiet` | Suppress non-error output |
143
147
 
144
148
  ---
145
149
 
@@ -153,21 +157,21 @@ pi install npm:wordpress-agent-kit
153
157
 
154
158
  ### Pi Tools (Callable by the Agent)
155
159
 
156
- | Tool | What it does |
157
- |------|-------------|
158
- | `wp_triage` | Detect WordPress project type, signals, and tooling |
160
+ | Tool | What it does |
161
+ | ---------------- | --------------------------------------------------- |
162
+ | `wp_triage` | Detect WordPress project type, signals, and tooling |
159
163
  | `wp_install_kit` | Install/update kit into a project (safe by default) |
160
- | `wp_sync_skills` | Sync skills from WordPress/agent-skills upstream |
161
- | `wp_upgrade` | Check and apply version upgrades |
164
+ | `wp_sync_skills` | Sync skills from WordPress/agent-skills upstream |
165
+ | `wp_upgrade` | Check and apply version upgrades |
162
166
 
163
167
  ### Pi Commands (Type `/` in Pi TUI)
164
168
 
165
- | Command | What it does |
166
- |---------|-------------|
167
- | `/wp-triage [dir]` | Run project detection, show in status bar |
168
- | `/wp-install [dir]` | Install kit into current project |
169
- | `/wp-sync-skills [ref]` | Sync skills from upstream |
170
- | `/wp-upgrade` | Show installed vs latest version |
169
+ | Command | What it does |
170
+ | ----------------------- | ----------------------------------------- |
171
+ | `/wp-triage [dir]` | Run project detection, show in status bar |
172
+ | `/wp-install [dir]` | Install kit into current project |
173
+ | `/wp-sync-skills [ref]` | Sync skills from upstream |
174
+ | `/wp-upgrade` | Show installed vs latest version |
171
175
 
172
176
  ---
173
177
 
@@ -177,24 +181,24 @@ Import directly into scripts, tests, or other tools:
177
181
 
178
182
  ```typescript
179
183
  import {
180
- installKitApi, // Install/update kit
181
- syncSkillsApi, // Sync skills from upstream
182
- runTriageApi, // Run project detection
183
- configureAgentsMdApi, // Configure AGENTS.md
184
- computeChanges, // Preview file changes (dry-run)
185
- isKitInstalled, // Check if kit is installed
186
- loadManifest, // Read install manifest
187
- updateKit, // Raw safe update
188
- ExitCode, // Semantic exit codes
184
+ installKitApi, // Install/update kit
185
+ syncSkillsApi, // Sync skills from upstream
186
+ runTriageApi, // Run project detection
187
+ configureAgentsMdApi, // Configure AGENTS.md
188
+ computeChanges, // Preview file changes (dry-run)
189
+ isKitInstalled, // Check if kit is installed
190
+ loadManifest, // Read install manifest
191
+ updateKit, // Raw safe update
192
+ ExitCode, // Semantic exit codes
189
193
  } from 'wordpress-agent-kit/api';
190
194
 
191
195
  // Install with safe update
192
196
  const result = await installKitApi({
193
197
  targetDir: '/path/to/my-plugin',
194
198
  platform: 'github',
195
- safe: true, // Use manifest-based diff
196
- backup: true, // Create backup before changes
197
- force: false, // Don't overwrite user mods
199
+ safe: true, // Use manifest-based diff
200
+ backup: true, // Create backup before changes
201
+ force: false, // Don't overwrite user mods
198
202
  });
199
203
 
200
204
  // Dry-run preview
@@ -212,44 +216,44 @@ console.log(triage.data.project.primary); // "plugin"
212
216
 
213
217
  ### Semantic Exit Codes
214
218
 
215
- | Code | Meaning |
216
- |------|---------|
217
- | 0 | Success |
218
- | 2 | Invalid arguments |
219
- | 3 | Not found |
220
- | 4 | Permission denied |
221
- | 5 | Already exists |
222
- | 6 | Git error |
223
- | 7 | Network error |
224
- | 8 | Validation failed |
225
- | 130 | Cancelled |
219
+ | Code | Meaning |
220
+ | ---- | ----------------- |
221
+ | 0 | Success |
222
+ | 2 | Invalid arguments |
223
+ | 3 | Not found |
224
+ | 4 | Permission denied |
225
+ | 5 | Already exists |
226
+ | 6 | Git error |
227
+ | 7 | Network error |
228
+ | 8 | Validation failed |
229
+ | 130 | Cancelled |
226
230
 
227
231
  ---
228
232
 
229
233
  ## Skills Reference
230
234
 
231
- All 17 skills follow the [AgentSkills.io](https://agentskills.io) specification. Skills in `skills-custom/` are project-specific (not from upstream) and survive `sync-skills`:
232
-
233
- | Skill | When to Use |
234
- |-------|------------|
235
- | `wp-project-triage` | Run deterministic project detection (type, tooling, versions) |
236
- | `wp-plugin-development` | Develop WordPress plugins (hooks, settings, security, release) |
237
- | `wp-block-development` | Develop Gutenberg blocks (block.json, attributes, rendering) |
238
- | `wp-block-themes` | Develop block themes (theme.json, templates, patterns, variations) |
239
- | `wp-rest-api` | Build, extend, or debug REST API endpoints/routes |
240
- | `wp-interactivity-api` | Build Interactive blocks with data-wp-* directives |
241
- | `wp-abilities-api` | Register and consume WordPress Abilities API |
242
- | `wp-abilities-audit` | Audit a plugin's REST surface for Abilities API opportunities |
243
- | `wp-abilities-verify` | Verify registered Abilities match their annotations |
244
- | `wp-performance` | Profile and optimize WordPress performance |
245
- | `wp-phpstan` | Configure and run PHPStan static analysis |
246
- | `wp-wpcli-and-ops` | WP-CLI commands, automation, multisite operations |
247
- | `wp-playground` | Test with disposable Playground instances; PHPUnit, Playwright E2E, CI |
248
- | `blueprint` | Write and edit WordPress Playground blueprint JSON |
249
- | `wpds` | Build UIs with the WordPress Design System |
250
- | `wp-plugin-directory-guidelines` | GPL compliance, naming, slug rules for WP.org submission |
251
- | `wordpress-router` | Route/classify repository type and select appropriate skills |
252
- | **`wp-wpengine`** *(optional, custom)* | **WP Engine git push, install/domain/cache/backup management via wpe-labs skills** |
235
+ All 18 skills follow the [AgentSkills.io](https://agentskills.io) specification. Skills in `skills-custom/` are project-specific (not from upstream) and survive `sync-skills`:
236
+
237
+ | Skill | When to Use |
238
+ | -------------------------------------- | ---------------------------------------------------------------------------------- |
239
+ | `wp-project-triage` | Run deterministic project detection (type, tooling, versions) |
240
+ | `wp-plugin-development` | Develop WordPress plugins (hooks, settings, security, release) |
241
+ | `wp-block-development` | Develop Gutenberg blocks (block.json, attributes, rendering) |
242
+ | `wp-block-themes` | Develop block themes (theme.json, templates, patterns, variations) |
243
+ | `wp-rest-api` | Build, extend, or debug REST API endpoints/routes |
244
+ | `wp-interactivity-api` | Build Interactive blocks with data-wp-\* directives |
245
+ | `wp-abilities-api` | Register and consume WordPress Abilities API |
246
+ | `wp-abilities-audit` | Audit a plugin's REST surface for Abilities API opportunities |
247
+ | `wp-abilities-verify` | Verify registered Abilities match their annotations |
248
+ | `wp-performance` | Profile and optimize WordPress performance |
249
+ | `wp-phpstan` | Configure and run PHPStan static analysis |
250
+ | `wp-wpcli-and-ops` | WP-CLI commands, automation, multisite operations |
251
+ | `wp-playground` | Test with disposable Playground instances; PHPUnit, Playwright E2E, CI |
252
+ | `blueprint` | Write and edit WordPress Playground blueprint JSON |
253
+ | `wpds` | Build UIs with the WordPress Design System |
254
+ | `wp-plugin-directory-guidelines` | GPL compliance, naming, slug rules for WP.org submission |
255
+ | `wordpress-router` | Route/classify repository type and select appropriate skills |
256
+ | **`wp-wpengine`** _(optional, custom)_ | **WP Engine git push, install/domain/cache/backup management via wpe-labs skills** |
253
257
 
254
258
  ---
255
259
 
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
3
  import { Command } from 'commander';
4
+ import { cleanSkillsCommand } from './commands/clean-skills.js';
4
5
  import { installCommand } from './commands/install.js';
5
6
  import { runPlaygroundCommand } from './commands/run-playground.js';
6
7
  import { setupCommand } from './commands/setup.js';
@@ -25,6 +26,7 @@ program
25
26
  sortSubcommands: true,
26
27
  });
27
28
  // Add commands
29
+ program.addCommand(cleanSkillsCommand);
28
30
  program.addCommand(installCommand);
29
31
  program.addCommand(setupCommand);
30
32
  program.addCommand(syncSkillsCommand);
@@ -52,9 +54,11 @@ Examples:
52
54
  $ wp-agent-kit install --platform github
53
55
  $ wp-agent-kit setup --auto --json
54
56
  $ wp-agent-kit sync-skills --ref trunk --ndjson
55
- $ wp-agent-kit install --platform pi --dry-run --json
57
+ $ wp-agent-kit clean-skills --dry-run --json
58
+ $ wp-agent-kit clean-skills --remove --platform github
56
59
  $ wp-agent-kit upgrade --check-only --json
57
60
 
61
+
58
62
  Programmatic API:
59
63
  import { installKit, syncSkills, runTriage } from 'wordpress-agent-kit/api';
60
64
 
@@ -0,0 +1,64 @@
1
+ import { Command } from 'commander';
2
+ import { cleanSkillsApi } from '../lib/api.js';
3
+ import { OutputFormatter } from '../utils/output.js';
4
+ function isDryRunResult(result) {
5
+ return result.success && 'wouldExecute' in (result.data || {});
6
+ }
7
+ function isRegularResult(result) {
8
+ return result.success && !('wouldExecute' in (result.data || {}));
9
+ }
10
+ /**
11
+ * Command to detect and remove orphaned skills from an installation.
12
+ * Compares installed skills against the canonical set (upstream + custom).
13
+ */
14
+ export const cleanSkillsCommand = new Command('clean-skills')
15
+ .description('Detect and remove orphaned skills from a WordPress Agent Kit installation')
16
+ .argument('[dir]', 'Target directory', process.cwd())
17
+ .option('--platform <platform>', 'Platform to clean (github, cursor, claude, agent, pi)', 'pi')
18
+ .option('--dry-run', 'Preview changes without applying (default: true)', true)
19
+ .option('--remove', 'Actually remove orphaned skills (default: false — report only)', false)
20
+ .option('--json', 'Output as JSON')
21
+ .option('--quiet', 'Suppress non-essential output')
22
+ .action(async (dir, options) => {
23
+ const targetDir = dir || process.cwd();
24
+ const platform = options.platform || 'pi';
25
+ const result = await cleanSkillsApi({
26
+ targetDir,
27
+ platform,
28
+ dryRun: !options.remove, // dry-run unless --remove is specified
29
+ remove: options.remove,
30
+ });
31
+ if (options.json || options.quiet) {
32
+ process.exit(OutputFormatter.getExitCode(result));
33
+ }
34
+ if (isRegularResult(result)) {
35
+ const data = result.data;
36
+ if (data.orphanedSkills.length === 0) {
37
+ console.log('✓ No orphaned skills found. All skills match the canonical set.');
38
+ }
39
+ else if (data.dryRun) {
40
+ console.log(`Found ${data.orphanedSkills.length} orphaned skill(s):`);
41
+ for (const skill of data.orphanedSkills) {
42
+ console.log(` - ${skill}`);
43
+ }
44
+ console.log('\nRun with --remove to remove them.');
45
+ }
46
+ else {
47
+ console.log(`✓ Removed ${data.removedSkills.length} orphaned skill(s):`);
48
+ for (const skill of data.removedSkills) {
49
+ console.log(` - ${skill}`);
50
+ }
51
+ }
52
+ }
53
+ else if (isDryRunResult(result)) {
54
+ const data = result.data;
55
+ console.log(`Dry-run: ${data.summary.orphanedSkills.length} orphaned skill(s) would be removed:`);
56
+ for (const skill of data.summary.orphanedSkills) {
57
+ console.log(` - ${skill}`);
58
+ }
59
+ }
60
+ else {
61
+ console.error(`✗ Clean failed: ${result.error?.message}`);
62
+ }
63
+ process.exit(result.success ? 0 : 1);
64
+ });
@@ -111,8 +111,12 @@ export const setupCommand = new Command('setup')
111
111
  let detectedTech = [];
112
112
  let detectedPackageManager = 'npm/pnpm';
113
113
  const triageScriptPaths = [
114
+ // Canonical location (AgentSkills.io convention)
115
+ path.join(targetDir, '.agents', 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
116
+ // Legacy platform-specific location
114
117
  path.join(targetDir, platformFolder, 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
115
- path.join(PACKAGE_ROOT, 'vendor/wp-agent-skills/skills/wp-project-triage/scripts/detect_wp_project.mjs'),
118
+ // Source repo
119
+ path.join(PACKAGE_ROOT, '.agents', 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
116
120
  ];
117
121
  const triageScriptPath = triageScriptPaths.find((p) => fs.existsSync(p));
118
122
  if (triageScriptPath) {
@@ -291,6 +295,6 @@ export const setupCommand = new Command('setup')
291
295
  console.log('\nNext steps:');
292
296
  console.log(` 1. Review ${path.join(targetDir, 'AGENTS.md')}`);
293
297
  console.log(` 2. Customize ${path.join(targetDir, platformFolder, 'prompts/')}`);
294
- console.log(` 3. Run triage: node ${path.join(targetDir, platformFolder, 'skills/wp-project-triage/scripts/detect_wp_project.mjs')}`);
298
+ console.log(` 3. Run triage: node ${path.join(targetDir, '.agents', 'skills/wp-project-triage/scripts/detect_wp_project.mjs')}`);
295
299
  process.exit(0);
296
300
  });
@@ -30,6 +30,9 @@ export const syncSkillsCommand = new Command('sync-skills')
30
30
  const data = result.data;
31
31
  console.log(`✓ Synced ${data.skillsSynced} skills from WordPress/agent-skills@${ref}`);
32
32
  console.log(` Method: ${data.method}`);
33
+ if (data.customMerged > 0) {
34
+ console.log(` Custom skills merged: ${data.customMerged}`);
35
+ }
33
36
  console.log(` Duration: ${data.durationMs}ms`);
34
37
  }
35
38
  else if (isDryRunResult(result)) {
package/dist/lib/api.js CHANGED
@@ -267,21 +267,35 @@ export async function syncSkillsApi(options = {}) {
267
267
  // Merge custom skills (skills-custom/) — these are not part of the upstream
268
268
  // WordPress/agent-skills repo and survive upstream syncs.
269
269
  const customSkillsDir = path.join(PACKAGE_ROOT, 'skills-custom');
270
+ let customMerged = 0;
270
271
  if (fs.existsSync(customSkillsDir)) {
271
272
  for (const skillName of fs.readdirSync(customSkillsDir)) {
272
273
  const src = path.join(customSkillsDir, skillName);
273
274
  const dest = path.join(targetSkills, skillName);
274
275
  if (fs.statSync(src).isDirectory()) {
276
+ const isNew = !fs.existsSync(dest);
275
277
  fs.cpSync(src, dest, { recursive: true });
276
- skillsSynced++;
278
+ if (isNew) {
279
+ skillsSynced++;
280
+ }
281
+ customMerged++;
277
282
  }
278
283
  }
279
284
  }
280
- return { success: true, skillsSynced, method };
285
+ // Copy synced skills to the canonical .agents/skills/ directory
286
+ // (AgentSkills.io convention — the pi.skills path in package.json points here).
287
+ const canonicalSkills = path.join(PACKAGE_ROOT, '.agents', 'skills');
288
+ if (fs.existsSync(canonicalSkills)) {
289
+ fs.rmSync(canonicalSkills, { recursive: true, force: true });
290
+ }
291
+ fs.mkdirSync(path.join(PACKAGE_ROOT, '.agents'), { recursive: true });
292
+ fs.cpSync(targetSkills, canonicalSkills, { recursive: true });
293
+ return { success: true, skillsSynced, customMerged, method };
281
294
  });
282
295
  return formatter.success({
283
296
  targetDir,
284
297
  skillsSynced: result.skillsSynced,
298
+ customMerged: result.customMerged,
285
299
  sourceUrl: 'https://github.com/WordPress/agent-skills.git',
286
300
  ref,
287
301
  durationMs: Date.now() - startTime,
@@ -334,7 +348,13 @@ function dryRunSyncSkills(targetDir, ref) {
334
348
  actions.push({
335
349
  type: 'create',
336
350
  target: targetSkills,
337
- description: 'Install synced skills',
351
+ description: 'Install synced skills to .github/skills (sync buffer), then copy to .agents/skills (canonical)',
352
+ });
353
+ const canonicalSkills = path.join(targetDir, '.agents', 'skills');
354
+ actions.push({
355
+ type: 'create',
356
+ target: canonicalSkills,
357
+ description: 'Copy synced skills to .agents/skills (canonical, AgentSkills.io convention)',
338
358
  });
339
359
  return new OutputFormatter('json', 'sync-skills', '0.0.0').success({
340
360
  wouldExecute: true,
@@ -342,6 +362,7 @@ function dryRunSyncSkills(targetDir, ref) {
342
362
  summary: {
343
363
  targetDir,
344
364
  skillsSynced: 0,
365
+ customMerged: 0,
345
366
  sourceUrl: 'https://github.com/WordPress/agent-skills.git',
346
367
  ref,
347
368
  durationMs: 0,
@@ -356,9 +377,13 @@ export async function runTriageApi(options) {
356
377
  const formatter = new OutputFormatter('json', 'triage', '0.0.0');
357
378
  const { targetDir, platform = 'github' } = options;
358
379
  try {
359
- const platformFolder = getPlatformFolder(platform);
360
380
  const triageScriptPaths = [
361
- path.join(targetDir, platformFolder, 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
381
+ // Canonical location (AgentSkills.io convention)
382
+ path.join(targetDir, '.agents', 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
383
+ // Legacy platform-specific location
384
+ path.join(targetDir, getPlatformFolder(platform), 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
385
+ // Source repo
386
+ path.join(PACKAGE_ROOT, '.agents', 'skills/wp-project-triage/scripts/detect_wp_project.mjs'),
362
387
  path.join(PACKAGE_ROOT, 'vendor/wp-agent-skills/skills/wp-project-triage/scripts/detect_wp_project.mjs'),
363
388
  ];
364
389
  const triageScriptPath = triageScriptPaths.find((p) => fs.existsSync(p));
@@ -530,6 +555,140 @@ function getInstalledSummary(targetDir, platform) {
530
555
  }
531
556
  return summary;
532
557
  }
558
+ /**
559
+ * Detect and optionally remove orphaned skills from a target installation.
560
+ * Compares the skills in the target platform directory against the source kit
561
+ * (upstream .agents/skills + skills-custom/) and identifies skills that exist
562
+ * in the target but not in the source.
563
+ */
564
+ export async function cleanSkillsApi(options) {
565
+ const startTime = Date.now();
566
+ const formatter = new OutputFormatter('json', 'clean-skills', '0.0.0');
567
+ const { targetDir, platform, dryRun = false, remove = false } = options;
568
+ try {
569
+ // Canonical skills come from .agents/skills/ (AgentSkills.io convention)
570
+ // with skills-custom/ as supplemental source for custom skills.
571
+ const canonicalSkillsDir = path.join(PACKAGE_ROOT, '.agents', 'skills');
572
+ const customSkillsDir = path.join(PACKAGE_ROOT, 'skills-custom');
573
+ const targetSkillsDir = path.join(targetDir, '.agents', 'skills');
574
+ // Build set of canonical skill names (upstream + custom)
575
+ const canonicalSkills = new Set();
576
+ if (fs.existsSync(canonicalSkillsDir)) {
577
+ for (const entry of fs.readdirSync(canonicalSkillsDir)) {
578
+ const entryPath = path.join(canonicalSkillsDir, entry);
579
+ if (fs.statSync(entryPath).isDirectory()) {
580
+ canonicalSkills.add(entry);
581
+ }
582
+ }
583
+ }
584
+ if (fs.existsSync(customSkillsDir)) {
585
+ for (const entry of fs.readdirSync(customSkillsDir)) {
586
+ const entryPath = path.join(customSkillsDir, entry);
587
+ if (fs.statSync(entryPath).isDirectory()) {
588
+ canonicalSkills.add(entry);
589
+ }
590
+ }
591
+ }
592
+ // Find orphaned skills in target .agents/skills/
593
+ const orphanedSkills = [];
594
+ if (fs.existsSync(targetSkillsDir)) {
595
+ for (const entry of fs.readdirSync(targetSkillsDir)) {
596
+ const entryPath = path.join(targetSkillsDir, entry);
597
+ if (fs.statSync(entryPath).isDirectory() && !canonicalSkills.has(entry)) {
598
+ orphanedSkills.push(entry);
599
+ }
600
+ }
601
+ }
602
+ // Detect legacy skill directories (platform-specific skills/ dirs)
603
+ const platformFolder = getPlatformFolder(platform);
604
+ const legacySkillsDir = path.join(targetDir, platformFolder, 'skills');
605
+ const legacySkillDirs = [];
606
+ if (fs.existsSync(legacySkillsDir)) {
607
+ legacySkillDirs.push(legacySkillsDir);
608
+ }
609
+ // Also check .github/skills for github platform (common legacy location)
610
+ if (platform !== 'github') {
611
+ const githubSkills = path.join(targetDir, '.github', 'skills');
612
+ if (fs.existsSync(githubSkills)) {
613
+ legacySkillDirs.push(githubSkills);
614
+ }
615
+ }
616
+ // Migrate legacy skills to .agents/skills/ and remove legacy dirs
617
+ const migratedSkills = [];
618
+ if (remove && !dryRun && legacySkillDirs.length > 0) {
619
+ for (const legacyDir of legacySkillDirs) {
620
+ for (const entry of fs.readdirSync(legacyDir)) {
621
+ const entryPath = path.join(legacyDir, entry);
622
+ if (!fs.statSync(entryPath).isDirectory())
623
+ continue;
624
+ const destPath = path.join(targetSkillsDir, entry);
625
+ if (!fs.existsSync(destPath)) {
626
+ fs.mkdirSync(path.dirname(destPath), { recursive: true });
627
+ fs.cpSync(entryPath, destPath, { recursive: true });
628
+ migratedSkills.push(entry);
629
+ }
630
+ }
631
+ // Remove the legacy skills directory
632
+ fs.rmSync(legacyDir, { recursive: true, force: true });
633
+ }
634
+ }
635
+ // Remove orphans if requested
636
+ const removedSkills = [];
637
+ if (remove && !dryRun) {
638
+ for (const orphan of orphanedSkills) {
639
+ const orphanPath = path.join(targetSkillsDir, orphan);
640
+ fs.rmSync(orphanPath, { recursive: true, force: true });
641
+ removedSkills.push(orphan);
642
+ }
643
+ }
644
+ const _durationMs = Date.now() - startTime;
645
+ if (dryRun) {
646
+ const actions = orphanedSkills.map((s) => ({
647
+ type: 'delete',
648
+ target: path.join('.agents', 'skills', s),
649
+ description: `Remove orphaned skill: ${s}`,
650
+ }));
651
+ for (const legacyDir of legacySkillDirs) {
652
+ actions.push({
653
+ type: 'delete',
654
+ target: legacyDir,
655
+ description: `Migrate and remove legacy skill directory: ${path.relative(targetDir, legacyDir)}`,
656
+ });
657
+ }
658
+ return formatter.success({
659
+ wouldExecute: true,
660
+ actions,
661
+ summary: {
662
+ targetDir,
663
+ platform,
664
+ orphanedSkills,
665
+ removedSkills: [],
666
+ legacySkillDirs,
667
+ migratedSkills: [],
668
+ dryRun: true,
669
+ },
670
+ });
671
+ }
672
+ return formatter.success({
673
+ targetDir,
674
+ platform,
675
+ orphanedSkills,
676
+ removedSkills,
677
+ legacySkillDirs,
678
+ migratedSkills,
679
+ dryRun: false,
680
+ });
681
+ }
682
+ catch (error) {
683
+ const err = error;
684
+ return formatter.fail({
685
+ code: err.code || 'CLEAN_FAILED',
686
+ message: err.message || 'Clean failed',
687
+ exitCode: err.exitCode ?? ExitCode.ERROR,
688
+ details: { platform, targetDir },
689
+ });
690
+ }
691
+ }
533
692
  export { ExitCode } from '../utils/exit-codes.js';
534
693
  export { OutputFormatter, createFormatter, parseOutputFormat } from '../utils/output.js';
535
694
  export { computeChanges, isKitInstalled, loadManifest, updateKit } from './updater.js';