wordpress-agent-kit 0.2.2 → 0.3.2
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.
- package/.github/agents/wp-architect.agent.md +1 -0
- package/.github/skills/blueprint/SKILL.md +418 -0
- package/.github/skills/wordpress-router/SKILL.md +1 -0
- package/.github/skills/wp-abilities-api/SKILL.md +13 -0
- package/.github/skills/wp-abilities-api/references/delegate-helper-pattern.md +241 -0
- package/.github/skills/wp-abilities-api/references/domain-vs-projection.md +113 -0
- package/.github/skills/wp-abilities-api/references/error-code-vocabulary.md +123 -0
- package/.github/skills/wp-abilities-api/references/grouping-heuristic.md +89 -0
- package/.github/skills/wp-abilities-api/references/input-schema-gotchas.md +265 -0
- package/.github/skills/wp-abilities-api/references/php-registration.md +47 -20
- package/.github/skills/wp-abilities-api/references/plugin-family-patterns.md +233 -0
- package/.github/skills/wp-abilities-api/references/shared-core-service.md +184 -0
- package/.github/skills/wp-abilities-audit/SKILL.md +199 -0
- package/.github/skills/wp-abilities-audit/references/audit-schema.md +300 -0
- package/.github/skills/wp-abilities-audit/references/capability-gate-tracing.md +197 -0
- package/.github/skills/wp-abilities-audit/references/controller-enumeration.md +116 -0
- package/.github/skills/wp-abilities-verify/SKILL.md +215 -0
- package/.github/skills/wp-abilities-verify/references/annotation-correctness.md +154 -0
- package/.github/skills/wp-abilities-verify/references/audit-schema-validation.md +131 -0
- package/.github/skills/wp-abilities-verify/references/permission-roundtrip.md +190 -0
- package/.github/skills/wp-abilities-verify/references/runtime-harness.md +462 -0
- package/.github/skills/wp-abilities-verify/references/schema-lints.md +118 -0
- package/.github/skills/wp-abilities-verify/references/static-enumeration.md +126 -0
- package/.github/skills/wp-block-development/SKILL.md +1 -0
- package/.github/skills/wp-block-themes/SKILL.md +1 -0
- package/.github/skills/wp-interactivity-api/SKILL.md +1 -0
- package/.github/skills/wp-performance/SKILL.md +1 -0
- package/.github/skills/wp-phpstan/SKILL.md +1 -0
- package/.github/skills/wp-playground/SKILL.md +1 -0
- package/.github/skills/wp-plugin-development/SKILL.md +1 -0
- package/.github/skills/wp-plugin-directory-guidelines/SKILL.md +133 -0
- package/.github/skills/wp-plugin-directory-guidelines/references/gpl-compliance.md +217 -0
- package/.github/skills/wp-plugin-directory-guidelines/references/guideline-review-checklist.md +592 -0
- package/.github/skills/wp-plugin-directory-guidelines/references/naming-rules.md +121 -0
- package/.github/skills/wp-project-triage/SKILL.md +1 -0
- package/.github/skills/wp-project-triage/scripts/detect_wp_project.mjs +22 -4
- package/.github/skills/wp-rest-api/SKILL.md +1 -0
- package/.github/skills/wp-wpcli-and-ops/SKILL.md +1 -0
- package/.github/skills/wpds/SKILL.md +1 -0
- package/AGENTS.md +33 -10
- package/AGENTS.template.md +63 -18
- package/README.md +226 -124
- package/biome.json +1 -1
- package/dist/commands/install.js +47 -6
- package/dist/commands/upgrade.js +34 -5
- package/dist/lib/api.js +93 -27
- package/dist/lib/installer.js +113 -7
- package/dist/lib/updater.js +260 -0
- package/extensions/wp-agent-kit/index.ts +452 -0
- package/package.json +21 -3
- package/kit-learnings.md +0 -192
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
/**
|
|
4
|
+
* WordPress Agent Kit — Pi Extension
|
|
5
|
+
*
|
|
6
|
+
* Provides Pi Coding Agent with WordPress development tools:
|
|
7
|
+
* - 17 WordPress agent skills (plugin/theme/block dev, REST API, WP-CLI, etc.)
|
|
8
|
+
* - Project triage detection
|
|
9
|
+
* - Skill installation, syncing, and upgrade management
|
|
10
|
+
*
|
|
11
|
+
* Follows Pi Coding Agent SDK conventions (extensions.md, packages.md, skills.md).
|
|
12
|
+
*/
|
|
13
|
+
import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
|
|
14
|
+
import { Type } from 'typebox';
|
|
15
|
+
|
|
16
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..', '..');
|
|
18
|
+
|
|
19
|
+
// Resolve the API import dynamically — works in both dev (src/) and npm (dist/)
|
|
20
|
+
let apiModule: typeof import('../../dist/lib/api.js');
|
|
21
|
+
try {
|
|
22
|
+
apiModule = await import('../../dist/lib/api.js');
|
|
23
|
+
} catch {
|
|
24
|
+
// Fallback for dev: import from source via jiti
|
|
25
|
+
apiModule = (await import('../../src/lib/api.js')) as typeof import('../../dist/lib/api.js');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const { installKitApi, syncSkillsApi, runTriageApi, isKitInstalled, loadManifest } = apiModule;
|
|
29
|
+
|
|
30
|
+
export default function (pi: ExtensionAPI) {
|
|
31
|
+
// =========================================================================
|
|
32
|
+
// Skills Registration
|
|
33
|
+
// =========================================================================
|
|
34
|
+
pi.on('resources_discover', async (_event, _ctx) => {
|
|
35
|
+
const skillsDir = path.join(PACKAGE_ROOT, '.github', 'skills');
|
|
36
|
+
const promptsDir = path.join(PACKAGE_ROOT, '.github', 'prompts');
|
|
37
|
+
return {
|
|
38
|
+
skillPaths: [skillsDir],
|
|
39
|
+
promptPaths: [promptsDir],
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// =========================================================================
|
|
44
|
+
// Session notifications
|
|
45
|
+
// =========================================================================
|
|
46
|
+
pi.on('session_start', async (_event, ctx) => {
|
|
47
|
+
const platforms: Array<'pi' | 'github'> = ['pi', 'github'];
|
|
48
|
+
for (const p of platforms) {
|
|
49
|
+
if (isKitInstalled(ctx.cwd, p)) {
|
|
50
|
+
const manifest = loadManifest(ctx.cwd, p);
|
|
51
|
+
if (manifest) {
|
|
52
|
+
ctx.ui.setStatus('wp-agent-kit', `WP Agent Kit v${manifest.version}`);
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// =========================================================================
|
|
60
|
+
// Custom Tools
|
|
61
|
+
// =========================================================================
|
|
62
|
+
|
|
63
|
+
// --- wp_triage ---
|
|
64
|
+
pi.registerTool({
|
|
65
|
+
name: 'wp_triage',
|
|
66
|
+
label: 'WP Triage',
|
|
67
|
+
description:
|
|
68
|
+
'Detect WordPress project type (plugin, theme, block theme, site, Gutenberg), signals (block.json, Interactivity API, WP-CLI, REST API), and tooling (PHP/Node). Use before making changes to any WordPress project.',
|
|
69
|
+
promptSnippet: 'Detect WordPress project type, signals, and tooling',
|
|
70
|
+
promptGuidelines: [
|
|
71
|
+
'Use wp_triage before making changes to any WordPress project to understand the codebase.',
|
|
72
|
+
'Use wp_triage output to route to the correct WordPress development skill.',
|
|
73
|
+
],
|
|
74
|
+
parameters: Type.Object({
|
|
75
|
+
targetDir: Type.Optional(
|
|
76
|
+
Type.String({
|
|
77
|
+
description: 'WordPress project directory (defaults to current working directory)',
|
|
78
|
+
})
|
|
79
|
+
),
|
|
80
|
+
}),
|
|
81
|
+
async execute(_callId, params, _signal, _onUpdate, _ctx) {
|
|
82
|
+
const targetDir = params.targetDir || process.cwd();
|
|
83
|
+
const result = await runTriageApi({
|
|
84
|
+
targetDir,
|
|
85
|
+
platform: 'pi',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (!result.success) {
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: 'text',
|
|
93
|
+
text: `Triage failed: ${result.error?.message || 'Unknown error'}`,
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
details: { error: result.error },
|
|
97
|
+
isError: true,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const t = result.data;
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: JSON.stringify(
|
|
107
|
+
{
|
|
108
|
+
project: t.project,
|
|
109
|
+
signals: t.signals,
|
|
110
|
+
tooling: t.tooling,
|
|
111
|
+
recommendation: t.project
|
|
112
|
+
? `${t.project.primary} project (confidence: ${t.project.confidence}). Use the matching wp-* skill.`
|
|
113
|
+
: 'Could not determine project type. Review signals manually.',
|
|
114
|
+
},
|
|
115
|
+
null,
|
|
116
|
+
2
|
|
117
|
+
),
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
details: t,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// --- wp_install_kit ---
|
|
126
|
+
pi.registerTool({
|
|
127
|
+
name: 'wp_install_kit',
|
|
128
|
+
label: 'WP Install Kit',
|
|
129
|
+
description:
|
|
130
|
+
'Install WordPress Agent Kit into a project directory. Copies 17 WordPress development skills, agent definitions, workflow instructions, and an AGENTS.md template. Safe by default — preserves user modifications on re-run.',
|
|
131
|
+
promptSnippet: 'Install WordPress AI agent skills and configuration into a project',
|
|
132
|
+
promptGuidelines: [
|
|
133
|
+
'Use wp_install_kit when setting up a new WordPress project for AI agent development.',
|
|
134
|
+
'Use wp_install_kit with dryRun: true to preview changes before applying.',
|
|
135
|
+
],
|
|
136
|
+
parameters: Type.Object({
|
|
137
|
+
targetDir: Type.String({
|
|
138
|
+
description: 'WordPress project root directory to install into',
|
|
139
|
+
}),
|
|
140
|
+
dryRun: Type.Optional(
|
|
141
|
+
Type.Boolean({
|
|
142
|
+
description: 'Preview changes without applying (default: false)',
|
|
143
|
+
})
|
|
144
|
+
),
|
|
145
|
+
force: Type.Optional(
|
|
146
|
+
Type.Boolean({
|
|
147
|
+
description: 'Overwrite user modifications on update (default: false)',
|
|
148
|
+
})
|
|
149
|
+
),
|
|
150
|
+
}),
|
|
151
|
+
async execute(_callId, params, _signal, onUpdate, _ctx) {
|
|
152
|
+
const opts = {
|
|
153
|
+
targetDir: params.targetDir,
|
|
154
|
+
platform: 'pi' as const,
|
|
155
|
+
dryRun: params.dryRun ?? false,
|
|
156
|
+
force: params.force ?? false,
|
|
157
|
+
safe: !(params.force ?? false),
|
|
158
|
+
backup: true,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
if (opts.dryRun) {
|
|
162
|
+
onUpdate?.({ content: [{ type: 'text', text: 'Computing changes (dry-run)...' }] });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const result = await installKitApi(opts);
|
|
166
|
+
|
|
167
|
+
if (!result.success) {
|
|
168
|
+
return {
|
|
169
|
+
content: [
|
|
170
|
+
{ type: 'text', text: `Install failed: ${result.error?.message || 'Unknown error'}` },
|
|
171
|
+
],
|
|
172
|
+
isError: true,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Dry-run: show change preview
|
|
177
|
+
if (opts.dryRun && 'wouldExecute' in (result.data || {})) {
|
|
178
|
+
const dr = result.data as {
|
|
179
|
+
wouldExecute: boolean;
|
|
180
|
+
actions: Array<{ type: string; description: string }>;
|
|
181
|
+
};
|
|
182
|
+
return {
|
|
183
|
+
content: [
|
|
184
|
+
{
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: [
|
|
187
|
+
'# WordPress Agent Kit — Dry Run',
|
|
188
|
+
'',
|
|
189
|
+
'## Changes',
|
|
190
|
+
...dr.actions.map((a) => `- **${a.type}**: ${a.description}`),
|
|
191
|
+
'',
|
|
192
|
+
'Run without `dryRun` to apply.',
|
|
193
|
+
].join('\n'),
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
details: dr,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Real result
|
|
201
|
+
const data = result.data as {
|
|
202
|
+
filesCreated: string[];
|
|
203
|
+
filesSkipped: string[];
|
|
204
|
+
isUpdate: boolean;
|
|
205
|
+
backupDir: string | null;
|
|
206
|
+
conflicts?: string[];
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const lines = [
|
|
210
|
+
data.isUpdate ? '# Updated' : '# Installed',
|
|
211
|
+
'',
|
|
212
|
+
`**Target**: ${opts.targetDir}`,
|
|
213
|
+
`**Files**: ${data.filesCreated.length} created/updated`,
|
|
214
|
+
];
|
|
215
|
+
|
|
216
|
+
if (data.filesSkipped.length > 0) {
|
|
217
|
+
lines.push(`**Preserved**: ${data.filesSkipped.length} files (user-modified)`);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (data.conflicts?.length) {
|
|
221
|
+
lines.push('', '⚠ **Conflicts** (re-run with `force: true` to overwrite):');
|
|
222
|
+
for (const c of data.conflicts.slice(0, 5)) lines.push(`- ${c}`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (data.backupDir) lines.push('', `**Backup**: ${data.backupDir}`);
|
|
226
|
+
|
|
227
|
+
lines.push(
|
|
228
|
+
'',
|
|
229
|
+
'## Next Steps',
|
|
230
|
+
'1. Run `wp_triage` to detect project type',
|
|
231
|
+
'2. Review `AGENTS.md` for guidance'
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
236
|
+
details: data,
|
|
237
|
+
};
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
// --- wp_sync_skills ---
|
|
242
|
+
pi.registerTool({
|
|
243
|
+
name: 'wp_sync_skills',
|
|
244
|
+
label: 'WP Sync Skills',
|
|
245
|
+
description:
|
|
246
|
+
'Sync WordPress agent skills from the upstream WordPress/agent-skills repository. Fetches the latest 17 skill definitions and replaces the local skills directory.',
|
|
247
|
+
promptSnippet: 'Sync latest WordPress agent skills from upstream',
|
|
248
|
+
promptGuidelines: [
|
|
249
|
+
'Use wp_sync_skills to pull the latest WordPress development skills from WordPress/agent-skills.',
|
|
250
|
+
],
|
|
251
|
+
parameters: Type.Object({
|
|
252
|
+
ref: Type.Optional(
|
|
253
|
+
Type.String({
|
|
254
|
+
description: 'Git ref to sync from (default: trunk)',
|
|
255
|
+
})
|
|
256
|
+
),
|
|
257
|
+
}),
|
|
258
|
+
async execute(_callId, params, _signal, onUpdate, _ctx) {
|
|
259
|
+
onUpdate?.({ content: [{ type: 'text', text: 'Syncing from WordPress/agent-skills...' }] });
|
|
260
|
+
|
|
261
|
+
const result = await syncSkillsApi({
|
|
262
|
+
targetDir: PACKAGE_ROOT,
|
|
263
|
+
ref: params.ref || 'trunk',
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
if (!result.success) {
|
|
267
|
+
return {
|
|
268
|
+
content: [
|
|
269
|
+
{ type: 'text', text: `Sync failed: ${result.error?.message || 'Unknown error'}` },
|
|
270
|
+
],
|
|
271
|
+
isError: true,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const data = result.data as { skillsSynced: number; method: string };
|
|
276
|
+
return {
|
|
277
|
+
content: [
|
|
278
|
+
{
|
|
279
|
+
type: 'text',
|
|
280
|
+
text: `# Skills Synced\n\n**Synced**: ${data.skillsSynced} skills\n**Method**: ${data.method}`,
|
|
281
|
+
},
|
|
282
|
+
],
|
|
283
|
+
details: data,
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// --- wp_upgrade ---
|
|
289
|
+
pi.registerTool({
|
|
290
|
+
name: 'wp_upgrade',
|
|
291
|
+
label: 'WP Upgrade',
|
|
292
|
+
description:
|
|
293
|
+
'Check for WordPress Agent Kit updates. Shows current vs latest version and can preview or apply upgrades.',
|
|
294
|
+
promptSnippet: 'Check WordPress Agent Kit version',
|
|
295
|
+
promptGuidelines: [
|
|
296
|
+
'Use wp_upgrade to check if the installed WordPress Agent Kit is up to date.',
|
|
297
|
+
'Use wp_upgrade with checkOnly: true to preview without applying.',
|
|
298
|
+
],
|
|
299
|
+
parameters: Type.Object({
|
|
300
|
+
targetDir: Type.Optional(
|
|
301
|
+
Type.String({
|
|
302
|
+
description: 'Project directory to check (defaults to cwd)',
|
|
303
|
+
})
|
|
304
|
+
),
|
|
305
|
+
checkOnly: Type.Optional(
|
|
306
|
+
Type.Boolean({
|
|
307
|
+
description: 'Only check for updates, do not apply (default: false)',
|
|
308
|
+
})
|
|
309
|
+
),
|
|
310
|
+
}),
|
|
311
|
+
async execute(_callId, params, _signal, _onUpdate, _ctx) {
|
|
312
|
+
const targetDir = params.targetDir || process.cwd();
|
|
313
|
+
const checkOnly = params.checkOnly ?? false;
|
|
314
|
+
const manifest = loadManifest(targetDir, 'pi') || loadManifest(targetDir, 'github');
|
|
315
|
+
const currentVersion = manifest?.version || 'not installed';
|
|
316
|
+
const latestVersion = (() => {
|
|
317
|
+
try {
|
|
318
|
+
const fs = require('node:fs');
|
|
319
|
+
return JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, 'package.json'), 'utf-8'))
|
|
320
|
+
.version;
|
|
321
|
+
} catch {
|
|
322
|
+
return 'unknown';
|
|
323
|
+
}
|
|
324
|
+
})();
|
|
325
|
+
|
|
326
|
+
const installed = isKitInstalled(targetDir, 'pi') || isKitInstalled(targetDir, 'github');
|
|
327
|
+
|
|
328
|
+
if (checkOnly) {
|
|
329
|
+
return {
|
|
330
|
+
content: [
|
|
331
|
+
{
|
|
332
|
+
type: 'text',
|
|
333
|
+
text: [
|
|
334
|
+
'# WordPress Agent Kit — Version Check',
|
|
335
|
+
'',
|
|
336
|
+
`**Installed**: ${installed ? 'yes' : 'no'}`,
|
|
337
|
+
`**Current**: ${currentVersion}`,
|
|
338
|
+
`**Latest**: ${latestVersion}`,
|
|
339
|
+
'',
|
|
340
|
+
currentVersion !== latestVersion && installed
|
|
341
|
+
? '⚠ Update available. Run without `checkOnly` to apply.'
|
|
342
|
+
: installed
|
|
343
|
+
? '✅ Up to date.'
|
|
344
|
+
: 'Not installed. Use `wp_install_kit` to install.',
|
|
345
|
+
].join('\n'),
|
|
346
|
+
},
|
|
347
|
+
],
|
|
348
|
+
details: { currentVersion, latestVersion, installed },
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
if (!installed) {
|
|
353
|
+
return {
|
|
354
|
+
content: [{ type: 'text', text: 'Kit not installed. Use `wp_install_kit` first.' }],
|
|
355
|
+
isError: true,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const result = await installKitApi({
|
|
360
|
+
targetDir,
|
|
361
|
+
platform: 'pi',
|
|
362
|
+
safe: true,
|
|
363
|
+
backup: true,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
if (!result.success) {
|
|
367
|
+
return {
|
|
368
|
+
content: [{ type: 'text', text: `Upgrade failed: ${result.error?.message}` }],
|
|
369
|
+
isError: true,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const data = result.data as {
|
|
374
|
+
filesCreated: string[];
|
|
375
|
+
filesSkipped: string[];
|
|
376
|
+
conflicts?: string[];
|
|
377
|
+
};
|
|
378
|
+
const lines = [
|
|
379
|
+
'# Upgraded',
|
|
380
|
+
'',
|
|
381
|
+
`**Version**: ${currentVersion} → ${latestVersion}`,
|
|
382
|
+
`**Files updated**: ${data.filesCreated.length}`,
|
|
383
|
+
];
|
|
384
|
+
if (data.filesSkipped.length)
|
|
385
|
+
lines.push(`**Preserved**: ${data.filesSkipped.length} (user-modified)`);
|
|
386
|
+
if (data.conflicts?.length)
|
|
387
|
+
lines.push(`⚠ ${data.conflicts.length} conflicts (use force: true)`);
|
|
388
|
+
|
|
389
|
+
return {
|
|
390
|
+
content: [{ type: 'text', text: lines.join('\n') }],
|
|
391
|
+
details: data,
|
|
392
|
+
};
|
|
393
|
+
},
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
// =========================================================================
|
|
397
|
+
// Commands
|
|
398
|
+
// =========================================================================
|
|
399
|
+
|
|
400
|
+
pi.registerCommand('wp-triage', {
|
|
401
|
+
description: 'Run WordPress project triage detection',
|
|
402
|
+
handler: async (args, ctx) => {
|
|
403
|
+
const targetDir = args?.trim() || ctx.cwd;
|
|
404
|
+
ctx.ui.setStatus('wp-triage', 'Running triage...');
|
|
405
|
+
const result = await runTriageApi({ targetDir, platform: 'pi' });
|
|
406
|
+
if (!result.success) {
|
|
407
|
+
ctx.ui.notify(`Triage failed: ${result.error?.message}`, 'error');
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const t = result.data;
|
|
411
|
+
const summary = t.project
|
|
412
|
+
? `${t.project.primary} (confidence: ${t.project.confidence})`
|
|
413
|
+
: 'unknown';
|
|
414
|
+
ctx.ui.notify(`Project: ${summary}`, 'info');
|
|
415
|
+
ctx.ui.setStatus('wp-triage', summary);
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
pi.registerCommand('wp-install', {
|
|
420
|
+
description: 'Install WordPress Agent Kit into current project',
|
|
421
|
+
handler: async (args, ctx) => {
|
|
422
|
+
const targetDir = args?.trim() || ctx.cwd;
|
|
423
|
+
ctx.ui.setStatus('wp-install', 'Installing...');
|
|
424
|
+
const result = await installKitApi({ targetDir, platform: 'pi', safe: true, backup: true });
|
|
425
|
+
if (!result.success) {
|
|
426
|
+
ctx.ui.notify(`Install failed: ${result.error?.message}`, 'error');
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const data = result.data as { filesCreated: string[]; isUpdate: boolean };
|
|
430
|
+
ctx.ui.notify(
|
|
431
|
+
`${data.isUpdate ? 'Updated' : 'Installed'} (${data.filesCreated.length} entries)`,
|
|
432
|
+
'info'
|
|
433
|
+
);
|
|
434
|
+
ctx.ui.setStatus('wp-agent-kit', 'v0.3.0 installed');
|
|
435
|
+
},
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
pi.registerCommand('wp-sync-skills', {
|
|
439
|
+
description: 'Sync WordPress skills from upstream',
|
|
440
|
+
handler: async (args, ctx) => {
|
|
441
|
+
ctx.ui.setStatus('wp-sync', 'Syncing...');
|
|
442
|
+
const result = await syncSkillsApi({ targetDir: PACKAGE_ROOT, ref: args?.trim() || 'trunk' });
|
|
443
|
+
if (!result.success) {
|
|
444
|
+
ctx.ui.notify(`Sync failed: ${result.error?.message}`, 'error');
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
const data = result.data as { skillsSynced: number };
|
|
448
|
+
ctx.ui.notify(`Synced ${data.skillsSynced} skills`, 'info');
|
|
449
|
+
ctx.ui.setStatus('wp-agent-kit', `${data.skillsSynced} skills`);
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wordpress-agent-kit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "WordPress-focused AGENTS.md + Agent Skills starter kit for AI coding agents.",
|
|
5
5
|
"license": "GPL-2.0-or-later",
|
|
6
6
|
"author": "Kyle Brodeur <kyle@brodeur.me> (https://brodeur.me)",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"agents-md",
|
|
14
14
|
"agent-skills",
|
|
15
15
|
"ai-coding",
|
|
16
|
-
"copilot"
|
|
16
|
+
"copilot",
|
|
17
|
+
"pi-package"
|
|
17
18
|
],
|
|
18
19
|
"engines": {
|
|
19
20
|
"node": ">=20.18"
|
|
@@ -21,10 +22,26 @@
|
|
|
21
22
|
"bin": {
|
|
22
23
|
"wp-agent-kit": "dist/cli.js"
|
|
23
24
|
},
|
|
25
|
+
"exports": {
|
|
26
|
+
".": "./dist/cli.js",
|
|
27
|
+
"./api": "./dist/lib/api.js"
|
|
28
|
+
},
|
|
29
|
+
"pi": {
|
|
30
|
+
"extensions": [
|
|
31
|
+
"./extensions/wp-agent-kit"
|
|
32
|
+
],
|
|
33
|
+
"skills": [
|
|
34
|
+
"./.github/skills"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
24
37
|
"dependencies": {
|
|
25
38
|
"@clack/prompts": "^0.8.2",
|
|
26
39
|
"commander": "^13.0.0"
|
|
27
40
|
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
43
|
+
"typebox": "*"
|
|
44
|
+
},
|
|
28
45
|
"devDependencies": {
|
|
29
46
|
"@biomejs/biome": "1.9.4",
|
|
30
47
|
"@eslint/js": "^9.17.0",
|
|
@@ -38,7 +55,8 @@
|
|
|
38
55
|
"typescript": "^5.7.2",
|
|
39
56
|
"typescript-eslint": "^8.18.0",
|
|
40
57
|
"vitest": "^2.1.8",
|
|
41
|
-
"@earendil-works/pi-coding-agent": "^0.78.1"
|
|
58
|
+
"@earendil-works/pi-coding-agent": "^0.78.1",
|
|
59
|
+
"typebox": "*"
|
|
42
60
|
},
|
|
43
61
|
"scripts": {
|
|
44
62
|
"dev": "tsx src/cli.ts",
|
package/kit-learnings.md
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
# WordPress Agent Kit - Installation & Usage Learnings
|
|
2
|
-
|
|
3
|
-
**Package:** `wordpress-agent-kit@0.2.1` (published on npm)
|
|
4
|
-
**Author:** Kyle Brodeur
|
|
5
|
-
**Repo:** https://github.com/kylebrodeur/wordpress-agent-kit
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Quick Start (What Actually Works)
|
|
10
|
-
|
|
11
|
-
### For Pi (Recommended)
|
|
12
|
-
```bash
|
|
13
|
-
pnpm dlx wordpress-agent-kit@latest install --platform pi
|
|
14
|
-
```
|
|
15
|
-
- Installs skills to `.pi/agent/skills/` (17 skills)
|
|
16
|
-
- Non-interactive, no TTY needed
|
|
17
|
-
- Works in headless/CI environments
|
|
18
|
-
|
|
19
|
-
### For Other Platforms
|
|
20
|
-
```bash
|
|
21
|
-
# GitHub Copilot / VS Code
|
|
22
|
-
pnpm dlx wordpress-agent-kit@latest install --platform github
|
|
23
|
-
|
|
24
|
-
# Cursor IDE
|
|
25
|
-
pnpm dlx wordpress-agent-kit@latest install --platform cursor
|
|
26
|
-
|
|
27
|
-
# Generic agent format
|
|
28
|
-
pnpm dlx wordpress-agent-kit@latest install --platform agent
|
|
29
|
-
|
|
30
|
-
# Claude (interactive - requires TTY)
|
|
31
|
-
pnpm dlx wordpress-agent-kit@latest install --platform claude
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## What DOESN'T Work (Common Pitfalls)
|
|
37
|
-
|
|
38
|
-
### `setup` command requires TTY
|
|
39
|
-
```bash
|
|
40
|
-
pnpm dlx wordpress-agent-kit@latest setup # FAILS in non-interactive shells
|
|
41
|
-
```
|
|
42
|
-
**Error:** `ERR_TTY_INIT_FAILED: uv_tty_init returned EINVAL (invalid argument)`
|
|
43
|
-
|
|
44
|
-
The `setup` command uses `@clack/prompts` for interactive prompts, which requires a real TTY. It fails in:
|
|
45
|
-
- CI/CD pipelines
|
|
46
|
-
- Docker containers without `-it`
|
|
47
|
-
- Non-interactive SSH sessions
|
|
48
|
-
- Most AI agent execution environments
|
|
49
|
-
|
|
50
|
-
**Workaround:** Use `install --platform <platform>` instead.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Platform Comparison
|
|
55
|
-
|
|
56
|
-
| Platform | Target Dir | Interactive? | Best For |
|
|
57
|
-
|----------|------------|--------------|----------|
|
|
58
|
-
| `pi` | `.pi/agent/skills/` | ❌ No | **Pi Coding Agent** (this project) |
|
|
59
|
-
| `github` | `.github/skills/` | ❌ No | GitHub Copilot, VS Code |
|
|
60
|
-
| `cursor` | `.cursor/skills/` | ❌ No | Cursor IDE |
|
|
61
|
-
| `agent` | `.agent/skills/` | ❌ No | Generic `.agent` workflows |
|
|
62
|
-
| `claude` | `.claude/skills/` | ✅ Yes | Claude Code (interactive only) |
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Skills Installed (17 Total)
|
|
67
|
-
|
|
68
|
-
All synced from `WordPress/agent-skills` trunk:
|
|
69
|
-
|
|
70
|
-
1. `wp-abilities-api` - Abilities API registration & consumption
|
|
71
|
-
2. `wp-abilities-audit` - Audit plugin REST surface for Abilities
|
|
72
|
-
3. `wp-abilities-verify` - Verify Abilities registrations
|
|
73
|
-
4. `wp-block-development` - Gutenberg blocks: block.json, attributes, rendering
|
|
74
|
-
5. `wp-block-themes` - Block themes: theme.json, templates, patterns
|
|
75
|
-
6. `wp-interactivity-api` - data-wp-* directives & stores
|
|
76
|
-
7. `wp-performance` - Profiling, caching, DB optimization
|
|
77
|
-
8. `wp-phpstan` - PHPStan config for WordPress
|
|
78
|
-
9. `wp-playground` - WordPress Playground for instant environments
|
|
79
|
-
10. `wp-plugin-development` - Plugin architecture, hooks, Settings API, security
|
|
80
|
-
11. `wp-plugin-directory-guidelines` - WP Plugin Directory requirements
|
|
81
|
-
12. `wp-project-triage` - Auto-detect project type, tooling, versions
|
|
82
|
-
13. `wp-rest-api` - REST API routes, schema, auth, response shaping
|
|
83
|
-
14. `wp-wpcli-and-ops` - WP-CLI commands, automation, multisite
|
|
84
|
-
15. `wpds` - WordPress Design System
|
|
85
|
-
16. `blueprint` - Playground Blueprints for declarative setup
|
|
86
|
-
17. `wordpress-router` - Classifies WP repos, routes to right workflow
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Verification Commands
|
|
91
|
-
|
|
92
|
-
After installation, verify everything works:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
# 1. Check skills installed
|
|
96
|
-
ls -la .pi/agent/skills/
|
|
97
|
-
|
|
98
|
-
# 2. Run project triage (detects WP project type)
|
|
99
|
-
node .pi/agent/skills/wp-project-triage/scripts/detect_wp_project.mjs
|
|
100
|
-
|
|
101
|
-
# 3. Run design-system tests (if applicable)
|
|
102
|
-
cd design-system && pnpm test && pnpm run typecheck
|
|
103
|
-
|
|
104
|
-
# 4. PHP syntax check
|
|
105
|
-
find wpaos wpaos-blocks -name '*.php' -exec php -l {} \;
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Key Files & Locations
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
wordpress-agent-kit/
|
|
114
|
-
├── package.json # Package definition (name: wordpress-agent-kit)
|
|
115
|
-
├── src/
|
|
116
|
-
│ ├── cli.ts # Main CLI entry
|
|
117
|
-
│ ├── commands/
|
|
118
|
-
│ │ ├── install.ts # Non-interactive install (USE THIS)
|
|
119
|
-
│ │ ├── setup.ts # Interactive setup (NEEDS TTY)
|
|
120
|
-
│ │ ├── sync-skills.ts # Pulls from WordPress/agent-skills
|
|
121
|
-
│ │ └── playground.ts # Local WP Playground
|
|
122
|
-
│ └── utils/
|
|
123
|
-
│ └── platforms.ts # Platform definitions (pi, github, cursor, agent, claude)
|
|
124
|
-
├── dist/bundles/ # Pre-built tarballs (legacy method)
|
|
125
|
-
└── vendor/wp-agent-skills/ # Synced upstream skills (gitignored)
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Syncing Latest Upstream Skills
|
|
131
|
-
|
|
132
|
-
The kit bundles skills at release time. To get latest:
|
|
133
|
-
|
|
134
|
-
```bash
|
|
135
|
-
# From kit repo (if contributing)
|
|
136
|
-
pnpm sync:skills
|
|
137
|
-
pnpm build:bundles
|
|
138
|
-
|
|
139
|
-
# Or just reinstall (pulls latest from npm)
|
|
140
|
-
pnpm dlx wordpress-agent-kit@latest install --platform pi --force
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## Integration with This Project (wp-agent-os)
|
|
146
|
-
|
|
147
|
-
### AGENTS.md References
|
|
148
|
-
The project's `AGENTS.md` still references `.github/skills/` but we use `.pi/agent/skills/`. The skills are the same - just different install locations.
|
|
149
|
-
|
|
150
|
-
### wp-abilities-api Verification
|
|
151
|
-
Verified that `wpaos/includes/abilities.php` uses correct arg keys per the skill:
|
|
152
|
-
- `label`, `description`, `category`, `input_schema`, `output_schema`
|
|
153
|
-
- `permission_callback`, `execute_callback`, `meta`
|
|
154
|
-
- `meta.show_in_rest: true`, `meta.mcp.public: true`
|
|
155
|
-
|
|
156
|
-
### CI/CD Usage
|
|
157
|
-
```yaml
|
|
158
|
-
# GitHub Actions example
|
|
159
|
-
- name: Install WordPress Agent Kit
|
|
160
|
-
run: pnpm dlx wordpress-agent-kit@latest install --platform github
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Troubleshooting
|
|
166
|
-
|
|
167
|
-
### "Command not found" / 404 on npm
|
|
168
|
-
- Package name is `wordpress-agent-kit` (NOT `wp-agent-kit`)
|
|
169
|
-
- Published to npm as `kylebrodeur` scope would be `@kylebrodeur/wordpress-agent-kit` but it's unscoped
|
|
170
|
-
|
|
171
|
-
### Skills not showing up
|
|
172
|
-
- Check install location matches your agent's config (`.pi/agent/skills/` for Pi)
|
|
173
|
-
- Run with `--force` to overwrite existing
|
|
174
|
-
|
|
175
|
-
### Old placeholder skills remain
|
|
176
|
-
- Delete old skill directories before reinstall:
|
|
177
|
-
```bash
|
|
178
|
-
rm -rf .claude/skills .github/skills .cursor/skills .agent/skills
|
|
179
|
-
pnpm dlx wordpress-agent-kit@latest install --platform pi
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
---
|
|
183
|
-
|
|
184
|
-
## Summary: Recommended Workflow for This Project
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
# One-liner for clean install in any environment
|
|
188
|
-
rm -rf .claude/skills .github/skills .cursor/skills .agent/skills .pi/agent/skills && \
|
|
189
|
-
pnpm dlx wordpress-agent-kit@latest install --platform pi
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Then the skills live in `.pi/agent/skills/` and are available to Pi automatically.
|