@webpresso/agent-kit 0.21.4 → 0.23.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 (194) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +93 -66
  4. package/bin/_run.js +143 -1
  5. package/bin/runtime-manifest.json +40 -0
  6. package/catalog/AGENTS.md.tpl +7 -6
  7. package/catalog/agent/commands/plan-refine.md +3 -3
  8. package/catalog/agent/commands/pll.md +2 -0
  9. package/catalog/agent/guides/parallel-execution.md +2 -0
  10. package/catalog/agent/rules/extraction-parity.md +27 -1
  11. package/catalog/agent/rules/public-package-safety.md +24 -1
  12. package/catalog/agent/skills/plan-refine/SKILL.md +5 -4
  13. package/catalog/agent/skills/pll/SKILL.md +1 -0
  14. package/catalog/base-kit/.github/workflows/ci.webpresso.yml.tmpl +33 -0
  15. package/catalog/base-kit/commitlint.config.ts.tmpl +1 -3
  16. package/catalog/base-kit/e2e/fixtures/smoke.html.tmpl +13 -0
  17. package/catalog/base-kit/e2e/smoke.spec.ts.tmpl +13 -0
  18. package/catalog/base-kit/oxlint.config.ts.tmpl +26 -0
  19. package/catalog/base-kit/playwright.config.ts.tmpl +10 -0
  20. package/catalog/base-kit/src/quality-sample.test.ts.tmpl +19 -0
  21. package/catalog/base-kit/src/quality-sample.ts.tmpl +11 -0
  22. package/catalog/base-kit/stryker.config.ts.tmpl +14 -0
  23. package/catalog/base-kit/tsconfig.json.tmpl +9 -0
  24. package/catalog/base-kit/vitest.config.ts.tmpl +10 -0
  25. package/catalog/docs/templates/adr.md +1 -1
  26. package/catalog/docs/templates/blueprint.md +2 -0
  27. package/catalog/docs/templates/blueprint.yaml +16 -15
  28. package/catalog/docs/templates/guide.md +1 -1
  29. package/catalog/docs/templates/postmortem.md +1 -1
  30. package/catalog/docs/templates/research.md +1 -1
  31. package/catalog/docs/templates/runbook.md +1 -1
  32. package/catalog/docs/templates/system.md +12 -3
  33. package/catalog/docs/templates/tech-debt.md +1 -0
  34. package/commands/blueprint.md +10 -12
  35. package/dist/esm/audit/blueprint-db-consistency.d.ts +1 -1
  36. package/dist/esm/audit/blueprint-db-consistency.js +6 -8
  37. package/dist/esm/audit/blueprint-lifecycle-sql.js +10 -3
  38. package/dist/esm/audit/cloudflare-deploy-contract.d.ts +3 -0
  39. package/dist/esm/audit/cloudflare-deploy-contract.js +64 -0
  40. package/dist/esm/audit/no-legacy-cli-bin.d.ts +3 -0
  41. package/dist/esm/audit/no-legacy-cli-bin.js +100 -0
  42. package/dist/esm/audit/package-surface.js +14 -1
  43. package/dist/esm/audit/repo-guardrails.js +40 -13
  44. package/dist/esm/audit/resolve-audit-script.d.ts +24 -0
  45. package/dist/esm/audit/resolve-audit-script.js +27 -0
  46. package/dist/esm/audit/roadmap-links.js +23 -10
  47. package/dist/esm/blueprint/core/schema.d.ts +8 -8
  48. package/dist/esm/blueprint/core/schema.js +2 -2
  49. package/dist/esm/blueprint/db/enums.d.ts +1 -1
  50. package/dist/esm/blueprint/db/ingester.js +18 -10
  51. package/dist/esm/blueprint/index.d.ts +0 -1
  52. package/dist/esm/blueprint/index.js +0 -2
  53. package/dist/esm/blueprint/lifecycle/audit.js +9 -2
  54. package/dist/esm/blueprint/lifecycle/local.js +15 -4
  55. package/dist/esm/blueprint/local.d.ts +0 -3
  56. package/dist/esm/blueprint/local.js +0 -2
  57. package/dist/esm/blueprint/service/BlueprintCreationService.js +16 -8
  58. package/dist/esm/blueprint/service/BlueprintService.js +37 -19
  59. package/dist/esm/blueprint/service/scanner.js +73 -9
  60. package/dist/esm/blueprint/tracked-document/schema.d.ts +2 -2
  61. package/dist/esm/blueprint/utils/document-paths.d.ts +23 -0
  62. package/dist/esm/blueprint/utils/document-paths.js +91 -0
  63. package/dist/esm/blueprint/utils/package-assets.d.ts +11 -0
  64. package/dist/esm/blueprint/utils/package-assets.js +33 -4
  65. package/dist/esm/build/package-manifest.js +7 -0
  66. package/dist/esm/build/release-policy.d.ts +27 -0
  67. package/dist/esm/build/release-policy.js +29 -0
  68. package/dist/esm/build/runtime-targets.d.ts +13 -0
  69. package/dist/esm/build/runtime-targets.js +48 -0
  70. package/dist/esm/build/sync-catalog-doc-templates.d.ts +23 -0
  71. package/dist/esm/build/sync-catalog-doc-templates.js +93 -0
  72. package/dist/esm/cli/auto-update/detect-pm.d.ts +15 -0
  73. package/dist/esm/cli/auto-update/detect-pm.js +24 -9
  74. package/dist/esm/cli/auto-update/skip.js +9 -1
  75. package/dist/esm/cli/bundle/agent-command-inventory.d.ts +120 -0
  76. package/dist/esm/cli/bundle/agent-command-inventory.js +100 -0
  77. package/dist/esm/cli/bundle/index.d.ts +17 -0
  78. package/dist/esm/cli/bundle/index.js +15 -0
  79. package/dist/esm/cli/cli.d.ts +1 -1
  80. package/dist/esm/cli/cli.js +49 -5
  81. package/dist/esm/cli/commands/audit-core.d.ts +1 -1
  82. package/dist/esm/cli/commands/audit.js +4 -7
  83. package/dist/esm/cli/commands/blueprint/router.js +16 -10
  84. package/dist/esm/cli/commands/blueprint/template-resolver.js +8 -4
  85. package/dist/esm/cli/commands/hook.d.ts +8 -0
  86. package/dist/esm/cli/commands/hook.js +47 -0
  87. package/dist/esm/cli/commands/init/host-visibility.js +4 -2
  88. package/dist/esm/cli/commands/init/index.js +80 -7
  89. package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +12 -0
  90. package/dist/esm/cli/commands/init/scaffold-base-kit.js +142 -7
  91. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/codex-ownership.js +9 -1
  92. package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +130 -20
  93. package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +65 -0
  94. package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +64 -0
  95. package/dist/esm/cli/commands/package-manager.d.ts +15 -0
  96. package/dist/esm/cli/commands/package-manager.js +42 -0
  97. package/dist/esm/cli/commands/test.d.ts +1 -0
  98. package/dist/esm/cli/commands/test.js +2 -1
  99. package/dist/esm/cli/commands/typecheck.js +10 -19
  100. package/dist/esm/cli/package-scripts.d.ts +12 -0
  101. package/dist/esm/cli/package-scripts.js +59 -0
  102. package/dist/esm/cli/utils.js +3 -22
  103. package/dist/esm/cli/wp-extensions.d.ts +14 -0
  104. package/dist/esm/cli/wp-extensions.js +34 -0
  105. package/dist/esm/config/docs-lint/schemas/common.d.ts +1 -1
  106. package/dist/esm/config/docs-lint/schemas/implementation-plan.d.ts +2 -2
  107. package/dist/esm/config/docs-lint/schemas/parent-roadmap.d.ts +1 -1
  108. package/dist/esm/config/stryker/index.d.ts +85 -0
  109. package/dist/esm/config/stryker/index.js +31 -0
  110. package/dist/esm/e2e/command-builder.js +35 -7
  111. package/dist/esm/e2e/config.d.ts +56 -0
  112. package/dist/esm/e2e/config.js +114 -0
  113. package/dist/esm/e2e/execution.js +8 -0
  114. package/dist/esm/e2e/run-planner.js +2 -0
  115. package/dist/esm/e2e/types.d.ts +3 -0
  116. package/dist/esm/format/index.js +5 -1
  117. package/dist/esm/hooks/guard-switch/index.d.ts +1 -1
  118. package/dist/esm/hooks/guard-switch/index.js +22 -14
  119. package/dist/esm/hooks/post-tool/lint-after-edit.d.ts +1 -0
  120. package/dist/esm/hooks/post-tool/lint-after-edit.js +5 -2
  121. package/dist/esm/hooks/pretool-guard/validators/file-conventions.js +1 -1
  122. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.d.ts +6 -0
  123. package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +27 -2
  124. package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +2 -1
  125. package/dist/esm/hooks/pretool-guard/validators/path-contract.js +59 -34
  126. package/dist/esm/hooks/pretool-guard/validators/plan-frontmatter.js +3 -3
  127. package/dist/esm/hooks/shared/routing-block.js +18 -4
  128. package/dist/esm/hooks/shared/validators/blueprint.js +3 -0
  129. package/dist/esm/hooks/stop/qa-changed-files.d.ts +1 -0
  130. package/dist/esm/hooks/stop/qa-changed-files.js +5 -2
  131. package/dist/esm/lint/index.js +3 -1
  132. package/dist/esm/mcp/auto-discover.d.ts +2 -0
  133. package/dist/esm/mcp/auto-discover.js +14 -6
  134. package/dist/esm/mcp/blueprint-server.js +379 -80
  135. package/dist/esm/mcp/cli.js +21 -0
  136. package/dist/esm/mcp/runners/test.js +15 -0
  137. package/dist/esm/mcp/server.d.ts +7 -0
  138. package/dist/esm/mcp/server.js +16 -27
  139. package/dist/esm/mcp/tools/_registry.d.ts +3 -0
  140. package/dist/esm/mcp/tools/_registry.js +21 -0
  141. package/dist/esm/mcp/tools/audit.d.ts +1 -0
  142. package/dist/esm/mcp/tools/audit.js +13 -8
  143. package/dist/esm/mcp/tools/typecheck.js +4 -2
  144. package/dist/esm/mutation/affected.d.ts +9 -0
  145. package/dist/esm/mutation/affected.js +36 -0
  146. package/dist/esm/package.json +8 -0
  147. package/dist/esm/runtime/package-version.d.ts +2 -0
  148. package/dist/esm/runtime/package-version.js +43 -0
  149. package/dist/esm/test/command-builder.d.ts +4 -0
  150. package/dist/esm/test/command-builder.js +28 -3
  151. package/dist/esm/test-helpers/hermetic-env.d.ts +25 -0
  152. package/dist/esm/test-helpers/hermetic-env.js +31 -0
  153. package/dist/esm/tool-runtime/index.d.ts +5 -0
  154. package/dist/esm/tool-runtime/index.js +24 -0
  155. package/dist/esm/tool-runtime/resolve-runner.d.ts +16 -0
  156. package/dist/esm/tool-runtime/resolve-runner.js +42 -0
  157. package/dist/esm/typecheck/index.js +4 -2
  158. package/dist/esm/wp-extension/index.d.ts +50 -0
  159. package/dist/esm/wp-extension/index.js +268 -0
  160. package/package.json +75 -46
  161. package/skills/plan-refine/SKILL.md +5 -4
  162. package/skills/pll/SKILL.md +1 -0
  163. package/dist/esm/blueprint/dag/cycle-detector.d.ts +0 -12
  164. package/dist/esm/blueprint/dag/cycle-detector.js +0 -46
  165. package/dist/esm/blueprint/dag/executor.d.ts +0 -140
  166. package/dist/esm/blueprint/dag/executor.js +0 -292
  167. package/dist/esm/blueprint/dag/index.d.ts +0 -20
  168. package/dist/esm/blueprint/dag/index.js +0 -17
  169. package/dist/esm/blueprint/dag/interfaces.d.ts +0 -56
  170. package/dist/esm/blueprint/dag/interfaces.js +0 -13
  171. package/dist/esm/blueprint/dag/local/independence.d.ts +0 -107
  172. package/dist/esm/blueprint/dag/local/independence.js +0 -231
  173. package/dist/esm/blueprint/dag/local/index.d.ts +0 -14
  174. package/dist/esm/blueprint/dag/local/index.js +0 -14
  175. package/dist/esm/blueprint/dag/local/package-graph.d.ts +0 -66
  176. package/dist/esm/blueprint/dag/local/package-graph.js +0 -148
  177. package/dist/esm/blueprint/dag/plan-parser.d.ts +0 -54
  178. package/dist/esm/blueprint/dag/plan-parser.js +0 -236
  179. package/dist/esm/blueprint/dag/task-graph-algorithms.d.ts +0 -13
  180. package/dist/esm/blueprint/dag/task-graph-algorithms.js +0 -236
  181. package/dist/esm/blueprint/dag/task-graph.d.ts +0 -171
  182. package/dist/esm/blueprint/dag/task-graph.js +0 -370
  183. package/dist/esm/blueprint/dag/types.d.ts +0 -17
  184. package/dist/esm/blueprint/dag/types.js +0 -2
  185. package/dist/esm/blueprint/graph/index.d.ts +0 -5
  186. package/dist/esm/blueprint/graph/index.js +0 -5
  187. package/dist/esm/blueprint/graph/mermaid-parser.d.ts +0 -3
  188. package/dist/esm/blueprint/graph/mermaid-parser.js +0 -93
  189. package/dist/esm/blueprint/graph/mermaid-serializer.d.ts +0 -3
  190. package/dist/esm/blueprint/graph/mermaid-serializer.js +0 -20
  191. package/dist/esm/blueprint/graph/schema.d.ts +0 -89
  192. package/dist/esm/blueprint/graph/schema.js +0 -104
  193. package/dist/esm/blueprint/graph/task-graph-adapter.d.ts +0 -6
  194. package/dist/esm/blueprint/graph/task-graph-adapter.js +0 -30
