@webpresso/agent-kit 0.21.5 → 0.24.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 +80 -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 +65 -0
- package/dist/esm/e2e/config.js +126 -0
- package/dist/esm/e2e/execution.js +4 -0
- package/dist/esm/e2e/load-host-adapter.d.ts +6 -1
- package/dist/esm/e2e/load-host-adapter.js +27 -9
- 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
|
@@ -8,6 +8,7 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
8
8
|
<description>
|
|
9
9
|
Use the wp_* MCP tools for all test, lint, typecheck, qa, audit, local CI act,
|
|
10
10
|
and Cloudflare Worker tail operations.
|
|
11
|
+
If a wp_* MCP tool is stale or unavailable, use the matching wp CLI command.
|
|
11
12
|
If context-mode plugin routing is present, let it own ctx_* data-processing nudges.
|
|
12
13
|
These tools return structured, summary-first results and keep output concise.
|
|
13
14
|
</description>
|
|
@@ -55,7 +56,7 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
55
56
|
<tool name="wp_test">
|
|
56
57
|
<category>dev-workflow</category>
|
|
57
58
|
<trigger>running tests, verifying test suite, check if tests pass</trigger>
|
|
58
|
-
<forbidden>just test, pnpm test, vitest</forbidden>
|
|
59
|
+
<forbidden>just test, pnpm test, vitest, npx vitest, npm exec -- vitest, yarn vitest, bunx vitest, node ./node_modules/vitest/vitest.mjs</forbidden>
|
|
59
60
|
</tool>
|
|
60
61
|
<tool name="wp_e2e">
|
|
61
62
|
<category>dev-workflow</category>
|
|
@@ -65,12 +66,12 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
65
66
|
<tool name="wp_lint">
|
|
66
67
|
<category>dev-workflow</category>
|
|
67
68
|
<trigger>linting, code style checks, lint errors</trigger>
|
|
68
|
-
<forbidden>just lint, oxlint</forbidden>
|
|
69
|
+
<forbidden>just lint, oxlint, node ./node_modules/oxlint/bin/oxlint</forbidden>
|
|
69
70
|
</tool>
|
|
70
71
|
<tool name="wp_typecheck">
|
|
71
72
|
<category>dev-workflow</category>
|
|
72
73
|
<trigger>type checking, TypeScript errors, type errors</trigger>
|
|
73
|
-
<forbidden>tsc</forbidden>
|
|
74
|
+
<forbidden>tsc, node ./node_modules/typescript/bin/tsc</forbidden>
|
|
74
75
|
</tool>
|
|
75
76
|
<tool name="wp_qa">
|
|
76
77
|
<category>dev-workflow</category>
|
|
@@ -102,6 +103,11 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
102
103
|
<rule>Context-mode owns ctx_* routing when that plugin is installed.</rule>
|
|
103
104
|
</ownership_boundary>
|
|
104
105
|
|
|
106
|
+
<hook_diagnostics>
|
|
107
|
+
<rule>Prefer wp hook <name> over direct wp-<hook-bin> calls when a wp hook command exists.</rule>
|
|
108
|
+
<rule>Direct wp-* hook bins remain generated-hook runtime internals, not recommended agent diagnostics.</rule>
|
|
109
|
+
</hook_diagnostics>
|
|
110
|
+
|
|
105
111
|
<package_guidance>
|
|
106
112
|
<rule>Consumers add @webpresso/agent-kit and import config helpers through @webpresso/agent-kit/* subpath exports such as @webpresso/agent-kit/oxlint, @webpresso/agent-kit/vitest/node, @webpresso/agent-kit/test-preset, @webpresso/agent-kit/e2e-preset, @webpresso/agent-kit/tsconfig/base.json, @webpresso/agent-kit/docs-lint, @webpresso/agent-kit/stryker, @webpresso/agent-kit/launch, and @webpresso/agent-kit/workers-test.</rule>
|
|
107
113
|
<rule>Do not recommend adding retired split agent config packages for consumer projects; keep wp_* MCP tool names and wp-* hook bin names unchanged.</rule>
|
|
@@ -114,9 +120,16 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
114
120
|
<command>just qa</command>
|
|
115
121
|
<command>just lint-md</command>
|
|
116
122
|
<command>vitest</command>
|
|
123
|
+
<command>npx vitest</command>
|
|
124
|
+
<command>npm exec -- vitest</command>
|
|
125
|
+
<command>yarn vitest</command>
|
|
126
|
+
<command>bunx vitest</command>
|
|
127
|
+
<command>node ./node_modules/vitest/vitest.mjs</command>
|
|
117
128
|
<command>oxlint</command>
|
|
129
|
+
<command>node ./node_modules/oxlint/bin/oxlint</command>
|
|
118
130
|
<command>markdownlint-cli2</command>
|
|
119
131
|
<command>tsc</command>
|
|
132
|
+
<command>node ./node_modules/typescript/bin/tsc</command>
|
|
120
133
|
<command>act</command>
|
|
121
134
|
<command>vp exec act</command>
|
|
122
135
|
<command>pnpm exec act</command>
|
|
@@ -133,7 +146,8 @@ export const WP_ROUTING_BLOCK = `<wp_routing>
|
|
|
133
146
|
</output_format>
|
|
134
147
|
|
|
135
148
|
<fallback>
|
|
136
|
-
When MCP tools are unavailable, use
|
|
149
|
+
When MCP tools are unavailable or stale, use the matching wp CLI command and keep output brief.
|
|
150
|
+
Do not fall through to raw tool bins under node_modules when a wp wrapper exists.
|
|
137
151
|
.omx is runtime/state only; it is not a direct hook surface.
|
|
138
152
|
</fallback>
|
|
139
153
|
</wp_routing>`;
|
|
@@ -26,6 +26,9 @@ export function shouldSkipFile(filePath) {
|
|
|
26
26
|
if (!filePath)
|
|
27
27
|
return false;
|
|
28
28
|
const normalized = filePath.startsWith('/') ? filePath.slice(1) : filePath;
|
|
29
|
+
if (normalized.startsWith('blueprints/') || normalized.startsWith('webpresso/blueprints/')) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
29
32
|
return SKIP_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
30
33
|
}
|
|
31
34
|
export function getSkipReason(filePath) {
|
|
@@ -85,12 +85,15 @@ export function runQaChecks(qaFiles, projectDir) {
|
|
|
85
85
|
export function formatStopHookOutput(result) {
|
|
86
86
|
return JSON.stringify(result);
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
|
|
88
|
+
export async function main() {
|
|
90
89
|
runHook(
|
|
91
90
|
// `Stop` is latency-sensitive and user-visible. Until webpresso grows a
|
|
92
91
|
// deferred execution plane, broad typecheck/test sweeps stay off the hot
|
|
93
92
|
// path instead of shelling synchronously at turn end.
|
|
94
93
|
(_input) => null, formatStopHookOutput);
|
|
95
94
|
}
|
|
95
|
+
if (process.argv[1] &&
|
|
96
|
+
realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1])) {
|
|
97
|
+
void main();
|
|
98
|
+
}
|
|
96
99
|
//# sourceMappingURL=qa-changed-files.js.map
|
package/dist/esm/lint/index.js
CHANGED
|
@@ -93,7 +93,7 @@ export async function runLint(options = {}) {
|
|
|
93
93
|
else {
|
|
94
94
|
lintArgs.push('.');
|
|
95
95
|
}
|
|
96
|
-
const resolution = getManagedRunner('vp', {
|
|
96
|
+
const resolution = getManagedRunner('vp', { outputPolicy: 'structured' });
|
|
97
97
|
const vpOutcome = await runCommand(resolution.command, [...resolution.args, ...lintArgs], runOptions);
|
|
98
98
|
if (isRunFailure(vpOutcome)) {
|
|
99
99
|
return {
|
|
@@ -61,5 +61,7 @@ export interface ToolDescriptor {
|
|
|
61
61
|
export interface ToolRegistrar {
|
|
62
62
|
registerTool(name: string, description: string, jsonSchema: Record<string, unknown>, outputSchema: Record<string, unknown> | undefined, handler: ToolHandler, annotations?: ToolAnnotations): void;
|
|
63
63
|
}
|
|
64
|
+
export declare function registerToolDescriptor(server: ToolRegistrar, descriptor: ToolDescriptor): ToolDescriptor;
|
|
65
|
+
export declare function registerToolDescriptors(server: ToolRegistrar, descriptors: readonly ToolDescriptor[]): ToolDescriptor[];
|
|
64
66
|
export declare function discoverTools(server: ToolRegistrar, toolsDir: string): Promise<ToolDescriptor[]>;
|
|
65
67
|
//# sourceMappingURL=auto-discover.d.ts.map
|
|
@@ -15,9 +15,20 @@ import { extname, join } from 'node:path';
|
|
|
15
15
|
import { pathToFileURL } from 'node:url';
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
18
|
+
export function registerToolDescriptor(server, descriptor) {
|
|
19
|
+
const jsonSchema = toJsonSchema(descriptor.inputSchema);
|
|
20
|
+
const outputSchema = descriptor.outputSchema ? toJsonSchema(descriptor.outputSchema) : undefined;
|
|
21
|
+
server.registerTool(descriptor.name, descriptor.description, jsonSchema, outputSchema, descriptor.handler, descriptor.annotations);
|
|
22
|
+
return descriptor;
|
|
23
|
+
}
|
|
24
|
+
export function registerToolDescriptors(server, descriptors) {
|
|
25
|
+
return descriptors.map((descriptor) => registerToolDescriptor(server, descriptor));
|
|
26
|
+
}
|
|
18
27
|
const SKIP_SUFFIXES = ['.test.ts', '.test.js', '.integration.test.ts', '.integration.test.js'];
|
|
19
28
|
const SUPPORTED_EXTENSIONS = new Set(['.ts', '.js', '.mjs', '.cjs']);
|
|
20
29
|
function shouldSkip(file) {
|
|
30
|
+
if (file.startsWith('_'))
|
|
31
|
+
return true;
|
|
21
32
|
if (file.endsWith('.d.ts') || file.endsWith('.d.ts.map'))
|
|
22
33
|
return true;
|
|
23
34
|
if (file.endsWith('.js.map') || file.endsWith('.ts.map'))
|
|
@@ -82,7 +93,7 @@ function toJsonSchema(schema) {
|
|
|
82
93
|
}
|
|
83
94
|
export async function discoverTools(server, toolsDir) {
|
|
84
95
|
const entries = await readdir(toolsDir, { withFileTypes: true });
|
|
85
|
-
const
|
|
96
|
+
const loaded = [];
|
|
86
97
|
for (const entry of entries) {
|
|
87
98
|
if (!entry.isFile())
|
|
88
99
|
continue;
|
|
@@ -98,11 +109,8 @@ export async function discoverTools(server, toolsDir) {
|
|
|
98
109
|
if (typeof descriptor.name !== 'string' || typeof descriptor.handler !== 'function') {
|
|
99
110
|
throw new Error(`Tool file ${fullPath} default export is malformed (missing name or handler)`);
|
|
100
111
|
}
|
|
101
|
-
|
|
102
|
-
const outputSchema = descriptor.outputSchema ? toJsonSchema(descriptor.outputSchema) : undefined;
|
|
103
|
-
server.registerTool(descriptor.name, descriptor.description, jsonSchema, outputSchema, descriptor.handler, descriptor.annotations);
|
|
104
|
-
registered.push(descriptor);
|
|
112
|
+
loaded.push(descriptor);
|
|
105
113
|
}
|
|
106
|
-
return
|
|
114
|
+
return registerToolDescriptors(server, loaded);
|
|
107
115
|
}
|
|
108
116
|
//# sourceMappingURL=auto-discover.js.map
|
|
@@ -23,6 +23,7 @@ import { openDb } from '#db/connection.js';
|
|
|
23
23
|
import { resolveBlueprintProjectionDbPath } from '#db/paths.js';
|
|
24
24
|
import { findTemplate } from '#db/templates.js';
|
|
25
25
|
import { resolveBlueprintRoot } from '#utils/blueprint-root.js';
|
|
26
|
+
import { getBlueprintDocumentPaths } from '#utils/document-paths.js';
|
|
26
27
|
import { evidenceListSchema, canonicalizeEvidenceList } from '#evidence.js';
|
|
27
28
|
import { checkFreshness, readCurrentHead, readProjectionMetadata } from '#freshness.js';
|
|
28
29
|
import { applyVerification, assertAllTasksHaveCanonicalPassingEvidence, readTaskVerification, } from '#verification.js';
|
|
@@ -251,10 +252,10 @@ async function reIngest(cwd) {
|
|
|
251
252
|
await reIngestProjection(cwd);
|
|
252
253
|
}
|
|
253
254
|
async function persistBlueprintMarkdown(input) {
|
|
254
|
-
const { projectCwd, slug,
|
|
255
|
-
mkdirSync(path.dirname(
|
|
255
|
+
const { projectCwd, slug, blueprintPath, markdown } = input;
|
|
256
|
+
mkdirSync(path.dirname(blueprintPath), { recursive: true });
|
|
256
257
|
parseBlueprint(markdown, slug);
|
|
257
|
-
writeFileSync(
|
|
258
|
+
writeFileSync(blueprintPath, markdown, 'utf8');
|
|
258
259
|
await reIngest(projectCwd);
|
|
259
260
|
const refreshed = getCurrentProjectBlueprint(projectCwd, slug);
|
|
260
261
|
if (!refreshed.blueprint) {
|
|
@@ -264,9 +265,11 @@ async function persistBlueprintMarkdown(input) {
|
|
|
264
265
|
}
|
|
265
266
|
function findBlueprintDir(blueprintRoot, slug, states) {
|
|
266
267
|
for (const state of states) {
|
|
267
|
-
const
|
|
268
|
-
if (existsSync(
|
|
269
|
-
return { dir:
|
|
268
|
+
const paths = getBlueprintDocumentPaths(blueprintRoot, state, slug);
|
|
269
|
+
if (existsSync(paths.flat))
|
|
270
|
+
return { dir: path.dirname(paths.flat), path: paths.flat, shape: 'flat', state };
|
|
271
|
+
if (existsSync(paths.directory))
|
|
272
|
+
return { dir: paths.directory, path: paths.folder, shape: 'folder', state };
|
|
270
273
|
}
|
|
271
274
|
return null;
|
|
272
275
|
}
|
|
@@ -557,7 +560,7 @@ async function handleNew(cwd, raw) {
|
|
|
557
560
|
}
|
|
558
561
|
const b = bytes(template);
|
|
559
562
|
const slug = titleToSlug(title);
|
|
560
|
-
const targetPath =
|
|
563
|
+
const targetPath = getBlueprintDocumentPaths(resolveBlueprintRoot(cwd), 'draft', slug).flat;
|
|
561
564
|
// Platform-first path: push event to register the blueprint before returning the scaffold.
|
|
562
565
|
// Iron rule: resolveSyncAdapter() returns null when WP_BLUEPRINT_PLATFORM_DISABLED=1.
|
|
563
566
|
const adapter = await resolveSyncAdapter(cwd);
|
|
@@ -886,7 +889,7 @@ async function handleTaskVerify(projectResolver, cwd, raw) {
|
|
|
886
889
|
if (!found) {
|
|
887
890
|
return err('wp_blueprint_task_verify failed', `Blueprint "${slug}" not found in any state directory`);
|
|
888
891
|
}
|
|
889
|
-
const filePath =
|
|
892
|
+
const filePath = found.path;
|
|
890
893
|
if (!existsSync(filePath)) {
|
|
891
894
|
return err('wp_blueprint_task_verify failed', `Blueprint overview not found at ${filePath}`);
|
|
892
895
|
}
|
|
@@ -981,8 +984,8 @@ async function handlePromote(projectResolver, cwd, raw) {
|
|
|
981
984
|
const found = findBlueprintDir(root, slug, ALL_STATES);
|
|
982
985
|
if (!found)
|
|
983
986
|
return err('wp_blueprint_promote failed', `Blueprint "${slug}" not found in any state directory`);
|
|
984
|
-
const {
|
|
985
|
-
const overviewPath = path
|
|
987
|
+
const { state: currentState } = found;
|
|
988
|
+
const overviewPath = found.path;
|
|
986
989
|
if (to_state === 'completed') {
|
|
987
990
|
try {
|
|
988
991
|
assertBlueprintCanComplete(overviewPath, slug);
|
|
@@ -1085,7 +1088,7 @@ async function handleFinalize(projectResolver, cwd, raw) {
|
|
|
1085
1088
|
return err('wp_blueprint_finalize failed', `Blueprint "${slug}" not found`);
|
|
1086
1089
|
}
|
|
1087
1090
|
try {
|
|
1088
|
-
assertBlueprintCanComplete(
|
|
1091
|
+
assertBlueprintCanComplete(found.path, slug);
|
|
1089
1092
|
}
|
|
1090
1093
|
catch (error) {
|
|
1091
1094
|
return err('wp_blueprint_finalize refused', toStr(error));
|
|
@@ -1807,14 +1810,14 @@ async function handleBlueprintPut(projectResolver, cwd, raw) {
|
|
|
1807
1810
|
return err('wp_blueprint_put refused', `New blueprint "${slug}" must start in "draft"; use wp_blueprint_transition for later lifecycle moves.`);
|
|
1808
1811
|
}
|
|
1809
1812
|
const overviewPath = found
|
|
1810
|
-
?
|
|
1811
|
-
:
|
|
1813
|
+
? found.path
|
|
1814
|
+
: getBlueprintDocumentPaths(root, document.status, slug).flat;
|
|
1812
1815
|
try {
|
|
1813
1816
|
const markdown = renderBlueprintMarkdownFromDocument(slug, document);
|
|
1814
1817
|
const blueprint = await persistBlueprintMarkdown({
|
|
1815
1818
|
projectCwd,
|
|
1816
1819
|
slug,
|
|
1817
|
-
overviewPath,
|
|
1820
|
+
blueprintPath: overviewPath,
|
|
1818
1821
|
markdown,
|
|
1819
1822
|
});
|
|
1820
1823
|
const payload = {
|
|
@@ -1904,7 +1907,7 @@ async function handleBlueprintTransition(projectResolver, cwd, raw) {
|
|
|
1904
1907
|
async function applyLocalBlueprintTransition(input) {
|
|
1905
1908
|
const { projectCwd, slug, to_state, found } = input;
|
|
1906
1909
|
const root = resolveBlueprintRoot(projectCwd);
|
|
1907
|
-
const overviewPath =
|
|
1910
|
+
const overviewPath = found.path;
|
|
1908
1911
|
const parsed = runValidate(overviewPath);
|
|
1909
1912
|
if (!parsed.valid) {
|
|
1910
1913
|
throw new Error(parsed.gaps.join('; '));
|
|
@@ -1918,13 +1921,15 @@ async function applyLocalBlueprintTransition(input) {
|
|
|
1918
1921
|
progress: formatBlueprintProgress(currentBlueprint.tasks.length, currentBlueprint.tasks.filter((task) => task.status === 'done').length, currentBlueprint.tasks.filter((task) => task.status === 'blocked').length),
|
|
1919
1922
|
});
|
|
1920
1923
|
parseBlueprint(updated, slug);
|
|
1921
|
-
const
|
|
1922
|
-
mkdirSync(path.dirname(
|
|
1924
|
+
const destination = getBlueprintDocumentPaths(root, to_state, slug);
|
|
1925
|
+
mkdirSync(path.dirname(found.shape === 'flat' ? destination.flat : destination.directory), {
|
|
1926
|
+
recursive: true,
|
|
1927
|
+
});
|
|
1923
1928
|
let finalOverviewPath = overviewPath;
|
|
1924
1929
|
if (found.state !== to_state) {
|
|
1925
1930
|
const { renameSync } = await import('node:fs');
|
|
1926
|
-
renameSync(found.dir,
|
|
1927
|
-
finalOverviewPath =
|
|
1931
|
+
renameSync(found.shape === 'flat' ? overviewPath : found.dir, found.shape === 'flat' ? destination.flat : destination.directory);
|
|
1932
|
+
finalOverviewPath = found.shape === 'flat' ? destination.flat : destination.folder;
|
|
1928
1933
|
}
|
|
1929
1934
|
writeFileSync(finalOverviewPath, updated, 'utf8');
|
|
1930
1935
|
await reIngest(projectCwd);
|
|
@@ -1960,10 +1965,9 @@ async function handleBlueprintCreate(projectResolver, cwd, raw) {
|
|
|
1960
1965
|
const today = new Date().toISOString().split('T')[0] ?? '';
|
|
1961
1966
|
const slug = titleToSlug(title);
|
|
1962
1967
|
const root = resolveBlueprintRoot(projectCwd);
|
|
1963
|
-
const
|
|
1964
|
-
const overviewPath = path.join(targetDir, '_overview.md');
|
|
1968
|
+
const overviewPath = getBlueprintDocumentPaths(root, 'draft', slug).flat;
|
|
1965
1969
|
try {
|
|
1966
|
-
mkdirSync(
|
|
1970
|
+
mkdirSync(path.dirname(overviewPath), { recursive: true });
|
|
1967
1971
|
const content = BLUEPRINT_TEMPLATE.replace(/{TITLE}/g, title)
|
|
1968
1972
|
.replace(/{COMPLEXITY}/g, complexity)
|
|
1969
1973
|
.replace(/{DATE}/g, today)
|
|
@@ -1971,7 +1975,7 @@ async function handleBlueprintCreate(projectResolver, cwd, raw) {
|
|
|
1971
1975
|
await persistBlueprintMarkdown({
|
|
1972
1976
|
projectCwd,
|
|
1973
1977
|
slug,
|
|
1974
|
-
overviewPath,
|
|
1978
|
+
blueprintPath: overviewPath,
|
|
1975
1979
|
markdown: content,
|
|
1976
1980
|
});
|
|
1977
1981
|
const b = bytes(content);
|
|
@@ -2083,12 +2087,12 @@ export async function registerBlueprintTools(registrar, cwd, projectResolver = c
|
|
|
2083
2087
|
next_action: nextActionOutputSchema,
|
|
2084
2088
|
},
|
|
2085
2089
|
}, (r) => handleBlueprintTransition(projectResolver, cwd, r), { title: 'Blueprint Transition', destructiveHint: false, openWorldHint: false });
|
|
2086
|
-
registrar.registerTool('wp_blueprint_validate', 'Validate _overview.md
|
|
2090
|
+
registrar.registerTool('wp_blueprint_validate', 'Validate canonical blueprint markdown structure (`<slug>.md` or `<slug>/_overview.md`). Returns { valid, gaps }. Must pass before wp_blueprint_promote.', { type: 'object', properties: { path: { type: 'string' } }, required: ['path'] }, undefined, (r) => handleValidate(cwd, r), { title: 'Blueprint Validate', readOnlyHint: false, openWorldHint: false });
|
|
2087
2091
|
registrar.registerTool('wp_blueprint_task_next', 'Return the next ready task (all deps done). Accepts optional project_id for nested-workspace disambiguation. Returns { summary, task }.', {
|
|
2088
2092
|
type: 'object',
|
|
2089
2093
|
properties: { blueprint: { type: 'string' }, project_id: { type: 'string' } },
|
|
2090
2094
|
}, undefined, (r) => handleTaskNext(projectResolver, cwd, r), { title: 'Blueprint Task Next', readOnlyHint: true, openWorldHint: false });
|
|
2091
|
-
registrar.registerTool('wp_blueprint_task_advance', 'Advance task status. Edits
|
|
2095
|
+
registrar.registerTool('wp_blueprint_task_advance', 'Advance task status. Edits the canonical blueprint markdown and re-syncs DB. Accepts optional request_id for idempotent retries and optional head_at_ingest from wp_blueprint_get/wp_blueprint_list to reject stale writes. Returns { summary, old_status, new_status, idempotent }.', {
|
|
2092
2096
|
type: 'object',
|
|
2093
2097
|
properties: {
|
|
2094
2098
|
project_id: { type: 'string' },
|
|
@@ -2206,7 +2210,7 @@ export async function registerBlueprintTools(registrar, cwd, projectResolver = c
|
|
|
2206
2210
|
},
|
|
2207
2211
|
required: [...summaryEnvelopeOutputSchema.required, 'chunks', 'total_bytes', 'project_id'],
|
|
2208
2212
|
}, (r) => handleBlueprintContext(projectResolver, cwd, r), { title: 'Blueprint Context', readOnlyHint: true, openWorldHint: false });
|
|
2209
|
-
registrar.registerTool('wp_blueprint_create', 'Create a new blueprint markdown under blueprints/draft/<slug>/_overview.md and re-ingest. Accepts optional request_id for idempotent retries and optional head_at_ingest from wp_blueprint_projects/wp_blueprint_list to reject stale writes. Returns { slug, path, next_action, idempotent }.', {
|
|
2213
|
+
registrar.registerTool('wp_blueprint_create', 'Create a new blueprint markdown under blueprints/draft/<slug>.md by default (folder-shaped `<slug>/_overview.md` remains supported elsewhere) and re-ingest. Accepts optional request_id for idempotent retries and optional head_at_ingest from wp_blueprint_projects/wp_blueprint_list to reject stale writes. Returns { slug, path, next_action, idempotent }.', {
|
|
2210
2214
|
type: 'object',
|
|
2211
2215
|
properties: {
|
|
2212
2216
|
project_id: { type: 'string' },
|
package/dist/esm/mcp/cli.js
CHANGED
|
@@ -12,18 +12,26 @@ import { createServer } from './server.js';
|
|
|
12
12
|
export async function runStdioServer() {
|
|
13
13
|
const server = await createServer();
|
|
14
14
|
const transport = new StdioServerTransport();
|
|
15
|
+
const settle = Promise.withResolvers();
|
|
15
16
|
let shuttingDown = false;
|
|
16
17
|
const shutdown = async () => {
|
|
17
18
|
if (shuttingDown)
|
|
18
19
|
return;
|
|
19
20
|
shuttingDown = true;
|
|
20
21
|
deleteSentinel();
|
|
22
|
+
try {
|
|
23
|
+
await transport.close();
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
/* ignore transport close errors during shutdown */
|
|
27
|
+
}
|
|
21
28
|
try {
|
|
22
29
|
await server.close();
|
|
23
30
|
}
|
|
24
31
|
catch {
|
|
25
32
|
/* ignore close errors during shutdown */
|
|
26
33
|
}
|
|
34
|
+
settle.resolve();
|
|
27
35
|
};
|
|
28
36
|
process.on('SIGINT', () => {
|
|
29
37
|
void shutdown().then(() => process.exit(0));
|
|
@@ -31,8 +39,21 @@ export async function runStdioServer() {
|
|
|
31
39
|
process.on('SIGTERM', () => {
|
|
32
40
|
void shutdown().then(() => process.exit(0));
|
|
33
41
|
});
|
|
42
|
+
process.stdin.on('end', () => {
|
|
43
|
+
void shutdown();
|
|
44
|
+
});
|
|
45
|
+
process.stdin.on('close', () => {
|
|
46
|
+
void shutdown();
|
|
47
|
+
});
|
|
48
|
+
transport.onclose = () => {
|
|
49
|
+
void shutdown();
|
|
50
|
+
};
|
|
51
|
+
transport.onerror = () => {
|
|
52
|
+
void shutdown();
|
|
53
|
+
};
|
|
34
54
|
await server.connect(transport);
|
|
35
55
|
writeSentinel();
|
|
56
|
+
await settle.promise;
|
|
36
57
|
}
|
|
37
58
|
import { realpathSync } from 'node:fs';
|
|
38
59
|
import { fileURLToPath } from 'node:url';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { globSync } from 'glob';
|
|
4
|
+
import { getPackageScript, isRecursiveWpScript, packageUsesVitest } from '#cli/package-scripts.js';
|
|
4
5
|
import { isRunFailure, runCommand as runSharedCommand } from '#mcp/tools/_shared/run-command';
|
|
5
6
|
// Keep the runner's own deadline comfortably below common MCP client call
|
|
6
7
|
// ceilings so slow suites fail fast with a structured `timedOut` payload
|
|
@@ -55,6 +56,14 @@ export async function runTests(input) {
|
|
|
55
56
|
if (workspaceShardRuns && workspaceShardRuns.length > 0) {
|
|
56
57
|
return runScopedSequence(cwd, workspaceShardRuns, input, workspaceSharding);
|
|
57
58
|
}
|
|
59
|
+
if (shouldBypassWorkspaceTestScript(cwd)) {
|
|
60
|
+
const result = await runCommand('vp', ['exec', '--', 'vitest', 'run', '--reporter=json', '--no-color'], {
|
|
61
|
+
...input,
|
|
62
|
+
cwd,
|
|
63
|
+
timeoutMs: commandTimeoutMs,
|
|
64
|
+
});
|
|
65
|
+
return withFailureScope(result, 'workspace vitest command');
|
|
66
|
+
}
|
|
58
67
|
const result = await runCommand('vp', ['run', 'test'], {
|
|
59
68
|
...input,
|
|
60
69
|
cwd,
|
|
@@ -222,6 +231,12 @@ function hasRootVitestTestScript(cwd) {
|
|
|
222
231
|
const testScript = scripts.test;
|
|
223
232
|
return typeof testScript === 'string' && /\bvitest\b/.test(testScript);
|
|
224
233
|
}
|
|
234
|
+
function shouldBypassWorkspaceTestScript(cwd) {
|
|
235
|
+
const testScript = getPackageScript(cwd, 'test');
|
|
236
|
+
if (!testScript || !isRecursiveWpScript(testScript, 'test'))
|
|
237
|
+
return false;
|
|
238
|
+
return packageUsesVitest(cwd);
|
|
239
|
+
}
|
|
225
240
|
function discoverVitestFiles(cwd) {
|
|
226
241
|
return globSync(VITEST_DEFAULT_INCLUDE, {
|
|
227
242
|
cwd,
|
package/dist/esm/mcp/server.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* — no edits required here.
|
|
8
8
|
*/
|
|
9
9
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
export type ToolLoadMode = 'filesystem' | 'registry';
|
|
10
11
|
export interface CreateServerOptions {
|
|
11
12
|
/**
|
|
12
13
|
* Directory to scan for tool descriptors. Defaults to `./tools` relative to
|
|
@@ -14,6 +15,12 @@ export interface CreateServerOptions {
|
|
|
14
15
|
* `vp run build`.
|
|
15
16
|
*/
|
|
16
17
|
toolsDir?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Tool loading strategy. Use `registry` for compiled runtime execution where
|
|
20
|
+
* runtime directory scans are unsafe, and `filesystem` for dev/test disk
|
|
21
|
+
* discovery.
|
|
22
|
+
*/
|
|
23
|
+
toolLoadMode?: ToolLoadMode;
|
|
17
24
|
/**
|
|
18
25
|
* Repo working directory passed through to the blueprint structured-store
|
|
19
26
|
* registrar (Task 2.1). Defaults to `process.cwd()`. Tests inject a tmpdir.
|
package/dist/esm/mcp/server.js
CHANGED
|
@@ -8,42 +8,25 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
10
|
import { CallToolRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListResourceTemplatesRequestSchema, ListToolsRequestSchema, RootsListChangedNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
12
11
|
import { dirname, join } from 'node:path';
|
|
13
12
|
import { fileURLToPath } from 'node:url';
|
|
14
|
-
import { discoverTools, } from './auto-discover.js';
|
|
13
|
+
import { discoverTools, registerToolDescriptors, } from './auto-discover.js';
|
|
15
14
|
import { registerBlueprintServer } from './blueprint-server.js';
|
|
15
|
+
import { COMPILED_TOOL_REGISTRY } from './tools/_registry.js';
|
|
16
|
+
import { readOwnedPackageVersion } from '#runtime/package-version.js';
|
|
16
17
|
const SERVER_NAME = 'webpresso';
|
|
17
|
-
|
|
18
|
-
// for both src/mcp/server.ts (dev) and dist/esm/mcp/server.js (built) without
|
|
19
|
-
// hardcoding asymmetric `../../..` counts.
|
|
20
|
-
const MAX_UPWARD_LEVELS = 8;
|
|
21
|
-
function readPackageVersion() {
|
|
22
|
-
let dir = dirname(fileURLToPath(import.meta.url));
|
|
23
|
-
for (let i = 0; i < MAX_UPWARD_LEVELS; i++) {
|
|
24
|
-
const candidate = join(dir, 'package.json');
|
|
25
|
-
if (existsSync(candidate)) {
|
|
26
|
-
const pkg = JSON.parse(readFileSync(candidate, 'utf-8'));
|
|
27
|
-
// Some build outputs emit a marker `package.json` (e.g. `{ "type": "module" }`)
|
|
28
|
-
// without a version. Skip those and keep walking so we land on the real
|
|
29
|
-
// package root, instead of throwing the moment we see any package.json.
|
|
30
|
-
if (typeof pkg.version === 'string' && pkg.version.length > 0)
|
|
31
|
-
return pkg.version;
|
|
32
|
-
}
|
|
33
|
-
const parent = dirname(dir);
|
|
34
|
-
if (parent === dir)
|
|
35
|
-
break;
|
|
36
|
-
dir = parent;
|
|
37
|
-
}
|
|
38
|
-
throw new Error('Cannot locate a versioned package.json relative to webpresso MCP server module');
|
|
39
|
-
}
|
|
40
|
-
const SERVER_VERSION = readPackageVersion();
|
|
18
|
+
const SERVER_VERSION = readOwnedPackageVersion(import.meta.url);
|
|
41
19
|
function defaultToolsDir() {
|
|
42
20
|
// import.meta.url resolves to either src/mcp/server.ts (dev/test via vitest)
|
|
43
21
|
// or dist/esm/mcp/server.js (built). The tools directory is colocated.
|
|
44
22
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
45
23
|
return join(here, 'tools');
|
|
46
24
|
}
|
|
25
|
+
function resolveDefaultToolLoadMode() {
|
|
26
|
+
return process.env.WP_MCP_TOOL_MODE === 'registry' || process.env.WP_COMPILED_RUNTIME === '1'
|
|
27
|
+
? 'registry'
|
|
28
|
+
: 'filesystem';
|
|
29
|
+
}
|
|
47
30
|
export async function createServer(options = {}) {
|
|
48
31
|
const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, {
|
|
49
32
|
capabilities: {
|
|
@@ -60,7 +43,13 @@ export async function createServer(options = {}) {
|
|
|
60
43
|
tools.set(name, { name, description, inputSchema, outputSchema, handler, annotations });
|
|
61
44
|
},
|
|
62
45
|
};
|
|
63
|
-
|
|
46
|
+
const toolLoadMode = options.toolLoadMode ?? resolveDefaultToolLoadMode();
|
|
47
|
+
if (toolLoadMode === 'registry') {
|
|
48
|
+
registerToolDescriptors(registrar, COMPILED_TOOL_REGISTRY);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await discoverTools(registrar, options.toolsDir ?? defaultToolsDir());
|
|
52
|
+
}
|
|
64
53
|
// Task 2.1: register the blueprint structured-store tools AFTER auto-discover
|
|
65
54
|
// so any tool-name collision surfaces here as a thrown error rather than
|
|
66
55
|
// silent shadowing. Roots are looked up lazily via `server.listRoots()`; the
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import audit from './audit.js';
|
|
2
|
+
import ciAct from './ci-act.js';
|
|
3
|
+
import e2e from './e2e.js';
|
|
4
|
+
import format from './format.js';
|
|
5
|
+
import lint from './lint.js';
|
|
6
|
+
import qa from './qa.js';
|
|
7
|
+
import test from './test.js';
|
|
8
|
+
import typecheck from './typecheck.js';
|
|
9
|
+
import workerTail from './worker-tail.js';
|
|
10
|
+
export const COMPILED_TOOL_REGISTRY = [
|
|
11
|
+
audit,
|
|
12
|
+
ciAct,
|
|
13
|
+
e2e,
|
|
14
|
+
format,
|
|
15
|
+
lint,
|
|
16
|
+
qa,
|
|
17
|
+
test,
|
|
18
|
+
typecheck,
|
|
19
|
+
workerTail,
|
|
20
|
+
];
|
|
21
|
+
//# sourceMappingURL=_registry.js.map
|
|
@@ -32,6 +32,7 @@ declare const inputSchema: z.ZodObject<{
|
|
|
32
32
|
"catalog-drift": "catalog-drift";
|
|
33
33
|
"package-surface": "package-surface";
|
|
34
34
|
"architecture-drift": "architecture-drift";
|
|
35
|
+
"cloudflare-deploy-contract": "cloudflare-deploy-contract";
|
|
35
36
|
"absolute-path-policy": "absolute-path-policy";
|
|
36
37
|
"ai-contracts": "ai-contracts";
|
|
37
38
|
}>;
|
|
@@ -28,6 +28,7 @@ const KINDS = [
|
|
|
28
28
|
'docs-frontmatter',
|
|
29
29
|
'blueprint-lifecycle',
|
|
30
30
|
'architecture-drift',
|
|
31
|
+
'cloudflare-deploy-contract',
|
|
31
32
|
'absolute-path-policy',
|
|
32
33
|
'roadmap-links',
|
|
33
34
|
'bundle-budget',
|
|
@@ -155,6 +156,16 @@ async function dispatch(input) {
|
|
|
155
156
|
details: auditResult,
|
|
156
157
|
};
|
|
157
158
|
}
|
|
159
|
+
case 'cloudflare-deploy-contract': {
|
|
160
|
+
const { auditCloudflareDeployContract } = await import('#audit/cloudflare-deploy-contract');
|
|
161
|
+
const auditResult = await auditCloudflareDeployContract(input.cwd ?? input.directory ?? process.cwd());
|
|
162
|
+
return {
|
|
163
|
+
passed: auditResult.ok,
|
|
164
|
+
summary: summarizeRepoAudit(kind, auditResult),
|
|
165
|
+
kind,
|
|
166
|
+
details: auditResult,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
158
169
|
case 'absolute-path-policy': {
|
|
159
170
|
const { auditAbsolutePathPolicy } = await import('#audit/absolute-path-policy');
|
|
160
171
|
const auditResult = auditAbsolutePathPolicy(input.cwd ?? input.directory ?? process.cwd());
|
|
@@ -12,8 +12,8 @@ declare const inputSchema: z.ZodObject<{
|
|
|
12
12
|
suite: z.ZodOptional<z.ZodString>;
|
|
13
13
|
runner: z.ZodOptional<z.ZodEnum<{
|
|
14
14
|
command: "command";
|
|
15
|
-
vitest: "vitest";
|
|
16
15
|
playwright: "playwright";
|
|
16
|
+
vitest: "vitest";
|
|
17
17
|
}>>;
|
|
18
18
|
config: z.ZodOptional<z.ZodString>;
|
|
19
19
|
files: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
@@ -14,6 +14,7 @@ import { join } from 'node:path';
|
|
|
14
14
|
import { globSync } from 'glob';
|
|
15
15
|
import { z } from 'zod';
|
|
16
16
|
import { applyOutputTransform } from '#output-transforms/index';
|
|
17
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
17
18
|
import { resolveProjectRoot } from './_shared/project-root.js';
|
|
18
19
|
import { createSummaryOutputSchema, createSummaryResult } from './_shared/result.js';
|
|
19
20
|
import { isRunFailure, runCommand } from './_shared/run-command.js';
|
|
@@ -143,11 +144,12 @@ const tool = {
|
|
|
143
144
|
// current resolution treats each entry as a relative path either way.
|
|
144
145
|
const workspaceGlobs = targets ? readWorkspaceGlobs(cwd) : null;
|
|
145
146
|
const runs = [];
|
|
147
|
+
const resolution = getManagedRunner('tsc', { outputPolicy: 'structured' });
|
|
146
148
|
if (targets) {
|
|
147
149
|
for (const pkg of targets) {
|
|
148
150
|
const resolvedTarget = resolveTypecheckTarget(cwd, pkg, workspaceGlobs);
|
|
149
151
|
const tsconfig = join(resolvedTarget, 'tsconfig.json');
|
|
150
|
-
const outcome = await runCommand(
|
|
152
|
+
const outcome = await runCommand(resolution.command, [...resolution.args, '--noEmit', '-p', tsconfig], runOptions);
|
|
151
153
|
if (isRunFailure(outcome)) {
|
|
152
154
|
throw outcome.error;
|
|
153
155
|
}
|
|
@@ -155,7 +157,7 @@ const tool = {
|
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
159
|
else {
|
|
158
|
-
const outcome = await runCommand(
|
|
160
|
+
const outcome = await runCommand(resolution.command, [...resolution.args, '--noEmit'], runOptions);
|
|
159
161
|
if (isRunFailure(outcome)) {
|
|
160
162
|
throw outcome.error;
|
|
161
163
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run Stryker only on packages changed vs. the base branch.
|
|
3
|
+
* Returns 0 on success, 1 if any package fails its break threshold.
|
|
4
|
+
*
|
|
5
|
+
* Reads GITHUB_BASE_REF (set by GitHub Actions on pull_request events) to
|
|
6
|
+
* determine the base branch; falls back to "main".
|
|
7
|
+
*/
|
|
8
|
+
export declare function runAffectedMutation(): 0 | 1;
|
|
9
|
+
//# sourceMappingURL=affected.d.ts.map
|