@webpresso/agent-kit 0.21.3 → 0.21.5
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 +105 -41
- package/catalog/AGENTS.md.tpl +3 -1
- package/catalog/agent/rules/changeset-release.md +13 -16
- package/catalog/agent/skills/plan-refine/SKILL.md +5 -4
- package/catalog/base-kit/commitlint.config.ts.tmpl +1 -3
- package/catalog/base-kit/e2e/fixtures/smoke.html.tmpl +13 -0
- package/catalog/base-kit/e2e/smoke.spec.ts.tmpl +13 -0
- package/catalog/base-kit/oxlint.config.ts.tmpl +26 -0
- package/catalog/base-kit/playwright.config.ts.tmpl +10 -0
- package/catalog/base-kit/src/quality-sample.test.ts.tmpl +19 -0
- package/catalog/base-kit/src/quality-sample.ts.tmpl +11 -0
- package/catalog/base-kit/stryker.config.ts.tmpl +14 -0
- package/catalog/base-kit/tsconfig.json.tmpl +9 -0
- package/catalog/base-kit/vitest.config.ts.tmpl +10 -0
- package/catalog/docs/templates/adr.md +1 -1
- package/catalog/docs/templates/blueprint.md +1 -0
- package/catalog/docs/templates/blueprint.yaml +6 -3
- package/catalog/docs/templates/guide.md +1 -1
- package/catalog/docs/templates/postmortem.md +1 -1
- package/catalog/docs/templates/research.md +1 -1
- package/catalog/docs/templates/runbook.md +1 -1
- package/catalog/docs/templates/system.md +12 -3
- package/catalog/docs/templates/tech-debt.md +1 -0
- package/commands/blueprint.md +37 -4
- package/dist/esm/audit/resolve-audit-script.d.ts +24 -0
- package/dist/esm/audit/resolve-audit-script.js +27 -0
- package/dist/esm/blueprint/db/enums.d.ts +1 -1
- package/dist/esm/blueprint/index.d.ts +0 -1
- package/dist/esm/blueprint/index.js +0 -2
- package/dist/esm/blueprint/local.d.ts +0 -3
- package/dist/esm/blueprint/local.js +0 -2
- package/dist/esm/blueprint/service/BlueprintCreationService.js +5 -2
- package/dist/esm/blueprint/utils/package-assets.d.ts +11 -0
- package/dist/esm/blueprint/utils/package-assets.js +33 -4
- package/dist/esm/build/sync-catalog-doc-templates.d.ts +23 -0
- package/dist/esm/build/sync-catalog-doc-templates.js +93 -0
- package/dist/esm/cli/commands/audit.js +2 -7
- package/dist/esm/cli/commands/blueprint/router.js +5 -2
- package/dist/esm/cli/commands/blueprint/template-resolver.js +8 -4
- package/dist/esm/cli/commands/init/host-visibility.js +4 -2
- package/dist/esm/cli/commands/init/index.js +46 -7
- package/dist/esm/cli/commands/init/scaffold-base-kit.d.ts +12 -0
- package/dist/esm/cli/commands/init/scaffold-base-kit.js +141 -6
- package/dist/esm/cli/commands/typecheck.js +10 -4
- package/dist/esm/e2e/command-builder.js +26 -7
- package/dist/esm/e2e/execution.js +4 -0
- package/dist/esm/e2e/run-planner.js +1 -0
- package/dist/esm/e2e/types.d.ts +1 -0
- package/dist/esm/format/index.js +7 -1
- package/dist/esm/lint/index.js +3 -1
- package/dist/esm/mcp/blueprint-server.js +361 -66
- package/dist/esm/mcp/tools/audit.js +2 -8
- package/dist/esm/mcp/tools/e2e.d.ts +1 -1
- package/dist/esm/package.json +3 -0
- package/dist/esm/secret-gate/runner.js +4 -0
- package/dist/esm/test/command-builder.d.ts +1 -0
- package/dist/esm/test/command-builder.js +8 -2
- package/dist/esm/test-helpers/hermetic-env.d.ts +25 -0
- package/dist/esm/test-helpers/hermetic-env.js +31 -0
- package/dist/esm/tool-runtime/index.d.ts +5 -0
- package/dist/esm/tool-runtime/index.js +23 -0
- package/dist/esm/tool-runtime/resolve-runner.d.ts +13 -0
- package/dist/esm/tool-runtime/resolve-runner.js +40 -0
- package/package.json +12 -18
- package/skills/plan-refine/SKILL.md +5 -4
- package/dist/esm/blueprint/dag/cycle-detector.d.ts +0 -12
- package/dist/esm/blueprint/dag/cycle-detector.js +0 -46
- package/dist/esm/blueprint/dag/executor.d.ts +0 -140
- package/dist/esm/blueprint/dag/executor.js +0 -292
- package/dist/esm/blueprint/dag/index.d.ts +0 -20
- package/dist/esm/blueprint/dag/index.js +0 -17
- package/dist/esm/blueprint/dag/interfaces.d.ts +0 -56
- package/dist/esm/blueprint/dag/interfaces.js +0 -13
- package/dist/esm/blueprint/dag/local/independence.d.ts +0 -107
- package/dist/esm/blueprint/dag/local/independence.js +0 -231
- package/dist/esm/blueprint/dag/local/index.d.ts +0 -14
- package/dist/esm/blueprint/dag/local/index.js +0 -14
- package/dist/esm/blueprint/dag/local/package-graph.d.ts +0 -66
- package/dist/esm/blueprint/dag/local/package-graph.js +0 -148
- package/dist/esm/blueprint/dag/plan-parser.d.ts +0 -54
- package/dist/esm/blueprint/dag/plan-parser.js +0 -236
- package/dist/esm/blueprint/dag/task-graph-algorithms.d.ts +0 -13
- package/dist/esm/blueprint/dag/task-graph-algorithms.js +0 -236
- package/dist/esm/blueprint/dag/task-graph.d.ts +0 -171
- package/dist/esm/blueprint/dag/task-graph.js +0 -370
- package/dist/esm/blueprint/dag/types.d.ts +0 -17
- package/dist/esm/blueprint/dag/types.js +0 -2
- package/dist/esm/blueprint/graph/index.d.ts +0 -5
- package/dist/esm/blueprint/graph/index.js +0 -5
- package/dist/esm/blueprint/graph/mermaid-parser.d.ts +0 -3
- package/dist/esm/blueprint/graph/mermaid-parser.js +0 -93
- package/dist/esm/blueprint/graph/mermaid-serializer.d.ts +0 -3
- package/dist/esm/blueprint/graph/mermaid-serializer.js +0 -20
- package/dist/esm/blueprint/graph/schema.d.ts +0 -89
- package/dist/esm/blueprint/graph/schema.js +0 -104
- package/dist/esm/blueprint/graph/task-graph-adapter.d.ts +0 -6
- package/dist/esm/blueprint/graph/task-graph-adapter.js +0 -30
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { writeFileMerged } from './merge.js';
|
|
4
|
+
const AUTHORING_TIME_DEPENDENCIES = [
|
|
5
|
+
'vitest',
|
|
6
|
+
'@playwright/test',
|
|
7
|
+
'@testing-library/jest-dom',
|
|
8
|
+
'typescript',
|
|
9
|
+
];
|
|
10
|
+
const EXECUTION_ONLY_REVIEW_DEPENDENCIES = [
|
|
11
|
+
'oxlint',
|
|
12
|
+
'oxfmt',
|
|
13
|
+
'prettier',
|
|
14
|
+
'markdownlint-cli2',
|
|
15
|
+
'stryker',
|
|
16
|
+
];
|
|
17
|
+
export function collectRuntimeContractGuidance(packageJson) {
|
|
18
|
+
const deps = {
|
|
19
|
+
...readDependencyBucket(packageJson?.['dependencies']),
|
|
20
|
+
...readDependencyBucket(packageJson?.['devDependencies']),
|
|
21
|
+
};
|
|
22
|
+
const installed = new Set(Object.keys(deps));
|
|
23
|
+
return {
|
|
24
|
+
keepLocalAuthoringDeps: AUTHORING_TIME_DEPENDENCIES.filter((name) => installed.has(name)),
|
|
25
|
+
reviewForRemovalDeps: EXECUTION_ONLY_REVIEW_DEPENDENCIES.filter((name) => installed.has(name)),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
4
28
|
/** Template files relative to `catalog/base-kit/`, and their target paths relative to repoRoot. */
|
|
5
29
|
const TEMPLATE_MAP = [
|
|
6
30
|
['.editorconfig.tmpl', '.editorconfig'],
|
|
@@ -18,6 +42,19 @@ const TEMPLATE_MAP = [
|
|
|
18
42
|
['test/.gitkeep.tmpl', 'test/.gitkeep'],
|
|
19
43
|
['e2e/.gitkeep.tmpl', 'e2e/.gitkeep'],
|
|
20
44
|
];
|
|
45
|
+
/** Consumer-owned quality scaffold: create for fresh repos, never clobber. */
|
|
46
|
+
const QUALITY_BOOTSTRAP_ONLY_MAP = [
|
|
47
|
+
['tsconfig.json.tmpl', 'tsconfig.json'],
|
|
48
|
+
['vitest.config.ts.tmpl', 'vitest.config.ts'],
|
|
49
|
+
['oxlint.config.ts.tmpl', 'oxlint.config.ts'],
|
|
50
|
+
['stryker.config.ts.tmpl', 'stryker.config.ts'],
|
|
51
|
+
['playwright.config.ts.tmpl', 'playwright.config.ts'],
|
|
52
|
+
['src/quality-sample.ts.tmpl', 'src/quality-sample.ts'],
|
|
53
|
+
['src/quality-sample.test.ts.tmpl', 'src/quality-sample.test.ts'],
|
|
54
|
+
['e2e/fixtures/smoke.html.tmpl', 'e2e/fixtures/smoke.html'],
|
|
55
|
+
['e2e/smoke.spec.ts.tmpl', 'e2e/smoke.spec.ts'],
|
|
56
|
+
];
|
|
57
|
+
export const BASE_KIT_QUALITY_TARGETS = QUALITY_BOOTSTRAP_ONLY_MAP.map(([, targetRel]) => targetRel);
|
|
21
58
|
/**
|
|
22
59
|
* Bootstrap-only templates: the scaffolder writes them when absent (so a
|
|
23
60
|
* fresh repo gets sane defaults) but NEVER overwrites them once they exist
|
|
@@ -75,35 +112,85 @@ function mergePackageJson(repoRoot, options, globalInstall = false) {
|
|
|
75
112
|
const hasVerifySecrets = typeof scripts['verify:secrets'] === 'string';
|
|
76
113
|
const hasSecretQuarantineAudit = typeof scripts['audit:secret-provider-quarantine'] === 'string';
|
|
77
114
|
const hasPrepareScript = typeof scripts['prepare'] === 'string';
|
|
115
|
+
const hasLintScript = typeof scripts['lint'] === 'string';
|
|
116
|
+
const hasTypecheckScript = typeof scripts['typecheck'] === 'string';
|
|
117
|
+
const hasTestScript = typeof scripts['test'] === 'string' && !isNpmInitPlaceholderTestScript(scripts['test']);
|
|
118
|
+
const hasMutationScript = typeof scripts['mutation'] === 'string';
|
|
119
|
+
const hasTestMutationScript = typeof scripts['test:mutation'] === 'string';
|
|
120
|
+
const hasE2eScript = typeof scripts['e2e'] === 'string';
|
|
121
|
+
const hasQaScript = typeof scripts['qa'] === 'string';
|
|
78
122
|
const verifyPathsScript = 'WP_SKIP_UPDATE_CHECK=1 wp audit absolute-path-policy --root .';
|
|
79
123
|
const verifySecretsScript = 'bun scripts/check-no-dev-vars.ts';
|
|
80
124
|
const secretQuarantineAuditScript = 'bun scripts/audit-secret-provider-quarantine.ts';
|
|
125
|
+
const lintScript = 'wp lint src e2e *.config.ts';
|
|
126
|
+
const typecheckScript = 'wp typecheck';
|
|
127
|
+
const testScript = 'wp test --file vitest.config.ts';
|
|
128
|
+
const mutationScript = 'wp test --mutation';
|
|
129
|
+
const testMutationScript = 'stryker run stryker.config.ts';
|
|
130
|
+
const e2eScript = 'wp e2e --config playwright.config.ts';
|
|
131
|
+
const qaScript = [
|
|
132
|
+
'wp lint src e2e *.config.ts',
|
|
133
|
+
'wp typecheck',
|
|
134
|
+
'wp test --file vitest.config.ts',
|
|
135
|
+
'wp test --mutation',
|
|
136
|
+
'wp e2e --config playwright.config.ts',
|
|
137
|
+
].join(' && ');
|
|
81
138
|
const devDeps = (pkg['devDependencies'] ?? {});
|
|
82
|
-
const hasAgentKitDevDep = typeof devDeps['webpresso'] === 'string';
|
|
83
|
-
const
|
|
139
|
+
const hasAgentKitDevDep = typeof devDeps['@webpresso/agent-kit'] === 'string';
|
|
140
|
+
const hasLegacyAgentKitDevDep = typeof devDeps['webpresso'] === 'string';
|
|
141
|
+
const shouldSkipSelfInstall = packageName === '@webpresso/agent-kit' || packageName === 'webpresso';
|
|
84
142
|
const shouldManageAgentKitAsGlobal = globalInstall && !shouldSkipSelfInstall;
|
|
143
|
+
const requiredAuthoringDeps = {
|
|
144
|
+
'@playwright/test': 'latest',
|
|
145
|
+
'@stryker-mutator/core': 'latest',
|
|
146
|
+
'@stryker-mutator/vitest-runner': 'latest',
|
|
147
|
+
'@types/node': 'latest',
|
|
148
|
+
typescript: 'latest',
|
|
149
|
+
vitest: 'latest',
|
|
150
|
+
};
|
|
85
151
|
if (alreadyHasEngines &&
|
|
86
152
|
alreadyHasPm &&
|
|
87
|
-
(shouldSkipSelfInstall ||
|
|
153
|
+
(shouldSkipSelfInstall ||
|
|
154
|
+
shouldManageAgentKitAsGlobal ||
|
|
155
|
+
hasAgentKitDevDep ||
|
|
156
|
+
hasLegacyAgentKitDevDep) &&
|
|
157
|
+
Object.keys(requiredAuthoringDeps).every((name) => typeof devDeps[name] === 'string') &&
|
|
88
158
|
(shouldSkipSelfInstall || hasSetupAgent) &&
|
|
89
159
|
(shouldSkipSelfInstall || hasVerifyPaths) &&
|
|
90
160
|
(shouldSkipSelfInstall || hasVerifySecrets) &&
|
|
91
161
|
(shouldSkipSelfInstall || hasSecretQuarantineAudit) &&
|
|
92
|
-
(shouldSkipSelfInstall || hasPrepareScript)
|
|
162
|
+
(shouldSkipSelfInstall || hasPrepareScript) &&
|
|
163
|
+
hasLintScript &&
|
|
164
|
+
hasTypecheckScript &&
|
|
165
|
+
hasTestScript &&
|
|
166
|
+
hasMutationScript &&
|
|
167
|
+
hasTestMutationScript &&
|
|
168
|
+
hasE2eScript &&
|
|
169
|
+
hasQaScript) {
|
|
93
170
|
return { targetPath: pkgPath, action: 'identical' };
|
|
94
171
|
}
|
|
95
172
|
pkg['engines'] = { ...existing, node: engines.node };
|
|
96
173
|
if (!alreadyHasPm)
|
|
97
174
|
pkg['packageManager'] = packageManager;
|
|
175
|
+
if (typeof pkg['type'] !== 'string')
|
|
176
|
+
pkg['type'] = 'module';
|
|
98
177
|
// Ensure husky is in devDependencies so `vp exec husky init` works
|
|
99
178
|
if (!devDeps['husky']) {
|
|
100
179
|
devDeps['husky'] = '^9.0.0';
|
|
101
180
|
}
|
|
102
|
-
if (!shouldSkipSelfInstall &&
|
|
181
|
+
if (!shouldSkipSelfInstall &&
|
|
182
|
+
!shouldManageAgentKitAsGlobal &&
|
|
183
|
+
!hasAgentKitDevDep &&
|
|
184
|
+
!hasLegacyAgentKitDevDep) {
|
|
103
185
|
// Keep consumers on the currently published dist-tag rather than a
|
|
104
186
|
// repo-internal path. Do not wire this through `prepare`: `wp` is not
|
|
105
187
|
// reliably on PATH during `vp install`, so `setup:agent` stays opt-in.
|
|
106
|
-
devDeps['webpresso'] = 'latest';
|
|
188
|
+
devDeps['@webpresso/agent-kit'] = 'latest';
|
|
189
|
+
}
|
|
190
|
+
for (const [name, version] of Object.entries(requiredAuthoringDeps)) {
|
|
191
|
+
if (!devDeps[name]) {
|
|
192
|
+
devDeps[name] = version;
|
|
193
|
+
}
|
|
107
194
|
}
|
|
108
195
|
pkg['devDependencies'] = devDeps;
|
|
109
196
|
if (!shouldSkipSelfInstall && !hasSetupAgent) {
|
|
@@ -121,6 +208,27 @@ function mergePackageJson(repoRoot, options, globalInstall = false) {
|
|
|
121
208
|
if (!shouldSkipSelfInstall && !hasPrepareScript) {
|
|
122
209
|
scripts['prepare'] = 'husky';
|
|
123
210
|
}
|
|
211
|
+
if (!hasLintScript) {
|
|
212
|
+
scripts['lint'] = lintScript;
|
|
213
|
+
}
|
|
214
|
+
if (!hasTypecheckScript) {
|
|
215
|
+
scripts['typecheck'] = typecheckScript;
|
|
216
|
+
}
|
|
217
|
+
if (!hasTestScript) {
|
|
218
|
+
scripts['test'] = testScript;
|
|
219
|
+
}
|
|
220
|
+
if (!hasMutationScript) {
|
|
221
|
+
scripts['mutation'] = mutationScript;
|
|
222
|
+
}
|
|
223
|
+
if (!hasTestMutationScript) {
|
|
224
|
+
scripts['test:mutation'] = testMutationScript;
|
|
225
|
+
}
|
|
226
|
+
if (!hasE2eScript) {
|
|
227
|
+
scripts['e2e'] = e2eScript;
|
|
228
|
+
}
|
|
229
|
+
if (!hasQaScript) {
|
|
230
|
+
scripts['qa'] = qaScript;
|
|
231
|
+
}
|
|
124
232
|
if (Object.keys(scripts).length > 0) {
|
|
125
233
|
pkg['scripts'] = scripts;
|
|
126
234
|
}
|
|
@@ -161,6 +269,24 @@ export function scaffoldBaseKit(input) {
|
|
|
161
269
|
writeFileSync(targetPath, content);
|
|
162
270
|
results.push({ targetPath, action: 'created' });
|
|
163
271
|
}
|
|
272
|
+
for (const [tmplRel, targetRel] of QUALITY_BOOTSTRAP_ONLY_MAP) {
|
|
273
|
+
const tmplPath = join(baseKitDir, tmplRel);
|
|
274
|
+
if (!existsSync(tmplPath))
|
|
275
|
+
continue;
|
|
276
|
+
const targetPath = join(repoRoot, targetRel);
|
|
277
|
+
if (existsSync(targetPath)) {
|
|
278
|
+
results.push({ targetPath, action: 'identical' });
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const content = readFileSync(tmplPath, 'utf8');
|
|
282
|
+
if (options.dryRun) {
|
|
283
|
+
results.push({ targetPath, action: 'skipped-dry' });
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
287
|
+
writeFileSync(targetPath, content);
|
|
288
|
+
results.push({ targetPath, action: 'created' });
|
|
289
|
+
}
|
|
164
290
|
// Make husky hook files executable
|
|
165
291
|
if (!options.dryRun) {
|
|
166
292
|
for (const [tmplRel, targetRel] of TEMPLATE_MAP) {
|
|
@@ -180,4 +306,13 @@ export function scaffoldBaseKit(input) {
|
|
|
180
306
|
results.push(mergePackageJson(repoRoot, options, globalInstall));
|
|
181
307
|
return results;
|
|
182
308
|
}
|
|
309
|
+
function readDependencyBucket(value) {
|
|
310
|
+
if (!value || typeof value !== 'object') {
|
|
311
|
+
return {};
|
|
312
|
+
}
|
|
313
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[0] === 'string' && typeof entry[1] === 'string'));
|
|
314
|
+
}
|
|
315
|
+
function isNpmInitPlaceholderTestScript(value) {
|
|
316
|
+
return /^echo ['"]?Error: no test specified['"]? && exit 1$/u.test(value.trim());
|
|
317
|
+
}
|
|
183
318
|
//# sourceMappingURL=scaffold-base-kit.js.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
1
2
|
import { spawnSync } from 'node:child_process';
|
|
2
3
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -17,14 +18,19 @@ export function registerTypecheckCommand(cli) {
|
|
|
17
18
|
export function buildTypecheckCommand(options = {}) {
|
|
18
19
|
const cwd = options.cwd ?? process.cwd();
|
|
19
20
|
if (hasCheckTypesScript(cwd)) {
|
|
21
|
+
const resolution = getManagedRunner('vp');
|
|
20
22
|
return {
|
|
21
|
-
command:
|
|
22
|
-
args: ['run', 'check-types'],
|
|
23
|
+
command: resolution.command,
|
|
24
|
+
args: [...resolution.args, 'run', 'check-types'],
|
|
23
25
|
};
|
|
24
26
|
}
|
|
27
|
+
const resolution = getManagedRunner('tsc', {
|
|
28
|
+
fallbackCommand: 'tsc',
|
|
29
|
+
fallbackArgs: [],
|
|
30
|
+
});
|
|
25
31
|
return {
|
|
26
|
-
command:
|
|
27
|
-
args: ['--noEmit', ...(options.pretty ? [] : ['--pretty', 'false'])],
|
|
32
|
+
command: resolution.command,
|
|
33
|
+
args: [...resolution.args, '--noEmit', ...(options.pretty ? [] : ['--pretty', 'false'])],
|
|
28
34
|
};
|
|
29
35
|
}
|
|
30
36
|
export function runTypecheckCommand(options = {}, deps = {}) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
1
2
|
import path from 'node:path';
|
|
2
3
|
export function buildE2eCommand(options) {
|
|
3
4
|
switch (options.step.runner) {
|
|
@@ -15,10 +16,11 @@ function buildPlaywrightCommand(options) {
|
|
|
15
16
|
throw new Error(`Step ${step.logName} uses runner "playwright" but does not define configPath.`);
|
|
16
17
|
}
|
|
17
18
|
const { baseDir, configArg, files } = resolveRunnerPaths(step.configPath, options.files ?? []);
|
|
18
|
-
const
|
|
19
|
+
const resolution = withBaseDir(getManagedRunner('playwright', { filterOutput: options.filterOutput }), baseDir);
|
|
20
|
+
const args = [...resolution.args, 'test', '--config', configArg];
|
|
19
21
|
appendPlaywrightFlags(args, options);
|
|
20
22
|
args.push(...(step.fixedArgs ?? []), ...files, ...(options.passthrough ?? []));
|
|
21
|
-
return { command:
|
|
23
|
+
return { command: resolution.command, args };
|
|
22
24
|
}
|
|
23
25
|
function buildVitestE2eCommand(options) {
|
|
24
26
|
const { step } = options;
|
|
@@ -26,12 +28,13 @@ function buildVitestE2eCommand(options) {
|
|
|
26
28
|
throw new Error(`Step ${step.logName} uses runner "vitest" but does not define configPath.`);
|
|
27
29
|
}
|
|
28
30
|
const { baseDir, configArg, files } = resolveRunnerPaths(step.configPath, options.files ?? []);
|
|
29
|
-
const
|
|
31
|
+
const resolution = withBaseDir(getManagedRunner('vitest', { filterOutput: options.filterOutput }), baseDir);
|
|
32
|
+
const args = [...resolution.args, 'run', '--config', configArg];
|
|
30
33
|
if (options.workers !== undefined) {
|
|
31
34
|
args.push('--poolOptions.threads.maxThreads', String(options.workers));
|
|
32
35
|
}
|
|
33
36
|
args.push(...(step.fixedArgs ?? []), ...files, ...(options.passthrough ?? []));
|
|
34
|
-
return { command:
|
|
37
|
+
return { command: resolution.command, args };
|
|
35
38
|
}
|
|
36
39
|
function buildCustomCommand(options) {
|
|
37
40
|
const { step } = options;
|
|
@@ -69,9 +72,6 @@ function appendPlaywrightFlags(args, options) {
|
|
|
69
72
|
args.push('--test-list', options.testList);
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
|
-
function buildPnpmExecPrefix(baseDir) {
|
|
73
|
-
return baseDir === '.' ? ['exec'] : ['--dir', baseDir, 'exec'];
|
|
74
|
-
}
|
|
75
75
|
function resolveRunnerPaths(configPath, files) {
|
|
76
76
|
const normalizedConfigPath = configPath.replace(/\\/gu, '/');
|
|
77
77
|
const baseDir = path.posix.dirname(normalizedConfigPath);
|
|
@@ -95,4 +95,23 @@ function resolveRunnerPaths(configPath, files) {
|
|
|
95
95
|
}),
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
+
function withBaseDir(resolution, baseDir) {
|
|
99
|
+
if (baseDir === '.') {
|
|
100
|
+
return { command: resolution.command, args: [...resolution.args] };
|
|
101
|
+
}
|
|
102
|
+
if (resolution.command === 'vp') {
|
|
103
|
+
return {
|
|
104
|
+
command: resolution.command,
|
|
105
|
+
args: ['--dir', baseDir, ...resolution.args],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const [wrappedCommand, ...wrappedArgs] = resolution.args;
|
|
109
|
+
if (resolution.command === 'rtk' && wrappedCommand === 'vp') {
|
|
110
|
+
return {
|
|
111
|
+
command: resolution.command,
|
|
112
|
+
args: ['vp', '--dir', baseDir, ...wrappedArgs],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return { command: resolution.command, args: [...resolution.args] };
|
|
116
|
+
}
|
|
98
117
|
//# sourceMappingURL=command-builder.js.map
|
|
@@ -18,6 +18,7 @@ export async function createE2eExecutionPlan(input, cwd = process.cwd()) {
|
|
|
18
18
|
workers: input.workers,
|
|
19
19
|
testList: input.testList,
|
|
20
20
|
passthrough: input.passthrough,
|
|
21
|
+
filterOutput: input.filterOutput,
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
const hostAdapter = await loadConfiguredHostAdapter(cwd);
|
|
@@ -35,6 +36,7 @@ export async function createE2eExecutionPlan(input, cwd = process.cwd()) {
|
|
|
35
36
|
workers: input.workers,
|
|
36
37
|
testList: input.testList,
|
|
37
38
|
passthrough: input.passthrough,
|
|
39
|
+
filterOutput: input.filterOutput,
|
|
38
40
|
});
|
|
39
41
|
}
|
|
40
42
|
if (hostAdapter.adapter.buildExecutionPlan) {
|
|
@@ -49,6 +51,7 @@ export async function createE2eExecutionPlan(input, cwd = process.cwd()) {
|
|
|
49
51
|
workers: input.workers,
|
|
50
52
|
testList: input.testList,
|
|
51
53
|
passthrough: input.passthrough,
|
|
54
|
+
filterOutput: input.filterOutput,
|
|
52
55
|
});
|
|
53
56
|
}
|
|
54
57
|
return planE2eRun({
|
|
@@ -60,6 +63,7 @@ export async function createE2eExecutionPlan(input, cwd = process.cwd()) {
|
|
|
60
63
|
workers: input.workers,
|
|
61
64
|
testList: input.testList,
|
|
62
65
|
passthrough: input.passthrough,
|
|
66
|
+
filterOutput: input.filterOutput,
|
|
63
67
|
});
|
|
64
68
|
}
|
|
65
69
|
export function plannedGroupsToCommandConfigs(groups) {
|
package/dist/esm/e2e/types.d.ts
CHANGED
package/dist/esm/format/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { isMissingBinary, isRunFailure, runCommand } from '#mcp/tools/_shared/run-command';
|
|
10
10
|
import { resolveProjectRoot } from '#mcp/tools/_shared/project-root';
|
|
11
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
11
12
|
const DEFAULT_FORMAT_TIMEOUT_MS = 5 * 60 * 1_000;
|
|
12
13
|
/**
|
|
13
14
|
* Run formatter and return a structured result. Throws a clear error when
|
|
@@ -33,7 +34,12 @@ export async function runFormat(options = {}) {
|
|
|
33
34
|
args.push('--ignore-path', '.gitignore');
|
|
34
35
|
if (options.files && options.files.length > 0)
|
|
35
36
|
args.push(...options.files);
|
|
36
|
-
const
|
|
37
|
+
const resolution = getManagedRunner('oxfmt', {
|
|
38
|
+
fallbackCommand: 'oxfmt',
|
|
39
|
+
fallbackArgs: [],
|
|
40
|
+
filterOutput: false,
|
|
41
|
+
});
|
|
42
|
+
const outcome = await runCommand(resolution.command, [...resolution.args, ...args], runOptions);
|
|
37
43
|
if (isRunFailure(outcome)) {
|
|
38
44
|
if (isMissingBinary(outcome)) {
|
|
39
45
|
throw new Error("oxfmt binary not found on PATH. Install it as a devDependency: 'vp install -D oxfmt'");
|
package/dist/esm/lint/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { isRunFailure, runCommand } from '#mcp/tools/_shared/run-command';
|
|
10
10
|
import { resolveProjectRoot } from '#mcp/tools/_shared/project-root';
|
|
11
|
+
import { getManagedRunner } from '#tool-runtime';
|
|
11
12
|
const DEFAULT_LINT_TIMEOUT_MS = 5 * 60 * 1_000;
|
|
12
13
|
/**
|
|
13
14
|
* Parse oxlint's `--format=json` output (ESLint-compatible array shape) into
|
|
@@ -92,7 +93,8 @@ export async function runLint(options = {}) {
|
|
|
92
93
|
else {
|
|
93
94
|
lintArgs.push('.');
|
|
94
95
|
}
|
|
95
|
-
const
|
|
96
|
+
const resolution = getManagedRunner('vp', { filterOutput: false });
|
|
97
|
+
const vpOutcome = await runCommand(resolution.command, [...resolution.args, ...lintArgs], runOptions);
|
|
96
98
|
if (isRunFailure(vpOutcome)) {
|
|
97
99
|
return {
|
|
98
100
|
passed: false,
|