@@ -0,0 +1,268 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { createRequire } from 'node:module';
4
+ import { pathToFileURL } from 'node:url';
5
+ export async function loadWpExtensions(options) {
6
+ const cwd = options.cwd ?? process.cwd();
7
+ const env = options.env ?? process.env;
8
+ const readJsonFile = options.readJsonFile ?? defaultReadJsonFile;
9
+ const resolveFrom = options.resolveFrom ?? defaultResolveFrom;
10
+ const importModule = options.importModule ?? defaultImportModule;
11
+ const rootManifestPath = join(cwd, 'package.json');
12
+ const rootManifest = readJsonFile(rootManifestPath);
13
+ const enabled = collectEnabledExtensionPackageNames(rootManifest);
14
+ const loaded = [];
15
+ for (const warning of enabled.warnings) {
16
+ loaded.push({
17
+ packageName: rootManifest?.name ?? '<root>',
18
+ specifier: 'webpresso.wpExtensions',
19
+ compatible: false,
20
+ detected: false,
21
+ warnings: [warning],
22
+ });
23
+ }
24
+ for (const packageName of enabled.packageNames) {
25
+ const packageJsonPath = tryResolve(() => resolveFrom(rootManifestPath, `${packageName}/package.json`));
26
+ if (!packageJsonPath)
27
+ continue;
28
+ const dependencyManifest = readJsonFile(packageJsonPath);
29
+ const extensionSpecifier = dependencyManifest?.webpresso?.wpExtension;
30
+ if (typeof extensionSpecifier !== 'string' || extensionSpecifier.trim().length === 0)
31
+ continue;
32
+ const normalizedSpecifier = extensionSpecifier.trim();
33
+ const modulePath = tryResolve(() => resolveFrom(packageJsonPath, normalizedSpecifier.startsWith('.') ? normalizedSpecifier : normalizedSpecifier));
34
+ if (!modulePath) {
35
+ loaded.push({
36
+ packageName,
37
+ specifier: normalizedSpecifier,
38
+ compatible: false,
39
+ detected: false,
40
+ warnings: [`${packageName}: could not resolve wp extension "${normalizedSpecifier}"`],
41
+ });
42
+ continue;
43
+ }
44
+ let mod;
45
+ try {
46
+ mod = await importModule(modulePath);
47
+ }
48
+ catch (error) {
49
+ loaded.push({
50
+ packageName,
51
+ specifier: normalizedSpecifier,
52
+ compatible: false,
53
+ detected: false,
54
+ warnings: [`${packageName}: failed to load wp extension — ${formatError(error)}`],
55
+ });
56
+ continue;
57
+ }
58
+ if (!isWpExtensionV1(mod.default)) {
59
+ loaded.push({
60
+ packageName,
61
+ specifier: normalizedSpecifier,
62
+ compatible: false,
63
+ detected: false,
64
+ warnings: [
65
+ `${packageName}: wp extension module must default-export a WpExtensionV1 object`,
66
+ ],
67
+ });
68
+ continue;
69
+ }
70
+ const extension = mod.default;
71
+ const compatible = satisfiesHostRange(options.hostVersion, extension.hostRange);
72
+ if (!compatible) {
73
+ loaded.push({
74
+ packageName,
75
+ specifier: normalizedSpecifier,
76
+ extension,
77
+ compatible: false,
78
+ detected: false,
79
+ warnings: [
80
+ `${packageName}: wp extension requires host ${extension.hostRange} but current host is ${options.hostVersion}`,
81
+ ],
82
+ });
83
+ continue;
84
+ }
85
+ let detected = false;
86
+ try {
87
+ detected = await extension.detect({ cwd, env });
88
+ }
89
+ catch (error) {
90
+ loaded.push({
91
+ packageName,
92
+ specifier: normalizedSpecifier,
93
+ extension,
94
+ compatible: true,
95
+ detected: false,
96
+ warnings: [`${packageName}: extension detect() threw: ${formatError(error)}`],
97
+ });
98
+ continue;
99
+ }
100
+ loaded.push({
101
+ packageName,
102
+ specifier: normalizedSpecifier,
103
+ extension,
104
+ compatible: true,
105
+ detected,
106
+ warnings: [],
107
+ });
108
+ }
109
+ return loaded;
110
+ }
111
+ export function resolveAcceptedExtensionAliases(extensions, baseCommands, acceptedCommandNames) {
112
+ const blocked = new Set(baseCommands);
113
+ const knownCommands = new Set(acceptedCommandNames);
114
+ for (const commandName of acceptedCommandNames) {
115
+ blocked.add(commandName);
116
+ }
117
+ const aliases = new Map();
118
+ const warnings = [];
119
+ for (const extension of extensions) {
120
+ if (!extension.extension || !extension.compatible || !extension.detected)
121
+ continue;
122
+ for (const alias of extension.extension.aliases ?? []) {
123
+ if (!knownCommands.has(alias.commandName)) {
124
+ warnings.push(`${extension.packageName}: skipped alias "${alias.name}" because command "${alias.commandName}" is not registered`);
125
+ continue;
126
+ }
127
+ if (blocked.has(alias.name)) {
128
+ warnings.push(`${extension.packageName}: skipped alias "${alias.name}" because it collides with an existing wp command`);
129
+ continue;
130
+ }
131
+ if (aliases.has(alias.name)) {
132
+ warnings.push(`${extension.packageName}: skipped alias "${alias.name}" because another extension already claimed it`);
133
+ continue;
134
+ }
135
+ aliases.set(alias.name, alias);
136
+ }
137
+ }
138
+ return { aliases, warnings, acceptedCommandNames: [...acceptedCommandNames] };
139
+ }
140
+ export function isWpExtensionV1(value) {
141
+ if (!value || typeof value !== 'object' || Array.isArray(value))
142
+ return false;
143
+ const candidate = value;
144
+ if (candidate.apiVersion !== '1')
145
+ return false;
146
+ if (typeof candidate.name !== 'string' || candidate.name.length === 0)
147
+ return false;
148
+ if (typeof candidate.version !== 'string' || candidate.version.length === 0)
149
+ return false;
150
+ if (typeof candidate.hostRange !== 'string' || candidate.hostRange.length === 0)
151
+ return false;
152
+ if (typeof candidate.detect !== 'function')
153
+ return false;
154
+ if (!Array.isArray(candidate.commands))
155
+ return false;
156
+ return candidate.commands.every((command) => command &&
157
+ typeof command === 'object' &&
158
+ typeof command.name === 'string' &&
159
+ typeof command.description === 'string' &&
160
+ typeof command.register === 'function');
161
+ }
162
+ function collectEnabledExtensionPackageNames(manifest) {
163
+ if (!manifest)
164
+ return { packageNames: [], warnings: [] };
165
+ const enabled = manifest.webpresso?.wpExtensions;
166
+ if (enabled === undefined || enabled === false)
167
+ return { packageNames: [], warnings: [] };
168
+ const dependencyNames = collectDependencyNames(manifest);
169
+ if (enabled === true)
170
+ return { packageNames: dependencyNames, warnings: [] };
171
+ if (!Array.isArray(enabled)) {
172
+ return {
173
+ packageNames: [],
174
+ warnings: ['root package webpresso.wpExtensions must be true or an array of package names'],
175
+ };
176
+ }
177
+ const dependencySet = new Set(dependencyNames);
178
+ const packageNames = [];
179
+ const warnings = [];
180
+ for (const entry of enabled) {
181
+ if (typeof entry !== 'string' || entry.trim().length === 0) {
182
+ warnings.push('root package webpresso.wpExtensions contains a non-string package name');
183
+ continue;
184
+ }
185
+ const packageName = entry.trim();
186
+ if (!dependencySet.has(packageName)) {
187
+ warnings.push(`root package enables wp extension "${packageName}" but it is not a direct dependency`);
188
+ continue;
189
+ }
190
+ packageNames.push(packageName);
191
+ }
192
+ return { packageNames: [...new Set(packageNames)], warnings };
193
+ }
194
+ function collectDependencyNames(manifest) {
195
+ const packageNames = new Set();
196
+ for (const section of ['dependencies', 'devDependencies', 'optionalDependencies']) {
197
+ const dependencies = manifest[section];
198
+ if (!dependencies || typeof dependencies !== 'object' || Array.isArray(dependencies))
199
+ continue;
200
+ for (const packageName of Object.keys(dependencies))
201
+ packageNames.add(packageName);
202
+ }
203
+ return [...packageNames];
204
+ }
205
+ function defaultReadJsonFile(path) {
206
+ if (!existsSync(path))
207
+ return;
208
+ try {
209
+ return JSON.parse(readFileSync(path, 'utf8'));
210
+ }
211
+ catch {
212
+ return;
213
+ }
214
+ }
215
+ function defaultResolveFrom(fromFile, specifier) {
216
+ const localRequire = createRequire(fromFile);
217
+ if (specifier.startsWith('.')) {
218
+ return localRequire.resolve(join(dirname(fromFile), specifier));
219
+ }
220
+ return localRequire.resolve(specifier);
221
+ }
222
+ async function defaultImportModule(specifier) {
223
+ return import(pathToFileURL(specifier).href);
224
+ }
225
+ function satisfiesHostRange(version, range) {
226
+ const normalizedRange = range.trim();
227
+ if (normalizedRange.startsWith('^')) {
228
+ const actual = parseVersion(version);
229
+ const expected = parseVersion(normalizedRange.slice(1));
230
+ if (!actual || !expected)
231
+ return false;
232
+ const [actualMajor, actualMinor, actualPatch] = actual;
233
+ const [expectedMajor, expectedMinor, expectedPatch] = expected;
234
+ if (expectedMajor === 0) {
235
+ return actualMajor === 0 && actualMinor === expectedMinor && actualPatch >= expectedPatch;
236
+ }
237
+ if (actualMajor !== expectedMajor)
238
+ return false;
239
+ if (actualMinor > expectedMinor)
240
+ return true;
241
+ if (actualMinor < expectedMinor)
242
+ return false;
243
+ return actualPatch >= expectedPatch;
244
+ }
245
+ const actual = parseVersion(version);
246
+ const expected = parseVersion(normalizedRange);
247
+ if (!actual || !expected)
248
+ return false;
249
+ return actual[0] === expected[0] && actual[1] === expected[1] && actual[2] === expected[2];
250
+ }
251
+ function parseVersion(value) {
252
+ const match = /^v?(\d+)\.(\d+)\.(\d+)/u.exec(value.trim());
253
+ if (!match)
254
+ return null;
255
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
256
+ }
257
+ function tryResolve(callback) {
258
+ try {
259
+ return callback();
260
+ }
261
+ catch {
262
+ return;
263
+ }
264
+ }
265
+ function formatError(error) {
266
+ return error instanceof Error ? error.message : String(error);
267
+ }
268
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpresso/agent-kit",
3
- "version": "0.21.4",
3
+ "version": "0.23.0",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,7 +14,7 @@
14
14
  "registry": "https://registry.npmjs.org/",
