@webpresso/agent-kit 0.21.5 → 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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +87 -124
- package/bin/_run.js +143 -1
- package/bin/runtime-manifest.json +40 -0
- package/catalog/AGENTS.md.tpl +7 -6
- package/catalog/agent/commands/plan-refine.md +3 -3
- package/catalog/agent/commands/pll.md +2 -0
- package/catalog/agent/guides/parallel-execution.md +2 -0
- package/catalog/agent/rules/extraction-parity.md +27 -1
- package/catalog/agent/rules/public-package-safety.md +24 -1
- package/catalog/agent/skills/pll/SKILL.md +1 -0
- package/catalog/base-kit/.github/workflows/ci.webpresso.yml.tmpl +33 -0
- package/catalog/base-kit/stryker.config.ts.tmpl +2 -2
- package/catalog/docs/templates/blueprint.md +1 -0
- package/catalog/docs/templates/blueprint.yaml +10 -12
- package/commands/blueprint.md +8 -43
- package/dist/esm/audit/blueprint-db-consistency.d.ts +1 -1
- package/dist/esm/audit/blueprint-db-consistency.js +6 -8
- package/dist/esm/audit/blueprint-lifecycle-sql.js +10 -3
- package/dist/esm/audit/cloudflare-deploy-contract.d.ts +3 -0
- package/dist/esm/audit/cloudflare-deploy-contract.js +64 -0
- package/dist/esm/audit/no-legacy-cli-bin.d.ts +3 -0
- package/dist/esm/audit/no-legacy-cli-bin.js +100 -0
- package/dist/esm/audit/package-surface.js +14 -1
- package/dist/esm/audit/repo-guardrails.js +40 -13
- package/dist/esm/audit/roadmap-links.js +23 -10
- package/dist/esm/blueprint/core/schema.d.ts +8 -8
- package/dist/esm/blueprint/core/schema.js +2 -2
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/db/ingester.js +18 -10
- package/dist/esm/blueprint/lifecycle/audit.js +9 -2
- package/dist/esm/blueprint/lifecycle/local.js +15 -4
- package/dist/esm/blueprint/service/BlueprintCreationService.js +11 -6
- package/dist/esm/blueprint/service/BlueprintService.js +37 -19
- package/dist/esm/blueprint/service/scanner.js +73 -9
- package/dist/esm/blueprint/tracked-document/schema.d.ts +2 -2
- package/dist/esm/blueprint/utils/document-paths.d.ts +23 -0
- package/dist/esm/blueprint/utils/document-paths.js +91 -0
- package/dist/esm/build/package-manifest.js +7 -0
- package/dist/esm/build/release-policy.d.ts +27 -0
- package/dist/esm/build/release-policy.js +29 -0
- package/dist/esm/build/runtime-targets.d.ts +13 -0
- package/dist/esm/build/runtime-targets.js +48 -0
- package/dist/esm/cli/auto-update/detect-pm.d.ts +15 -0
- package/dist/esm/cli/auto-update/detect-pm.js +24 -9
- package/dist/esm/cli/auto-update/skip.js +9 -1
- package/dist/esm/cli/bundle/agent-command-inventory.d.ts +120 -0
- package/dist/esm/cli/bundle/agent-command-inventory.js +100 -0
- package/dist/esm/cli/bundle/index.d.ts +17 -0
- package/dist/esm/cli/bundle/index.js +15 -0
- package/dist/esm/cli/cli.d.ts +1 -1
- package/dist/esm/cli/cli.js +49 -5
- package/dist/esm/cli/commands/audit-core.d.ts +1 -1
- package/dist/esm/cli/commands/audit.js +2 -0
- package/dist/esm/cli/commands/blueprint/router.js +11 -8
- package/dist/esm/cli/commands/hook.d.ts +8 -0
- package/dist/esm/cli/commands/hook.js +47 -0
- package/dist/esm/cli/commands/init/index.js +35 -1
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +1 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/codex-ownership.js +9 -1
- package/dist/esm/cli/commands/init/scaffolders/agent-hooks/index.js +130 -20
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.d.ts +65 -0
- package/dist/esm/cli/commands/init/scaffolders/agent-kit-global/index.js +64 -0
- package/dist/esm/cli/commands/package-manager.d.ts +15 -0
- package/dist/esm/cli/commands/package-manager.js +42 -0
- package/dist/esm/cli/commands/test.d.ts +1 -0
- package/dist/esm/cli/commands/test.js +2 -1
- package/dist/esm/cli/commands/typecheck.js +5 -20
- package/dist/esm/cli/package-scripts.d.ts +12 -0
- package/dist/esm/cli/package-scripts.js +59 -0
- package/dist/esm/cli/utils.js +3 -22
- package/dist/esm/cli/wp-extensions.d.ts +14 -0
- package/dist/esm/cli/wp-extensions.js +34 -0
- package/dist/esm/config/docs-lint/schemas/common.d.ts +1 -1
- package/dist/esm/config/docs-lint/schemas/implementation-plan.d.ts +2 -2
- package/dist/esm/config/docs-lint/schemas/parent-roadmap.d.ts +1 -1
- package/dist/esm/config/stryker/index.d.ts +85 -0
- package/dist/esm/config/stryker/index.js +31 -0
- package/dist/esm/e2e/command-builder.js +11 -2
- package/dist/esm/e2e/config.d.ts +56 -0
- package/dist/esm/e2e/config.js +114 -0
- package/dist/esm/e2e/execution.js +4 -0
- package/dist/esm/e2e/run-planner.js +1 -0
- package/dist/esm/e2e/types.d.ts +2 -0
- package/dist/esm/format/index.js +1 -3
- package/dist/esm/hooks/guard-switch/index.d.ts +1 -1
- package/dist/esm/hooks/guard-switch/index.js +22 -14
- package/dist/esm/hooks/post-tool/lint-after-edit.d.ts +1 -0
- package/dist/esm/hooks/post-tool/lint-after-edit.js +5 -2
- package/dist/esm/hooks/pretool-guard/validators/file-conventions.js +1 -1
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.d.ts +6 -0
- package/dist/esm/hooks/pretool-guard/validators/forbidden-commands.js +27 -2
- package/dist/esm/hooks/pretool-guard/validators/path-contract.d.ts +2 -1
- package/dist/esm/hooks/pretool-guard/validators/path-contract.js +59 -34
- package/dist/esm/hooks/pretool-guard/validators/plan-frontmatter.js +3 -3
- package/dist/esm/hooks/shared/routing-block.js +18 -4
- package/dist/esm/hooks/shared/validators/blueprint.js +3 -0
- package/dist/esm/hooks/stop/qa-changed-files.d.ts +1 -0
- package/dist/esm/hooks/stop/qa-changed-files.js +5 -2
- package/dist/esm/lint/index.js +1 -1
- package/dist/esm/mcp/auto-discover.d.ts +2 -0
- package/dist/esm/mcp/auto-discover.js +14 -6
- package/dist/esm/mcp/blueprint-server.js +30 -26
- package/dist/esm/mcp/cli.js +21 -0
- package/dist/esm/mcp/runners/test.js +15 -0
- package/dist/esm/mcp/server.d.ts +7 -0
- package/dist/esm/mcp/server.js +16 -27
- package/dist/esm/mcp/tools/_registry.d.ts +3 -0
- package/dist/esm/mcp/tools/_registry.js +21 -0
- package/dist/esm/mcp/tools/audit.d.ts +1 -0
- package/dist/esm/mcp/tools/audit.js +11 -0
- package/dist/esm/mcp/tools/e2e.d.ts +1 -1
- package/dist/esm/mcp/tools/typecheck.js +4 -2
- package/dist/esm/mutation/affected.d.ts +9 -0
- package/dist/esm/mutation/affected.js +36 -0
- package/dist/esm/package.json +5 -0
- package/dist/esm/runtime/package-version.d.ts +2 -0
- package/dist/esm/runtime/package-version.js +43 -0
- package/dist/esm/test/command-builder.d.ts +3 -0
- package/dist/esm/test/command-builder.js +22 -3
- package/dist/esm/tool-runtime/index.d.ts +2 -2
- package/dist/esm/tool-runtime/index.js +2 -1
- package/dist/esm/tool-runtime/resolve-runner.d.ts +3 -0
- package/dist/esm/tool-runtime/resolve-runner.js +7 -5
- package/dist/esm/typecheck/index.js +4 -2
- package/dist/esm/wp-extension/index.d.ts +50 -0
- package/dist/esm/wp-extension/index.js +268 -0
- package/package.json +67 -31
- package/skills/pll/SKILL.md +1 -0
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { resolveRunner, } from './resolve-runner.js';
|
|
2
2
|
const runtimeCache = new Map();
|
|
3
3
|
function cacheKey(tool, options) {
|
|
4
|
+
const outputPolicy = options.outputPolicy ?? (options.filterOutput === false ? 'structured' : 'rtk-filtered');
|
|
4
5
|
return JSON.stringify({
|
|
5
6
|
tool,
|
|
6
|
-
|
|
7
|
+
outputPolicy,
|
|
7
8
|
fallbackCommand: options.fallbackCommand ?? null,
|
|
8
9
|
fallbackArgs: options.fallbackArgs ?? [],
|
|
9
10
|
});
|
|
@@ -4,10 +4,13 @@ export interface ManagedRunnerResolution {
|
|
|
4
4
|
readonly args: readonly string[];
|
|
5
5
|
readonly source: 'managed' | 'fallback';
|
|
6
6
|
}
|
|
7
|
+
export type ManagedRunnerOutputPolicy = 'rtk-filtered' | 'structured';
|
|
7
8
|
export interface ResolveRunnerOptions {
|
|
8
9
|
readonly fallbackCommand?: string;
|
|
9
10
|
readonly fallbackArgs?: readonly string[];
|
|
11
|
+
/** @deprecated Use {@link outputPolicy} for explicit output routing. */
|
|
10
12
|
readonly filterOutput?: boolean;
|
|
13
|
+
readonly outputPolicy?: ManagedRunnerOutputPolicy;
|
|
11
14
|
}
|
|
12
15
|
export declare function resolveRunner(tool: string, options?: ResolveRunnerOptions): ManagedRunnerResolution;
|
|
13
16
|
//# sourceMappingURL=resolve-runner.d.ts.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
const MANAGED_TOOL_PREFIX = {
|
|
2
|
+
oxfmt: { command: 'vp', args: ['exec', 'oxfmt'] },
|
|
2
3
|
playwright: { command: 'vp', args: ['exec', 'playwright'] },
|
|
4
|
+
tsc: { command: 'vp', args: ['exec', 'tsc'] },
|
|
3
5
|
vitest: { command: 'vp', args: ['exec', 'vitest'] },
|
|
4
6
|
vp: { command: 'vp', args: [] },
|
|
5
7
|
};
|
|
6
|
-
function withOptionalRtk(resolution,
|
|
7
|
-
if (
|
|
8
|
+
function withOptionalRtk(resolution, outputPolicy) {
|
|
9
|
+
if (outputPolicy !== 'rtk-filtered')
|
|
8
10
|
return resolution;
|
|
9
11
|
return {
|
|
10
12
|
...resolution,
|
|
@@ -17,7 +19,7 @@ export function resolveRunner(tool, options = {}) {
|
|
|
17
19
|
if (!normalized) {
|
|
18
20
|
throw new Error('tool runtime resolution requires a non-empty tool name');
|
|
19
21
|
}
|
|
20
|
-
const
|
|
22
|
+
const outputPolicy = options.outputPolicy ?? (options.filterOutput === false ? 'structured' : 'rtk-filtered');
|
|
21
23
|
const managed = MANAGED_TOOL_PREFIX[normalized];
|
|
22
24
|
if (managed) {
|
|
23
25
|
return withOptionalRtk({
|
|
@@ -25,7 +27,7 @@ export function resolveRunner(tool, options = {}) {
|
|
|
25
27
|
command: managed.command,
|
|
26
28
|
args: [...managed.args],
|
|
27
29
|
source: 'managed',
|
|
28
|
-
},
|
|
30
|
+
}, outputPolicy);
|
|
29
31
|
}
|
|
30
32
|
if (options.fallbackCommand) {
|
|
31
33
|
return withOptionalRtk({
|
|
@@ -33,7 +35,7 @@ export function resolveRunner(tool, options = {}) {
|
|
|
33
35
|
command: options.fallbackCommand,
|
|
34
36
|
args: [...(options.fallbackArgs ?? [])],
|
|
35
37
|
source: 'fallback',
|
|
36
|
-
},
|
|
38
|
+
}, outputPolicy);
|
|
37
39
|
}
|
|
38
40
|
throw new Error(`No managed runtime runner is defined for tool "${normalized}"`);
|
|
39
41
|
}
|
|
@@ -12,6 +12,7 @@ import { join } from 'node:path';
|
|
|
12
12
|
import { globSync } from 'glob';
|
|
13
13
|
import { isRunFailure, runCommand } from '#mcp/tools/_shared/run-command';
|
|
14
14
|
import { resolveProjectRoot } from '#mcp/tools/_shared/project-root';
|
|
15
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
15
16
|
const DEFAULT_TYPECHECK_TIMEOUT_MS = 10 * 60 * 1_000;
|
|
16
17
|
// Matches both standard tsc formats:
|
|
17
18
|
// src/foo.ts(5,12): error TS2304: Cannot find name 'bar'.
|
|
@@ -99,11 +100,12 @@ export async function runTypecheck(options = {}) {
|
|
|
99
100
|
const targets = options.packages && options.packages.length > 0 ? options.packages : null;
|
|
100
101
|
const workspaceGlobs = targets ? readWorkspaceGlobs(cwd) : null;
|
|
101
102
|
const runs = [];
|
|
103
|
+
const resolution = getManagedRunner('tsc', { outputPolicy: 'structured' });
|
|
102
104
|
if (targets) {
|
|
103
105
|
for (const pkg of targets) {
|
|
104
106
|
const resolvedTarget = resolveTypecheckTarget(cwd, pkg, workspaceGlobs);
|
|
105
107
|
const tsconfig = join(resolvedTarget, 'tsconfig.json');
|
|
106
|
-
const outcome = await runCommand(
|
|
108
|
+
const outcome = await runCommand(resolution.command, [...resolution.args, '--noEmit', '-p', tsconfig], runOptions);
|
|
107
109
|
if (isRunFailure(outcome)) {
|
|
108
110
|
throw outcome.error;
|
|
109
111
|
}
|
|
@@ -111,7 +113,7 @@ export async function runTypecheck(options = {}) {
|
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
else {
|
|
114
|
-
const outcome = await runCommand(
|
|
116
|
+
const outcome = await runCommand(resolution.command, [...resolution.args, '--noEmit'], runOptions);
|
|
115
117
|
if (isRunFailure(outcome)) {
|
|
116
118
|
throw outcome.error;
|
|
117
119
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { CAC } from 'cac';
|
|
2
|
+
export interface WpExtensionContext {
|
|
3
|
+
readonly cwd: string;
|
|
4
|
+
readonly env: NodeJS.ProcessEnv;
|
|
5
|
+
}
|
|
6
|
+
export interface WpExtensionCommandV1 {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly description: string;
|
|
9
|
+
readonly register: (cli: CAC) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface WpExtensionAliasV1 {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly commandName: string;
|
|
14
|
+
}
|
|
15
|
+
export interface WpExtensionV1 {
|
|
16
|
+
readonly apiVersion: '1';
|
|
17
|
+
readonly name: string;
|
|
18
|
+
readonly version: string;
|
|
19
|
+
readonly hostRange: string;
|
|
20
|
+
readonly detect: (context: WpExtensionContext) => boolean | Promise<boolean>;
|
|
21
|
+
readonly commands: readonly WpExtensionCommandV1[];
|
|
22
|
+
readonly aliases?: readonly WpExtensionAliasV1[];
|
|
23
|
+
}
|
|
24
|
+
export interface LoadedWpExtension {
|
|
25
|
+
readonly packageName: string;
|
|
26
|
+
readonly specifier: string;
|
|
27
|
+
readonly extension?: WpExtensionV1;
|
|
28
|
+
readonly compatible: boolean;
|
|
29
|
+
readonly detected: boolean;
|
|
30
|
+
readonly warnings: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
export interface WpExtensionAliasResolution {
|
|
33
|
+
readonly aliases: ReadonlyMap<string, WpExtensionAliasV1>;
|
|
34
|
+
readonly warnings: readonly string[];
|
|
35
|
+
readonly acceptedCommandNames: readonly string[];
|
|
36
|
+
}
|
|
37
|
+
export interface LoadWpExtensionsOptions {
|
|
38
|
+
readonly cwd?: string;
|
|
39
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
40
|
+
readonly hostVersion: string;
|
|
41
|
+
readonly importModule?: (specifier: string) => Promise<{
|
|
42
|
+
default?: unknown;
|
|
43
|
+
}>;
|
|
44
|
+
readonly resolveFrom?: (fromFile: string, specifier: string) => string;
|
|
45
|
+
readonly readJsonFile?: (path: string) => unknown;
|
|
46
|
+
}
|
|
47
|
+
export declare function loadWpExtensions(options: LoadWpExtensionsOptions): Promise<readonly LoadedWpExtension[]>;
|
|
48
|
+
export declare function resolveAcceptedExtensionAliases(extensions: readonly LoadedWpExtension[], baseCommands: Iterable<string>, acceptedCommandNames: Iterable<string>): WpExtensionAliasResolution;
|
|
49
|
+
export declare function isWpExtensionV1(value: unknown): value is WpExtensionV1;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -116,6 +116,11 @@
|
|
|
116
116
|
"#tool-runtime": "./src/tool-runtime/index.ts",
|
|
117
117
|
"#tool-runtime/*.js": "./src/tool-runtime/*.ts",
|
|
118
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",
|
|
119
124
|
"#output-transforms/*.js": "./src/output-transforms/*.ts",
|
|
120
125
|
"#output-transforms/*": "./src/output-transforms/*.ts",
|
|
121
126
|
"#lint/*.js": "./src/lint/*.ts",
|
|
@@ -164,6 +169,12 @@
|
|
|
164
169
|
"default": "./dist/esm/index.js"
|
|
165
170
|
}
|
|
166
171
|
},
|
|
172
|
+
"./bundle": {
|
|
173
|
+
"import": {
|
|
174
|
+
"types": "./dist/esm/cli/bundle/index.d.ts",
|
|
175
|
+
"default": "./dist/esm/cli/bundle/index.js"
|
|
176
|
+
}
|
|
177
|
+
},
|
|
167
178
|
"./blueprint": {
|
|
168
179
|
"import": {
|
|
169
180
|
"types": "./dist/esm/blueprint/index.d.ts",
|
|
@@ -303,6 +314,12 @@
|
|
|
303
314
|
"default": "./dist/esm/config/stryker/index.js"
|
|
304
315
|
}
|
|
305
316
|
},
|
|
317
|
+
"./mutation": {
|
|
318
|
+
"import": {
|
|
319
|
+
"types": "./dist/esm/mutation/affected.d.ts",
|
|
320
|
+
"default": "./dist/esm/mutation/affected.js"
|
|
321
|
+
}
|
|
322
|
+
},
|
|
306
323
|
"./oxlint": {
|
|
307
324
|
"import": {
|
|
308
325
|
"types": "./dist/esm/config/oxlint/index.d.ts",
|
|
@@ -453,6 +470,12 @@
|
|
|
453
470
|
"default": "./dist/esm/typecheck/index.js"
|
|
454
471
|
}
|
|
455
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
|
+
},
|
|
456
479
|
"./vite": {
|
|
457
480
|
"import": {
|
|
458
481
|
"types": "./dist/esm/vite/index.d.ts",
|
|
@@ -505,6 +528,8 @@
|
|
|
505
528
|
"scripts": {
|
|
506
529
|
"setup:agent": "wp setup",
|
|
507
530
|
"build": "tshy && vp run chmod-bins && vp run link-self-bins",
|
|
531
|
+
"build:runtime-binaries": "bun scripts/build-runtime-binaries.ts",
|
|
532
|
+
"stage:plugin-runtime": "bun scripts/stage-plugin-runtime-artifacts.ts",
|
|
508
533
|
"postbuild": "vp run generate-skills && vp run sync-doc-templates",
|
|
509
534
|
"chmod-bins": "bun scripts/chmod-bins.ts",
|
|
510
535
|
"link-self-bins": "bun scripts/link-self-bins.ts",
|
|
@@ -516,45 +541,46 @@
|
|
|
516
541
|
"sync-marketplace-version": "bun scripts/sync-marketplace-version.ts",
|
|
517
542
|
"version": "changeset version && vp run sync-marketplace-version",
|
|
518
543
|
"release:publish": "bun scripts/release-publish.ts",
|
|
519
|
-
"typecheck": "
|
|
520
|
-
"test": "vitest run --exclude '**/*.integration.test.ts' && vitest run --no-file-parallelism .integration.test.ts",
|
|
521
|
-
"test:unit": "vitest run --exclude '**/*.integration.test.ts'",
|
|
522
|
-
"test:integration": "vitest run --no-file-parallelism .integration.test.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",
|
|
523
548
|
"test:mutation": "bun stryker run stryker.config.ts",
|
|
524
549
|
"eval": "bun src/runners/evals/index.ts",
|
|
525
|
-
"lint": "
|
|
526
|
-
"lint:fix": "
|
|
527
|
-
"format": "
|
|
528
|
-
"format:check": "
|
|
550
|
+
"lint": "wp lint",
|
|
551
|
+
"lint:fix": "wp lint --fix",
|
|
552
|
+
"format": "wp format",
|
|
553
|
+
"format:check": "wp format --check",
|
|
529
554
|
"lint:pkg": "publint && attw --pack . && (command -v claude >/dev/null 2>&1 && claude plugin validate . || true)",
|
|
530
|
-
"blueprints:check": "
|
|
531
|
-
"docs:check": "
|
|
532
|
-
"catalog:check": "
|
|
533
|
-
"license:check": "
|
|
534
|
-
"imports:check": "
|
|
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",
|
|
535
560
|
"verify:secrets": "bun scripts/check-no-dev-vars.ts",
|
|
536
561
|
"audit:secret-provider-quarantine": "bun scripts/audit-secret-provider-quarantine.ts",
|
|
562
|
+
"workflow-actions:check": "bun scripts/check-workflow-action-pins.ts",
|
|
537
563
|
"public:consumer-smoke": "bun scripts/public-consumer-smoke.ts",
|
|
538
564
|
"public:readiness": "bun scripts/public-readiness.ts",
|
|
539
|
-
"audits:check": "
|
|
540
|
-
"hooks:doctor": "
|
|
541
|
-
"hooks:doctor:ci": "
|
|
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",
|
|
542
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",
|
|
543
569
|
"changeset": "changeset",
|
|
544
570
|
"changeset:status": "changeset status",
|
|
545
|
-
"verify:paths": "
|
|
571
|
+
"verify:paths": "wp audit absolute-path-policy --root .",
|
|
546
572
|
"prepare": "husky"
|
|
547
573
|
},
|
|
548
574
|
"dependencies": {
|
|
549
|
-
"@vitejs/plugin-react": "^6.0.1",
|
|
550
575
|
"@manypkg/find-root": "^3.1.0",
|
|
551
576
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
552
|
-
"
|
|
577
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
578
|
+
"better-sqlite3": "^12.10.0",
|
|
553
579
|
"cac": "^7.0.0",
|
|
554
580
|
"env-paths": "^4.0.0",
|
|
555
581
|
"glob": "^13.0.6",
|
|
556
582
|
"gray-matter": "^4.0.3",
|
|
557
|
-
"js-yaml": "^4.1.
|
|
583
|
+
"js-yaml": "^4.1.1",
|
|
558
584
|
"ora": "^8.2.0",
|
|
559
585
|
"proper-lockfile": "^4.1.2",
|
|
560
586
|
"remark": "^15.0.1",
|
|
@@ -562,8 +588,8 @@
|
|
|
562
588
|
"remark-validate-links": "^13.1.0",
|
|
563
589
|
"rulesync": "8.15.1",
|
|
564
590
|
"ts-pattern": "^5.9.0",
|
|
565
|
-
"vite-plus": "^0.1.
|
|
566
|
-
"yaml": "^2.
|
|
591
|
+
"vite-plus": "^0.1.22",
|
|
592
|
+
"yaml": "^2.9.0",
|
|
567
593
|
"zod": "^4.4.3",
|
|
568
594
|
"zod-to-json-schema": "^3.25.2"
|
|
569
595
|
},
|
|
@@ -575,18 +601,18 @@
|
|
|
575
601
|
"@stryker-mutator/typescript-checker": "^9.6.1",
|
|
576
602
|
"@stryker-mutator/vitest-runner": "^9.6.1",
|
|
577
603
|
"@types/better-sqlite3": "^7.6.13",
|
|
578
|
-
"@types/bun": "^1.
|
|
604
|
+
"@types/bun": "^1.3.14",
|
|
579
605
|
"@types/js-yaml": "^4.0.9",
|
|
580
|
-
"@types/node": "^25.
|
|
581
|
-
"husky": "^9.
|
|
606
|
+
"@types/node": "^25.9.1",
|
|
607
|
+
"husky": "^9.1.7",
|
|
582
608
|
"oxfmt": "^0.48.0",
|
|
583
|
-
"oxlint": "^1.
|
|
584
|
-
"publint": "^0.3.
|
|
609
|
+
"oxlint": "^1.67.0",
|
|
610
|
+
"publint": "^0.3.21",
|
|
585
611
|
"secretlint": "^13.0.2",
|
|
586
612
|
"tshy": "^4.1.2",
|
|
587
613
|
"typescript": "^6.0.3",
|
|
588
|
-
"vite": "^8.0.
|
|
589
|
-
"vitest": "^4.1.
|
|
614
|
+
"vite": "^8.0.14",
|
|
615
|
+
"vitest": "^4.1.7",
|
|
590
616
|
"webpresso": "latest"
|
|
591
617
|
},
|
|
592
618
|
"tshy": {
|
|
@@ -602,6 +628,7 @@
|
|
|
602
628
|
],
|
|
603
629
|
"exports": {
|
|
604
630
|
".": "./src/index.ts",
|
|
631
|
+
"./bundle": "./src/cli/bundle/index.ts",
|
|
605
632
|
"./blueprint": "./src/blueprint/index.ts",
|
|
606
633
|
"./blueprint/local": "./src/blueprint/local.ts",
|
|
607
634
|
"./blueprint/tech-debt": "./src/blueprint/tech-debt/index.ts",
|
|
@@ -626,6 +653,7 @@
|
|
|
626
653
|
"./vitest/react-setup.ts": "./src/config/vitest/react-setup.ts",
|
|
627
654
|
"./vitest/flakiness-reporter": "./src/config/vitest/flakiness-reporter.ts",
|
|
628
655
|
"./stryker": "./src/config/stryker/index.ts",
|
|
656
|
+
"./mutation": "./src/mutation/affected.ts",
|
|
629
657
|
"./oxlint": "./src/config/oxlint/index.ts",
|
|
630
658
|
"./oxlint/import-hygiene": "./src/config/oxlint/import-hygiene.ts",
|
|
631
659
|
"./oxlint/monorepo-paths": "./src/config/oxlint/monorepo-paths.ts",
|
|
@@ -651,6 +679,7 @@
|
|
|
651
679
|
"./symlinker": "./src/symlinker/index.ts",
|
|
652
680
|
"./test": "./src/test/index.ts",
|
|
653
681
|
"./typecheck": "./src/typecheck/index.ts",
|
|
682
|
+
"./wp-extension": "./src/wp-extension/index.ts",
|
|
654
683
|
"./vite": "./src/vite/index.ts",
|
|
655
684
|
"./vite/local": "./src/vite/local.ts",
|
|
656
685
|
"./ai-memory": "./src/ai-memory/index.ts",
|
|
@@ -665,5 +694,12 @@
|
|
|
665
694
|
"engines": {
|
|
666
695
|
"node": ">=24"
|
|
667
696
|
},
|
|
668
|
-
"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
|
+
}
|
|
669
705
|
}
|
package/skills/pll/SKILL.md
CHANGED
|
@@ -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
|
```
|