15
15
  "access": "public"
16
16
  },
17
- "description": "One command scaffolds a repo so every AI coding agent (Claude Code, Codex CLI, Cursor, Windsurf, Gemini, OpenCode) shares the same context, hooks, and quality gates. The `wp` CLI: blueprints, skills catalog, lore commits, tech-debt lifecycle, audit composite.",
17
+ "description": "TypeScript infrastructure for AI-agent-driven development: the `wp` CLI + MCP server give agents planning (blueprints), tests, mutation, e2e, CI, docs, and tech-debt summary-first so they keep context, and enforced as pre-commit/CI contracts. Manages AGENTS.md / CLAUDE.md and per-agent surfaces.",
18
18
  "keywords": [
19
19
  "agent",
20
20
  "webpresso",
@@ -113,6 +113,14 @@
113
113
  "#mcp/*": "./src/mcp/*.ts",
114
114
  "#content/*.js": "./src/content/*.ts",
115
115
  "#content/*": "./src/content/*.ts",
116
+ "#tool-runtime": "./src/tool-runtime/index.ts",
117
+ "#tool-runtime/*.js": "./src/tool-runtime/*.ts",
118
+ "#tool-runtime/*": "./src/tool-runtime/*.ts",
119
+ "#wp-extension": "./src/wp-extension/index.ts",
120
+ "#wp-extension/*.js": "./src/wp-extension/*.ts",
121
+ "#wp-extension/*": "./src/wp-extension/*.ts",
122
+ "#runtime/*.js": "./src/runtime/*.ts",
123
+ "#runtime/*": "./src/runtime/*.ts",
116
124
  "#output-transforms/*.js": "./src/output-transforms/*.ts",
117
125
  "#output-transforms/*": "./src/output-transforms/*.ts",
118
126
  "#lint/*.js": "./src/lint/*.ts",
@@ -161,22 +169,16 @@
161
169
  "default": "./dist/esm/index.js"
162
170
  }
163
171
  },
164
- "./blueprint": {
165
- "import": {
166
- "types": "./dist/esm/blueprint/index.d.ts",
167
- "default": "./dist/esm/blueprint/index.js"
168
- }
169
- },
170
- "./blueprint/dag": {
172
+ "./bundle": {
171
173
  "import": {
172
- "types": "./dist/esm/blueprint/dag/index.d.ts",
173
- "default": "./dist/esm/blueprint/dag/index.js"
174
+ "types": "./dist/esm/cli/bundle/index.d.ts",
175
+ "default": "./dist/esm/cli/bundle/index.js"
174
176
  }
175
177
  },
176
- "./blueprint/dag/local": {
178
+ "./blueprint": {
177
179
  "import": {
178
- "types": "./dist/esm/blueprint/dag/local/index.d.ts",
179
- "default": "./dist/esm/blueprint/dag/local/index.js"
180
+ "types": "./dist/esm/blueprint/index.d.ts",
181
+ "default": "./dist/esm/blueprint/index.js"
180
182
  }
181
183
  },
182
184
  "./blueprint/local": {
@@ -312,6 +314,12 @@
312
314
  "default": "./dist/esm/config/stryker/index.js"
313
315
  }
314
316
  },
317
+ "./mutation": {
318
+ "import": {
319
+ "types": "./dist/esm/mutation/affected.d.ts",
320
+ "default": "./dist/esm/mutation/affected.js"
321
+ }
322
+ },
315
323
  "./oxlint": {
316
324
  "import": {
317
325
  "types": "./dist/esm/config/oxlint/index.d.ts",
@@ -462,6 +470,12 @@
462
470
  "default": "./dist/esm/typecheck/index.js"
463
471
  }
464
472
  },
473
+ "./wp-extension": {
474
+ "import": {
475
+ "types": "./dist/esm/wp-extension/index.d.ts",
476
+ "default": "./dist/esm/wp-extension/index.js"
477
+ }
478
+ },
465
479
  "./vite": {
466
480
  "import": {
467
481
  "types": "./dist/esm/vite/index.d.ts",
@@ -514,52 +528,59 @@
514
528
  "scripts": {
515
529
  "setup:agent": "wp setup",
516
530
  "build": "tshy && vp run chmod-bins && vp run link-self-bins",
517
- "postbuild": "vp run generate-skills",
531
+ "build:runtime-binaries": "bun scripts/build-runtime-binaries.ts",
532
+ "stage:plugin-runtime": "bun scripts/stage-plugin-runtime-artifacts.ts",
533
+ "postbuild": "vp run generate-skills && vp run sync-doc-templates",
518
534
  "chmod-bins": "bun scripts/chmod-bins.ts",
519
535
  "link-self-bins": "bun scripts/link-self-bins.ts",
520
536
  "dev:link": "bun scripts/link-edge-local.ts",
521
537
  "prepack": "bun src/build/package-manifest.ts prepare",
522
538
  "postpack": "bun src/build/package-manifest.ts restore",
523
539
  "generate-skills": "bun src/build/generate-skills-dir.ts",
540
+ "sync-doc-templates": "bun src/build/sync-catalog-doc-templates.ts",
524
541
  "sync-marketplace-version": "bun scripts/sync-marketplace-version.ts",
525
542
  "version": "changeset version && vp run sync-marketplace-version",
526
- "release:publish": "pnpm run build && npm publish --provenance --access public",
527
- "typecheck": "tsc --noEmit",
528
- "test": "vitest run",
543
+ "release:publish": "bun scripts/release-publish.ts",
544
+ "typecheck": "wp typecheck",
545
+ "test": "vitest run --exclude '**/*.integration.test.ts' --maxWorkers 1 && vitest run --no-file-parallelism .integration.test.ts --testTimeout 30000",
546
+ "test:unit": "vitest run --exclude '**/*.integration.test.ts' --maxWorkers 1",
547
+ "test:integration": "vitest run --no-file-parallelism .integration.test.ts --testTimeout 30000",
529
548
  "test:mutation": "bun stryker run stryker.config.ts",
530
549
  "eval": "bun src/runners/evals/index.ts",
531
- "lint": "vp lint",
532
- "lint:fix": "vp lint --fix",
533
- "format": "WP_SKIP_UPDATE_CHECK=1 wp format",
534
- "format:check": "WP_SKIP_UPDATE_CHECK=1 wp format --check",
550
+ "lint": "wp lint",
551
+ "lint:fix": "wp lint --fix",
552
+ "format": "wp format",
553
+ "format:check": "wp format --check",
535
554
  "lint:pkg": "publint && attw --pack . && (command -v claude >/dev/null 2>&1 && claude plugin validate . || true)",
536
- "blueprints:check": "WP_SKIP_UPDATE_CHECK=1 wp audit blueprint-lifecycle",
537
- "docs:check": "WP_SKIP_UPDATE_CHECK=1 wp audit docs-frontmatter",
538
- "catalog:check": "WP_SKIP_UPDATE_CHECK=1 wp audit catalog-drift",
539
- "license:check": "WP_SKIP_UPDATE_CHECK=1 bun src/cli/cli.ts audit open-source-licenses && bash scripts/verify-no-context-mode.sh",
540
- "imports:check": "WP_SKIP_UPDATE_CHECK=1 wp audit no-relative-parent-imports",
555
+ "blueprints:check": "wp audit blueprint-lifecycle",
556
+ "docs:check": "wp audit docs-frontmatter",
557
+ "catalog:check": "wp audit catalog-drift",
558
+ "license:check": "wp audit open-source-licenses && bash scripts/verify-no-context-mode.sh",
559
+ "imports:check": "wp audit no-relative-parent-imports",
541
560
  "verify:secrets": "bun scripts/check-no-dev-vars.ts",
542
561
  "audit:secret-provider-quarantine": "bun scripts/audit-secret-provider-quarantine.ts",
562
+ "workflow-actions:check": "bun scripts/check-workflow-action-pins.ts",
563
+ "public:consumer-smoke": "bun scripts/public-consumer-smoke.ts",
543
564
  "public:readiness": "bun scripts/public-readiness.ts",
544
- "audits:check": "WP_SKIP_UPDATE_CHECK=1 wp audit guardrails && vp run hooks:doctor:ci",
545
- "hooks:doctor": "WP_SKIP_UPDATE_CHECK=1 wp hooks doctor",
546
- "hooks:doctor:ci": "WP_SKIP_UPDATE_CHECK=1 wp hooks doctor --skip-mcp",
565
+ "audits:check": "wp audit guardrails && vp run workflow-actions:check && vp run hooks:doctor:ci",
566
+ "hooks:doctor": "wp hooks doctor",
567
+ "hooks:doctor:ci": "wp hooks doctor --skip-mcp",
547
568
  "qa": "vp run build && vp run typecheck && vp run lint && vp run format:check && vp run test && vp run lint:pkg && vp run audits:check",
548
569
  "changeset": "changeset",
549
570
  "changeset:status": "changeset status",
550
- "verify:paths": "WP_SKIP_UPDATE_CHECK=1 wp audit absolute-path-policy --root .",
571
+ "verify:paths": "wp audit absolute-path-policy --root .",
551
572
  "prepare": "husky"
552
573
  },
553
574
  "dependencies": {
554
- "@vitejs/plugin-react": "^6.0.1",
555
575
  "@manypkg/find-root": "^3.1.0",
556
576
  "@modelcontextprotocol/sdk": "^1.29.0",
557
- "better-sqlite3": "^12.9.0",
577
+ "@vitejs/plugin-react": "^6.0.2",
578
+ "better-sqlite3": "^12.10.0",
558
579
  "cac": "^7.0.0",
559
580
  "env-paths": "^4.0.0",
560
581
  "glob": "^13.0.6",
561
582
  "gray-matter": "^4.0.3",
562
- "js-yaml": "^4.1.0",
583
+ "js-yaml": "^4.1.1",
563
584
  "ora": "^8.2.0",
564
585
  "proper-lockfile": "^4.1.2",
565
586
  "remark": "^15.0.1",
@@ -567,8 +588,8 @@
567
588
  "remark-validate-links": "^13.1.0",
568
589
  "rulesync": "8.15.1",
569
590
  "ts-pattern": "^5.9.0",
570
- "vite-plus": "^0.1.19",
571
- "yaml": "^2.8.1",
591
+ "vite-plus": "^0.1.22",
592
+ "yaml": "^2.9.0",
572
593
  "zod": "^4.4.3",
573
594
  "zod-to-json-schema": "^3.25.2"
574
595
  },
@@ -580,18 +601,18 @@
580
601
  "@stryker-mutator/typescript-checker": "^9.6.1",
581
602
  "@stryker-mutator/vitest-runner": "^9.6.1",
582
603
  "@types/better-sqlite3": "^7.6.13",
583
- "@types/bun": "^1.1.14",
604
+ "@types/bun": "^1.3.14",
584
605
  "@types/js-yaml": "^4.0.9",
585
- "@types/node": "^25.6.2",
586
- "husky": "^9.0.0",
606
+ "@types/node": "^25.9.1",
607
+ "husky": "^9.1.7",
587
608
  "oxfmt": "^0.48.0",
588
- "oxlint": "^1.63.0",
589
- "publint": "^0.3.20",
609
+ "oxlint": "^1.67.0",
610
+ "publint": "^0.3.21",
590
611
  "secretlint": "^13.0.2",
591
612
  "tshy": "^4.1.2",
592
613
  "typescript": "^6.0.3",
593
- "vite": "^8.0.11",
594
- "vitest": "^4.1.5",
614
+ "vite": "^8.0.14",
615
+ "vitest": "^4.1.7",
595
616
  "webpresso": "latest"
596
617
  },
597
618
  "tshy": {
@@ -607,9 +628,8 @@
607
628
  ],
608
629
  "exports": {
609
630
  ".": "./src/index.ts",
631
+ "./bundle": "./src/cli/bundle/index.ts",
610
632
  "./blueprint": "./src/blueprint/index.ts",
611
- "./blueprint/dag": "./src/blueprint/dag/index.ts",
612
- "./blueprint/dag/local": "./src/blueprint/dag/local/index.ts",
613
633
  "./blueprint/local": "./src/blueprint/local.ts",
614
634
  "./blueprint/tech-debt": "./src/blueprint/tech-debt/index.ts",
615
635
  "./blueprint/test-utils": "./src/blueprint/test-utils/blueprint-mocks.ts",
@@ -633,6 +653,7 @@
633
653
  "./vitest/react-setup.ts": "./src/config/vitest/react-setup.ts",
634
654
  "./vitest/flakiness-reporter": "./src/config/vitest/flakiness-reporter.ts",
635
655
  "./stryker": "./src/config/stryker/index.ts",
656
+ "./mutation": "./src/mutation/affected.ts",
636
657
  "./oxlint": "./src/config/oxlint/index.ts",
637
658
  "./oxlint/import-hygiene": "./src/config/oxlint/import-hygiene.ts",
638
659
  "./oxlint/monorepo-paths": "./src/config/oxlint/monorepo-paths.ts",
@@ -658,6 +679,7 @@
658
679
  "./symlinker": "./src/symlinker/index.ts",
659
680
  "./test": "./src/test/index.ts",
660
681
  "./typecheck": "./src/typecheck/index.ts",
682
+ "./wp-extension": "./src/wp-extension/index.ts",
661
683
  "./vite": "./src/vite/index.ts",
662
684
  "./vite/local": "./src/vite/local.ts",
663
685
  "./ai-memory": "./src/ai-memory/index.ts",
@@ -672,5 +694,12 @@
672
694
  "engines": {
673
695
  "node": ">=24"
674
696
  },
675
- "packageManager": "pnpm@11.1.1"
697
+ "packageManager": "pnpm@11.1.1",
698
+ "optionalDependencies": {
699
+ "@webpresso/agent-kit-runtime-darwin-arm64": "0.23.0",
700
+ "@webpresso/agent-kit-runtime-darwin-x64": "0.23.0",
701
+ "@webpresso/agent-kit-runtime-linux-x64": "0.23.0",
702
+ "@webpresso/agent-kit-runtime-linux-arm64": "0.23.0",
703
+ "@webpresso/agent-kit-runtime-windows-x64": "0.23.0"
704
+ }
676
705
  }
@@ -16,10 +16,11 @@ description: Methodology for refining, fact-checking, and hardening implementati
16
16
  >
17
17
  > Blueprint hardening and lifecycle infrastructure are production-ready:
18
18
  >
19
- > - Kahn's Algorithm DAG analysis (fully tested)
20
- > - `ParallelExecutor` concurrency engine with abort, timeout, per-type limits
21
- > - Blueprint dependency format and validation
22
- > - Failed tasks block dependents automatically
19
+ > - Blueprint dependency parsing, format validation, and the lifecycle state
20
+ > machine with evidence-gated task completion (fully tested, in-package)
21
+ > - Parallel execution is delegated to the `/pll` runtime adapter (OMX), which
22
+ > batches independent tasks by dependency order and blocks dependents of
23
+ > failed tasks
23
24
  >
24
25
  > **Remaining gaps:** execution docs and wrappers must stay aligned with the currently shipped runtime and CLI surface.
25
26
 
@@ -81,5 +81,6 @@ When no explicit task list is supplied, ground lane selection in `wp blueprint l
81
81
  ```bash
82
82
  /pll "lint auth, lint utils, typecheck api [depends: lint auth], test api [depends: typecheck api]"
83
83
  /pll tasks.md --max=6
84
+ /pll blueprints/in-progress/new-launch.md
84
85
  /pll blueprints/in-progress/new-launch/_overview.md
85
86
  ```
@@ -1,12 +0,0 @@
1
- export declare class CycleDetector {
2
- private edges;
3
- private visited;
4
- private recStack;
5
- private path;
6
- private cycles;
7
- constructor(edges: Map<string, Set<string>>);
8
- detect(nodes: IterableIterator<string>): string[][] | null;
9
- private dfs;
10
- private processNeighbor;
11
- }
12
- //# sourceMappingURL=cycle-detector.d.ts.map
@@ -1,46 +0,0 @@
1
- export class CycleDetector {
2
- edges;
3
- visited = new Set();
4
- recStack = new Set();
5
- path = [];
6
- cycles = [];
7
- constructor(edges) {
8
- this.edges = edges;
9
- }
10
- detect(nodes) {
11
- for (const nodeId of nodes) {
12
- if (!this.visited.has(nodeId) && this.dfs(nodeId)) {
13
- return this.cycles;
14
- }
15
- }
16
- return this.cycles.length > 0 ? this.cycles : null;
17
- }
18
- dfs(nodeId) {
19
- this.visited.add(nodeId);
20
- this.recStack.add(nodeId);
21
- this.path.push(nodeId);
22
- const edges = this.edges.get(nodeId);
23
- if (edges) {
24
- for (const neighbor of edges) {
25
- if (this.processNeighbor(neighbor))
26
- return true;
27
- }
28
- }
29
- this.path.pop();
30
- this.recStack.delete(nodeId);
31
- return false;
32
- }
33
- processNeighbor(neighbor) {
34
- if (!this.visited.has(neighbor)) {
35
- if (this.dfs(neighbor))
36
- return true;
37
- }
38
- else if (this.recStack.has(neighbor)) {
39
- const cycleStart = this.path.indexOf(neighbor);
40
- this.cycles.push([...this.path.slice(cycleStart), neighbor]);
41
- return true;
42
- }
43
- return false;
44
- }
45
- }
46
- //# sourceMappingURL=cycle-detector.js.map