@vibe-agent-toolkit/cli 0.1.39-rc.1 → 0.1.39-rc.11
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/dist/commands/audit/git-url-clone.d.ts +1 -1
- package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
- package/dist/commands/audit/git-url-clone.js +3 -67
- package/dist/commands/audit/git-url-clone.js.map +1 -1
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +1 -2
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/claude/plugin/build.d.ts.map +1 -1
- package/dist/commands/claude/plugin/build.js +68 -4
- package/dist/commands/claude/plugin/build.js.map +1 -1
- package/dist/commands/consistency-check.d.ts +13 -0
- package/dist/commands/consistency-check.d.ts.map +1 -1
- package/dist/commands/consistency-check.js +98 -1
- package/dist/commands/consistency-check.js.map +1 -1
- package/dist/commands/corpus/runner.d.ts.map +1 -1
- package/dist/commands/corpus/runner.js +1 -2
- package/dist/commands/corpus/runner.js.map +1 -1
- package/dist/commands/skill/index.d.ts.map +1 -1
- package/dist/commands/skill/index.js +2 -0
- package/dist/commands/skill/index.js.map +1 -1
- package/dist/commands/skill/test/configure.d.ts +22 -0
- package/dist/commands/skill/test/configure.d.ts.map +1 -0
- package/dist/commands/skill/test/configure.js +127 -0
- package/dist/commands/skill/test/configure.js.map +1 -0
- package/dist/commands/skill/test/index.d.ts +6 -0
- package/dist/commands/skill/test/index.d.ts.map +1 -0
- package/dist/commands/skill/test/index.js +16 -0
- package/dist/commands/skill/test/index.js.map +1 -0
- package/dist/commands/skill/test/run.d.ts +40 -0
- package/dist/commands/skill/test/run.d.ts.map +1 -0
- package/dist/commands/skill/test/run.js +381 -0
- package/dist/commands/skill/test/run.js.map +1 -0
- package/package.json +11 -11
- package/dist/utils/git-url.d.ts +0 -43
- package/dist/utils/git-url.d.ts.map +0 -1
- package/dist/utils/git-url.js +0 -135
- package/dist/utils/git-url.js.map +0 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `vat skill test run <skill...>` — execute a packaged skill's eval suite in isolation.
|
|
3
|
+
*
|
|
4
|
+
* Thin orchestration layer: parse flags, resolve precedence (flag > config > default),
|
|
5
|
+
* print the §12 security warning, call runSkillTestHarness, map result/error to exit code.
|
|
6
|
+
* All domain logic lives in run-harness.ts (agent-skills package).
|
|
7
|
+
*/
|
|
8
|
+
import { basename } from 'node:path';
|
|
9
|
+
import { BootstrapNeededError, mapErrorToExitCode, runSkillTestHarness } from '@vibe-agent-toolkit/agent-skills';
|
|
10
|
+
import { findProjectRoot, toForwardSlash } from '@vibe-agent-toolkit/utils';
|
|
11
|
+
import { Command } from 'commander';
|
|
12
|
+
import { loadConfig } from '../../../utils/config-loader.js';
|
|
13
|
+
/** Extract the trailing path segment (cross-platform) from a path-like string. */
|
|
14
|
+
function lastPathSegment(p) {
|
|
15
|
+
return basename(toForwardSlash(p));
|
|
16
|
+
}
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Security warning (§12)
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
const SECURITY_WARNING = `
|
|
21
|
+
WARNING: vat skill test run executes arbitrary skill code inside a headless
|
|
22
|
+
Claude session. The experimenter prompt and all staged skill files run with
|
|
23
|
+
bypassPermissions. Pass --i-understand-this-runs-skill-code to acknowledge
|
|
24
|
+
this and proceed.
|
|
25
|
+
`.trim();
|
|
26
|
+
function printSecurityWarning() {
|
|
27
|
+
process.stderr.write(SECURITY_WARNING + '\n\n');
|
|
28
|
+
}
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Knob coercion helpers
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
function coercePositiveInt(value, flagName) {
|
|
33
|
+
if (value === undefined)
|
|
34
|
+
return undefined;
|
|
35
|
+
const n = Number.parseInt(value, 10);
|
|
36
|
+
if (!Number.isInteger(n) || n <= 0) {
|
|
37
|
+
throw new Error(`${flagName} must be a positive integer. Got: ${value}`);
|
|
38
|
+
}
|
|
39
|
+
return n;
|
|
40
|
+
}
|
|
41
|
+
function coercePositiveFloat(value, flagName) {
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
return undefined;
|
|
44
|
+
const n = Number.parseFloat(value);
|
|
45
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
46
|
+
throw new Error(`${flagName} must be a positive number. Got: ${value}`);
|
|
47
|
+
}
|
|
48
|
+
return n;
|
|
49
|
+
}
|
|
50
|
+
function coerceKnobs(options) {
|
|
51
|
+
const result = {};
|
|
52
|
+
const maxTurns = coercePositiveInt(options.maxTurns, '--max-turns');
|
|
53
|
+
if (maxTurns !== undefined)
|
|
54
|
+
result.maxTurns = maxTurns;
|
|
55
|
+
const maxBudgetUsd = coercePositiveFloat(options.maxBudgetUsd, '--max-budget-usd');
|
|
56
|
+
if (maxBudgetUsd !== undefined)
|
|
57
|
+
result.maxBudgetUsd = maxBudgetUsd;
|
|
58
|
+
const timeout = coercePositiveInt(options.timeout, '--timeout');
|
|
59
|
+
if (timeout !== undefined)
|
|
60
|
+
result.timeout = timeout;
|
|
61
|
+
const stall = coercePositiveInt(options.stall, '--stall');
|
|
62
|
+
if (stall !== undefined)
|
|
63
|
+
result.stall = stall;
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Parse a single `name=src` pair into a [name, SkillSourceSpec] tuple. The
|
|
68
|
+
* source half uses a `kind:value` prefix:
|
|
69
|
+
* workspace:foo · npm:@scope/s@1.2.3 · url:https://… · path:../baz · vendored
|
|
70
|
+
* A bare value without `name=` is rejected — every injected dep needs a name so
|
|
71
|
+
* the domain can key it (and so the skill resolves under that name in staging).
|
|
72
|
+
*/
|
|
73
|
+
function parseWithPair(pair) {
|
|
74
|
+
const eq = pair.indexOf('=');
|
|
75
|
+
if (eq <= 0) {
|
|
76
|
+
throw new Error(`--with entries must be "name=<src>" (e.g. mydep=workspace:foo, bar=npm:@scope/s@1.2.3, baz=path:../baz). Got: ${pair}`);
|
|
77
|
+
}
|
|
78
|
+
const name = pair.slice(0, eq);
|
|
79
|
+
const src = pair.slice(eq + 1);
|
|
80
|
+
return [name, parseSourceSpec(src, pair)];
|
|
81
|
+
}
|
|
82
|
+
/** Parse the `kind:value` source half of a --with pair into a SkillSourceSpec. */
|
|
83
|
+
function parseSourceSpec(src, original) {
|
|
84
|
+
if (src === 'vendored')
|
|
85
|
+
return { vendored: true };
|
|
86
|
+
const colon = src.indexOf(':');
|
|
87
|
+
const kind = colon === -1 ? src : src.slice(0, colon);
|
|
88
|
+
const value = colon === -1 ? '' : src.slice(colon + 1);
|
|
89
|
+
switch (kind) {
|
|
90
|
+
case 'workspace': return requireValue(value, original, () => ({ workspace: value }));
|
|
91
|
+
case 'npm': return requireValue(value, original, () => ({ npm: value }));
|
|
92
|
+
case 'path': return requireValue(value, original, () => ({ path: value }));
|
|
93
|
+
case 'url': return requireValue(value, original, () => ({ url: value }));
|
|
94
|
+
default:
|
|
95
|
+
throw new Error(`--with source must start with workspace:|npm:|url:|path:|vendored. Got: ${original}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function requireValue(value, original, build) {
|
|
99
|
+
if (!value) {
|
|
100
|
+
throw new Error(`--with source is missing a value: ${original}`);
|
|
101
|
+
}
|
|
102
|
+
return build();
|
|
103
|
+
}
|
|
104
|
+
/** Parse an array of `name=src` flag values into a name→spec record. */
|
|
105
|
+
function parseWithFlags(pairs) {
|
|
106
|
+
if (pairs === undefined || pairs.length === 0)
|
|
107
|
+
return undefined;
|
|
108
|
+
const record = {};
|
|
109
|
+
for (const pair of pairs) {
|
|
110
|
+
const [name, spec] = parseWithPair(pair);
|
|
111
|
+
record[name] = spec;
|
|
112
|
+
}
|
|
113
|
+
return record;
|
|
114
|
+
}
|
|
115
|
+
/** Derive a stable name for a config-supplied (nameless) skill source descriptor. */
|
|
116
|
+
function descriptorName(d) {
|
|
117
|
+
if ('workspace' in d)
|
|
118
|
+
return d.workspace;
|
|
119
|
+
if ('npm' in d)
|
|
120
|
+
return d.npm.replace(/@[^@/]+$/, '');
|
|
121
|
+
if ('path' in d)
|
|
122
|
+
return lastPathSegment(d.path) || d.path;
|
|
123
|
+
if ('url' in d)
|
|
124
|
+
return 'url-dep';
|
|
125
|
+
return 'skill-creator';
|
|
126
|
+
}
|
|
127
|
+
/** Map a config descriptor array (with/optional) into a name→spec record. */
|
|
128
|
+
function descriptorsToRecord(list) {
|
|
129
|
+
if (list === undefined || list.length === 0)
|
|
130
|
+
return undefined;
|
|
131
|
+
const record = {};
|
|
132
|
+
for (const d of list)
|
|
133
|
+
record[descriptorName(d)] = d;
|
|
134
|
+
return record;
|
|
135
|
+
}
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// Precedence resolution: flag > config > default
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
/**
|
|
140
|
+
* Load the persisted `skills.config.<skill>.test` block for the subject skill.
|
|
141
|
+
* The subject is the first positional skill name (a path or skill key). We key
|
|
142
|
+
* the config by its basename so `./dist/skills/my-skill/` matches `my-skill`.
|
|
143
|
+
* Missing config / missing file → undefined (defaults apply).
|
|
144
|
+
*/
|
|
145
|
+
function loadTestConfig(skills) {
|
|
146
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
147
|
+
if (projectRoot === null)
|
|
148
|
+
return undefined;
|
|
149
|
+
let config;
|
|
150
|
+
try {
|
|
151
|
+
config = loadConfig(projectRoot);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return undefined; // tolerate a broken/absent config → defaults
|
|
155
|
+
}
|
|
156
|
+
const perSkill = config?.skills?.config;
|
|
157
|
+
if (perSkill === undefined)
|
|
158
|
+
return undefined;
|
|
159
|
+
const subject = skills[0] ?? '';
|
|
160
|
+
const base = lastPathSegment(subject) || subject;
|
|
161
|
+
return perSkill[subject]?.test ?? perSkill[base]?.test;
|
|
162
|
+
}
|
|
163
|
+
/** Resolve the project root used as the harness repoRoot anchor. */
|
|
164
|
+
function resolveRepoRoot() {
|
|
165
|
+
return findProjectRoot(process.cwd()) ?? process.cwd();
|
|
166
|
+
}
|
|
167
|
+
/** Copy flag-only passthrough options (no config counterpart) onto opts. */
|
|
168
|
+
function applyFlagOnlyOptions(opts, options) {
|
|
169
|
+
if (options.refresh !== undefined)
|
|
170
|
+
opts.refresh = options.refresh;
|
|
171
|
+
if (options.workdir !== undefined)
|
|
172
|
+
opts.workdir = options.workdir;
|
|
173
|
+
if (options.out !== undefined)
|
|
174
|
+
opts.out = options.out;
|
|
175
|
+
if (options.keep !== undefined)
|
|
176
|
+
opts.keep = options.keep;
|
|
177
|
+
if (options.dryRun !== undefined)
|
|
178
|
+
opts.dryRun = options.dryRun;
|
|
179
|
+
if (options.allowUnverifiedSkillSource !== undefined)
|
|
180
|
+
opts.allowUnverifiedSkillSource = options.allowUnverifiedSkillSource;
|
|
181
|
+
if (options.iUnderstandThisRunsSkillCode !== undefined)
|
|
182
|
+
opts.acknowledgedRunsSkillCode = options.iUnderstandThisRunsSkillCode;
|
|
183
|
+
}
|
|
184
|
+
/** Apply flag>config merges for scalar knobs (auth, model, baseline, eval/prompt). */
|
|
185
|
+
function applyScalarMerges(opts, options, config) {
|
|
186
|
+
const authMode = options.auth ?? config?.auth;
|
|
187
|
+
if (authMode !== undefined)
|
|
188
|
+
opts.auth = authMode;
|
|
189
|
+
const authRequirement = options.requireAuth ?? config?.requireAuth;
|
|
190
|
+
if (authRequirement !== undefined)
|
|
191
|
+
opts.requireAuth = authRequirement;
|
|
192
|
+
const baseline = options.baseline ?? config?.baseline;
|
|
193
|
+
if (baseline !== undefined)
|
|
194
|
+
opts.baseline = baseline;
|
|
195
|
+
const model = options.model ?? config?.model;
|
|
196
|
+
if (model !== undefined)
|
|
197
|
+
opts.model = model;
|
|
198
|
+
if (config?.evals !== undefined)
|
|
199
|
+
opts.evalsSubpath = config.evals;
|
|
200
|
+
if (config?.experimenterPrompt !== undefined)
|
|
201
|
+
opts.promptOverride = config.experimenterPrompt;
|
|
202
|
+
if (config?.build !== undefined)
|
|
203
|
+
opts.build = config.build;
|
|
204
|
+
}
|
|
205
|
+
/** Apply flag>config merges for numeric knobs (turns/budget/timeout/stall). */
|
|
206
|
+
function applyKnobMerges(opts, knobs, config) {
|
|
207
|
+
const maxTurns = knobs.maxTurns ?? config?.maxTurns;
|
|
208
|
+
if (maxTurns !== undefined)
|
|
209
|
+
opts.maxTurns = maxTurns;
|
|
210
|
+
const maxBudgetUsd = knobs.maxBudgetUsd ?? config?.maxBudgetUsd;
|
|
211
|
+
if (maxBudgetUsd !== undefined)
|
|
212
|
+
opts.maxBudgetUsd = maxBudgetUsd;
|
|
213
|
+
const timeout = knobs.timeout ?? config?.timeout;
|
|
214
|
+
if (timeout !== undefined)
|
|
215
|
+
opts.timeout = timeout;
|
|
216
|
+
const stall = knobs.stall ?? config?.stall;
|
|
217
|
+
if (stall !== undefined)
|
|
218
|
+
opts.stall = stall;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Parse a single `KEY=VALUE` pair (split on the FIRST `=`, so values may contain
|
|
222
|
+
* `=`). The key must be non-empty; the value may be empty.
|
|
223
|
+
*/
|
|
224
|
+
function parseEnvPair(pair) {
|
|
225
|
+
const eq = pair.indexOf('=');
|
|
226
|
+
if (eq <= 0) {
|
|
227
|
+
throw new Error(`--env entries must be "KEY=VALUE" (e.g. CUSTOMER_SNAPSHOT_PATH=\${fixturesDir}/snapshot.json). Got: ${pair}`);
|
|
228
|
+
}
|
|
229
|
+
return [pair.slice(0, eq), pair.slice(eq + 1)];
|
|
230
|
+
}
|
|
231
|
+
/** Parse repeated `--env KEY=VALUE` flags into a record (undefined when none). */
|
|
232
|
+
function parseEnvFlags(pairs) {
|
|
233
|
+
if (pairs === undefined || pairs.length === 0)
|
|
234
|
+
return undefined;
|
|
235
|
+
const record = {};
|
|
236
|
+
for (const pair of pairs) {
|
|
237
|
+
const [key, value] = parseEnvPair(pair);
|
|
238
|
+
record[key] = value;
|
|
239
|
+
}
|
|
240
|
+
return record;
|
|
241
|
+
}
|
|
242
|
+
/** Merge config + CLI `env` maps; CLI wins per-key. undefined when both absent. */
|
|
243
|
+
function mergeEnv(configEnv, cliEnv) {
|
|
244
|
+
if (configEnv === undefined && cliEnv === undefined)
|
|
245
|
+
return undefined;
|
|
246
|
+
return { ...configEnv, ...cliEnv };
|
|
247
|
+
}
|
|
248
|
+
/** Union config + CLI `passEnv` lists (config first), de-duplicated. */
|
|
249
|
+
function mergePassEnv(configPass, cliPass) {
|
|
250
|
+
if (configPass === undefined && cliPass === undefined)
|
|
251
|
+
return undefined;
|
|
252
|
+
return [...new Set([...(configPass ?? []), ...(cliPass ?? [])])];
|
|
253
|
+
}
|
|
254
|
+
/** Apply flag>config merges for the declared test env (Features A + B). */
|
|
255
|
+
function applyEnvMerges(opts, options, config) {
|
|
256
|
+
const env = mergeEnv(config?.env, parseEnvFlags(options.env));
|
|
257
|
+
if (env !== undefined)
|
|
258
|
+
opts.env = env;
|
|
259
|
+
const passEnv = mergePassEnv(config?.passEnv, options.passEnv);
|
|
260
|
+
if (passEnv !== undefined)
|
|
261
|
+
opts.passEnv = passEnv;
|
|
262
|
+
}
|
|
263
|
+
/** Apply flag>config merges for injected-dependency records. */
|
|
264
|
+
function applyDepMerges(opts, options, config) {
|
|
265
|
+
const withSources = parseWithFlags(options.with) ?? descriptorsToRecord(config?.with);
|
|
266
|
+
if (withSources !== undefined)
|
|
267
|
+
opts.withSources = withSources;
|
|
268
|
+
const withOptional = parseWithFlags(options.withOptional) ?? descriptorsToRecord(config?.optional);
|
|
269
|
+
if (withOptional !== undefined)
|
|
270
|
+
opts.withOptional = withOptional;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Resolve CLI flags → RunHarnessOptions, applying flag > config > default
|
|
274
|
+
* precedence. CLI flags win; config (`skills.config.<skill>.test`) fills gaps;
|
|
275
|
+
* built-in defaults (inside the domain) are the final fallback.
|
|
276
|
+
*/
|
|
277
|
+
function buildHarnessOpts(skills, options, knobs, config) {
|
|
278
|
+
const repoRoot = resolveRepoRoot();
|
|
279
|
+
const opts = { skills, repoRoot };
|
|
280
|
+
// cwd for the pre-stage build hook. repoRoot comes from findProjectRoot, whose
|
|
281
|
+
// discovery ladder is config-anchored (vibe-agent-toolkit.config.yaml first, then
|
|
282
|
+
// .git), so the project root IS the directory holding the config — configRoot and
|
|
283
|
+
// repoRoot are the same dir by construction, not coincidence.
|
|
284
|
+
opts.configRoot = repoRoot;
|
|
285
|
+
applyFlagOnlyOptions(opts, options);
|
|
286
|
+
applyScalarMerges(opts, options, config);
|
|
287
|
+
applyKnobMerges(opts, knobs, config);
|
|
288
|
+
applyDepMerges(opts, options, config);
|
|
289
|
+
applyEnvMerges(opts, options, config);
|
|
290
|
+
return opts;
|
|
291
|
+
}
|
|
292
|
+
// ---------------------------------------------------------------------------
|
|
293
|
+
// Testable action
|
|
294
|
+
// ---------------------------------------------------------------------------
|
|
295
|
+
/**
|
|
296
|
+
* The unit-testable action for `vat skill test run`. Exported so tests can
|
|
297
|
+
* call it directly without parsing CLI args. Calls process.exit on completion.
|
|
298
|
+
*
|
|
299
|
+
* Note: the security ack enforcement lives inside runSkillTestHarness (domain),
|
|
300
|
+
* NOT here — this ensures the mock in tests can bypass it cleanly.
|
|
301
|
+
*/
|
|
302
|
+
export async function runSkillTestRun(skills, options) {
|
|
303
|
+
printSecurityWarning();
|
|
304
|
+
const knobs = coerceKnobs(options);
|
|
305
|
+
const config = loadTestConfig(skills);
|
|
306
|
+
const harnessOpts = buildHarnessOpts(skills, options, knobs, config);
|
|
307
|
+
try {
|
|
308
|
+
const result = await runSkillTestHarness(harnessOpts);
|
|
309
|
+
process.stderr.write(`Harness: ${result.harnessPath}\n`);
|
|
310
|
+
process.stdout.write(`Summary: ${result.summary}\n`);
|
|
311
|
+
process.exit(result.exitCode);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
catch (err) {
|
|
315
|
+
const exitCode = mapErrorToExitCode(err);
|
|
316
|
+
// BootstrapNeededError (exit 3) is the happy "wrote a template, fill it in
|
|
317
|
+
// and re-run" path — surface its message plainly, not as a hard `Error:`.
|
|
318
|
+
if (err instanceof BootstrapNeededError) {
|
|
319
|
+
process.stderr.write(`${err.message}\n`);
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
323
|
+
}
|
|
324
|
+
process.exit(exitCode);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// ---------------------------------------------------------------------------
|
|
329
|
+
// Commander command builder
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
export function createSkillTestRunCommand() {
|
|
332
|
+
const command = new Command('run');
|
|
333
|
+
command
|
|
334
|
+
.description('Execute the eval suite for a packaged skill in a headless Claude sandbox')
|
|
335
|
+
.argument('<skill...>', 'Skill name(s) to test (primary subject set)')
|
|
336
|
+
.option('--with <pair...>', 'Inject a declared-dependency skill as name=<src>, where <src> is workspace:<pkg> | npm:<spec> | url:<u> | path:<dir> | vendored (e.g. mydep=npm:@scope/s@1.2.3)')
|
|
337
|
+
.option('--with-optional <pair...>', 'Inject an optional skill as name=<src> (same syntax as --with)')
|
|
338
|
+
.option('--env <pair...>', 'Inject an env var into the experimenter spawn as KEY=VALUE (repeatable). Values support ${fixturesDir}, ${stagedSkillDir}, ${harnessRoot}, ${resultsDir}. CLI overrides config for the same key.')
|
|
339
|
+
.option('--pass-env <key...>', 'Forward a host env var by NAME to the experimenter spawn if present (repeatable). Protected names (PATH, auth, model) are ignored.')
|
|
340
|
+
.option('--refresh', 'Force a full re-stage (ignore existing staged content)')
|
|
341
|
+
.option('--workdir <dir>', 'Override the harness working directory')
|
|
342
|
+
.option('--out <dir>', 'Override the harness output directory')
|
|
343
|
+
.option('--keep', 'Keep the harness directory after the run')
|
|
344
|
+
.option('--dry-run', 'Assemble the command without spawning Claude')
|
|
345
|
+
.option('--auth <mode>', 'Auth mechanism: inherit | subscription | api-key | auto')
|
|
346
|
+
.option('--require-auth <mech>', 'Require a specific auth mechanism: subscription | api-key')
|
|
347
|
+
.option('--baseline', 'Enable A/B baseline run (with/without skill)')
|
|
348
|
+
.option('--allow-unverified-skill-source', 'Skip the vendored manifest integrity check')
|
|
349
|
+
.option('--i-understand-this-runs-skill-code', 'Acknowledge this command executes skill code (required)')
|
|
350
|
+
.option('--model <id>', 'Pinned model ID override')
|
|
351
|
+
.option('--max-turns <n>', 'Cap on experimenter turns (positive integer)')
|
|
352
|
+
.option('--max-budget-usd <n>', 'Hard USD budget cap (positive number)')
|
|
353
|
+
.option('--timeout <s>', 'Wall-clock timeout in seconds (positive integer)')
|
|
354
|
+
.option('--stall <s>', 'Stall-watchdog in seconds (positive integer)')
|
|
355
|
+
.option('--debug', 'Enable debug logging')
|
|
356
|
+
.action(runSkillTestRun)
|
|
357
|
+
.addHelpText('after', `
|
|
358
|
+
Description:
|
|
359
|
+
Stages the named skill(s) into an isolated tmp directory, runs preflight
|
|
360
|
+
checks (claude binary, auth, eval inputs, budget), then spawns a headless
|
|
361
|
+
Claude session with a non-interactive experimenter prompt. The experimenter
|
|
362
|
+
grades each eval against the skill's expectations and writes grading.json.
|
|
363
|
+
|
|
364
|
+
IMPORTANT: This command executes arbitrary skill code. You MUST pass
|
|
365
|
+
--i-understand-this-runs-skill-code to acknowledge this and proceed.
|
|
366
|
+
|
|
367
|
+
Exit Codes:
|
|
368
|
+
0 - Harness ran to completion and produced a valid grading.json (check summary/grading.json for pass/fail counts)
|
|
369
|
+
1 - Internal error (grading.json absent/invalid, experimenter crash, stall/timeout)
|
|
370
|
+
2 - Preflight failed (missing binary, auth error, eval inputs absent, unsafe workdir, ack missing)
|
|
371
|
+
3 - Bootstrap needed: evals.json was absent, so VAT wrote a starter template next to the skill source. Fill it in and re-run.
|
|
372
|
+
|
|
373
|
+
Note: eval pass/fail is NOT reflected in the exit code. Read the printed summary
|
|
374
|
+
("PASS N/N" or "FAIL N/N") or grading.json to determine whether expectations passed.
|
|
375
|
+
|
|
376
|
+
Example:
|
|
377
|
+
$ vat skill test run my-skill --i-understand-this-runs-skill-code
|
|
378
|
+
`);
|
|
379
|
+
return command;
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../../../src/commands/skill/test/run.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibe-agent-toolkit/cli",
|
|
3
|
-
"version": "0.1.39-rc.
|
|
3
|
+
"version": "0.1.39-rc.11",
|
|
4
4
|
"description": "Command-line interface for vibe-agent-toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"//dependencies-note": "DO NOT add example agent packages or adopter packages here. Adopter packages (like vat-development-agents) depend on the CLI binary at build time — declaring them as deps creates a circular build dependency. They are built in a second turbo pass via package#task overrides in turbo.json.",
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@anthropic-ai/sdk": "^0.71.2",
|
|
44
|
-
"@vibe-agent-toolkit/agent-config": "0.1.39-rc.
|
|
45
|
-
"@vibe-agent-toolkit/agent-schema": "0.1.39-rc.
|
|
46
|
-
"@vibe-agent-toolkit/agent-skills": "0.1.39-rc.
|
|
47
|
-
"@vibe-agent-toolkit/claude-marketplace": "0.1.39-rc.
|
|
48
|
-
"@vibe-agent-toolkit/discovery": "0.1.39-rc.
|
|
49
|
-
"@vibe-agent-toolkit/gateway-mcp": "0.1.39-rc.
|
|
50
|
-
"@vibe-agent-toolkit/rag": "0.1.39-rc.
|
|
51
|
-
"@vibe-agent-toolkit/rag-lancedb": "0.1.39-rc.
|
|
52
|
-
"@vibe-agent-toolkit/resources": "0.1.39-rc.
|
|
53
|
-
"@vibe-agent-toolkit/utils": "0.1.39-rc.
|
|
44
|
+
"@vibe-agent-toolkit/agent-config": "0.1.39-rc.11",
|
|
45
|
+
"@vibe-agent-toolkit/agent-schema": "0.1.39-rc.11",
|
|
46
|
+
"@vibe-agent-toolkit/agent-skills": "0.1.39-rc.11",
|
|
47
|
+
"@vibe-agent-toolkit/claude-marketplace": "0.1.39-rc.11",
|
|
48
|
+
"@vibe-agent-toolkit/discovery": "0.1.39-rc.11",
|
|
49
|
+
"@vibe-agent-toolkit/gateway-mcp": "0.1.39-rc.11",
|
|
50
|
+
"@vibe-agent-toolkit/rag": "0.1.39-rc.11",
|
|
51
|
+
"@vibe-agent-toolkit/rag-lancedb": "0.1.39-rc.11",
|
|
52
|
+
"@vibe-agent-toolkit/resources": "0.1.39-rc.11",
|
|
53
|
+
"@vibe-agent-toolkit/utils": "0.1.39-rc.11",
|
|
54
54
|
"adm-zip": "^0.5.16",
|
|
55
55
|
"commander": "^12.1.0",
|
|
56
56
|
"picomatch": "^4.0.3",
|
package/dist/utils/git-url.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parsed representation of a git URL accepted by `vat audit`.
|
|
3
|
-
*
|
|
4
|
-
* - `cloneUrl` is the URL passed to `git clone` (after stripping ref/subpath
|
|
5
|
-
* fragments and after expanding GitHub shorthand to a full HTTPS URL).
|
|
6
|
-
* - `ref` is an optional branch or tag name (deep commit SHAs are not
|
|
7
|
-
* guaranteed to work with shallow clone — see design spec for details).
|
|
8
|
-
* - `subpath` is an optional subdirectory within the cloned repo to audit.
|
|
9
|
-
*/
|
|
10
|
-
export interface ParsedGitUrl {
|
|
11
|
-
cloneUrl: string;
|
|
12
|
-
ref?: string;
|
|
13
|
-
subpath?: string;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Parse a string into a {@link ParsedGitUrl}.
|
|
17
|
-
*
|
|
18
|
-
* Accepted forms:
|
|
19
|
-
* - `https://host/owner/repo.git`
|
|
20
|
-
* - `https://host/owner/repo.git#ref`
|
|
21
|
-
* - `https://host/owner/repo.git#ref:subpath`
|
|
22
|
-
* - `https://github.com/owner/repo/tree/<ref>/<subpath>` (GitHub web URL)
|
|
23
|
-
* - `owner/repo` (GitHub shorthand → expanded to HTTPS)
|
|
24
|
-
* - `git@host:owner/repo.git`
|
|
25
|
-
* - `ssh://git@host/owner/repo.git`
|
|
26
|
-
*
|
|
27
|
-
* Throws on malformed input.
|
|
28
|
-
*/
|
|
29
|
-
export declare function parseGitUrl(input: string): ParsedGitUrl;
|
|
30
|
-
/**
|
|
31
|
-
* Detect whether a string should be treated as a git URL (for the polymorphic
|
|
32
|
-
* `[git-url-or-path]` audit argument). True for:
|
|
33
|
-
* - http(s):// URLs
|
|
34
|
-
* - ssh:// URLs
|
|
35
|
-
* - file:// URLs (used by integration tests against local bare repos)
|
|
36
|
-
* - git@host:path scp-style URLs
|
|
37
|
-
* - GitHub shorthand `owner/repo` (strict — no extensions, no extra slashes)
|
|
38
|
-
*
|
|
39
|
-
* Everything else (including relative paths like `./foo/bar`, absolute paths,
|
|
40
|
-
* and multi-segment paths like `foo/bar/baz`) is treated as a filesystem path.
|
|
41
|
-
*/
|
|
42
|
-
export declare function isGitUrl(input: string): boolean;
|
|
43
|
-
//# sourceMappingURL=git-url.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-url.d.ts","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAgEvD;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAmB/C"}
|
package/dist/utils/git-url.js
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Split a URL with an optional `#ref[:subpath]` fragment into the base URL
|
|
3
|
-
* and fragment components. Keeps the fragment-handling logic local so the
|
|
4
|
-
* per-form regexes can stay simple and anchored.
|
|
5
|
-
*/
|
|
6
|
-
function splitFragment(input) {
|
|
7
|
-
const hashIndex = input.indexOf('#');
|
|
8
|
-
if (hashIndex === -1) {
|
|
9
|
-
return { base: input };
|
|
10
|
-
}
|
|
11
|
-
const base = input.slice(0, hashIndex);
|
|
12
|
-
const fragment = input.slice(hashIndex + 1);
|
|
13
|
-
const colonIndex = fragment.indexOf(':');
|
|
14
|
-
if (colonIndex === -1) {
|
|
15
|
-
return { base, ref: fragment };
|
|
16
|
-
}
|
|
17
|
-
return {
|
|
18
|
-
base,
|
|
19
|
-
ref: fragment.slice(0, colonIndex),
|
|
20
|
-
subpath: fragment.slice(colonIndex + 1),
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Parse a string into a {@link ParsedGitUrl}.
|
|
25
|
-
*
|
|
26
|
-
* Accepted forms:
|
|
27
|
-
* - `https://host/owner/repo.git`
|
|
28
|
-
* - `https://host/owner/repo.git#ref`
|
|
29
|
-
* - `https://host/owner/repo.git#ref:subpath`
|
|
30
|
-
* - `https://github.com/owner/repo/tree/<ref>/<subpath>` (GitHub web URL)
|
|
31
|
-
* - `owner/repo` (GitHub shorthand → expanded to HTTPS)
|
|
32
|
-
* - `git@host:owner/repo.git`
|
|
33
|
-
* - `ssh://git@host/owner/repo.git`
|
|
34
|
-
*
|
|
35
|
-
* Throws on malformed input.
|
|
36
|
-
*/
|
|
37
|
-
export function parseGitUrl(input) {
|
|
38
|
-
const trimmed = input.trim();
|
|
39
|
-
if (trimmed === '') {
|
|
40
|
-
throw new Error(`Invalid git URL or path: <empty>.`);
|
|
41
|
-
}
|
|
42
|
-
// file:// form: file:///path/to/repo[#ref[:subpath]] — used primarily by
|
|
43
|
-
// integration tests that clone a local bare repo. `git clone` accepts
|
|
44
|
-
// file:// natively.
|
|
45
|
-
if (trimmed.startsWith('file://')) {
|
|
46
|
-
const { base, ref, subpath } = splitFragment(trimmed);
|
|
47
|
-
return buildParsed(base, ref, subpath);
|
|
48
|
-
}
|
|
49
|
-
// HTTPS .git form: https://host/path.git[#ref[:subpath]]
|
|
50
|
-
if (/^https?:\/\//.test(trimmed)) {
|
|
51
|
-
const { base, ref, subpath } = splitFragment(trimmed);
|
|
52
|
-
if (base.endsWith('.git')) {
|
|
53
|
-
return buildParsed(base, ref, subpath);
|
|
54
|
-
}
|
|
55
|
-
// GitHub web URL: https://github.com/owner/repo/tree/<ref>[/<subpath>]
|
|
56
|
-
const ghWeb =
|
|
57
|
-
// eslint-disable-next-line security/detect-unsafe-regex -- Anchored ^...$ with bounded character classes; the only variable-length group is the trailing subpath. Safe from ReDoS.
|
|
58
|
-
/^https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)\/tree\/([^/]+)(?:\/(.+))?$/.exec(trimmed);
|
|
59
|
-
if (ghWeb) {
|
|
60
|
-
const owner = ghWeb[1] ?? '';
|
|
61
|
-
const repo = ghWeb[2] ?? '';
|
|
62
|
-
const webRef = ghWeb[3];
|
|
63
|
-
const webSubpath = ghWeb[4];
|
|
64
|
-
return buildParsed(`https://github.com/${owner}/${repo}.git`, webRef, webSubpath);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// SSH ssh:// form: ssh://git@host/path[#ref[:subpath]]
|
|
68
|
-
if (trimmed.startsWith('ssh://')) {
|
|
69
|
-
const { base, ref, subpath } = splitFragment(trimmed);
|
|
70
|
-
return buildParsed(base, ref, subpath);
|
|
71
|
-
}
|
|
72
|
-
// SSH scp-like form: git@host:owner/repo.git[#ref[:subpath]]
|
|
73
|
-
// Anchored, no alternation with nested quantifiers — safe from ReDoS.
|
|
74
|
-
if (/^[^@\s]+@[^:\s]+:[^#\s]+/.test(trimmed)) {
|
|
75
|
-
const { base, ref, subpath } = splitFragment(trimmed);
|
|
76
|
-
return buildParsed(base, ref, subpath);
|
|
77
|
-
}
|
|
78
|
-
// GitHub shorthand: owner/repo[#ref[:subpath]] (single slash in base)
|
|
79
|
-
const { base, ref, subpath } = splitFragment(trimmed);
|
|
80
|
-
const shorthand = /^([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)$/.exec(base);
|
|
81
|
-
if (shorthand) {
|
|
82
|
-
const owner = shorthand[1] ?? '';
|
|
83
|
-
const repo = shorthand[2] ?? '';
|
|
84
|
-
return buildParsed(`https://github.com/${owner}/${repo}.git`, ref, subpath);
|
|
85
|
-
}
|
|
86
|
-
throw new Error(`Invalid git URL or path: ${input}. Accepted forms: ` +
|
|
87
|
-
`https://<host>/<owner>/<repo>.git, ` +
|
|
88
|
-
`git@<host>:<owner>/<repo>.git, ` +
|
|
89
|
-
`<owner>/<repo>, or a local filesystem path.`);
|
|
90
|
-
}
|
|
91
|
-
function buildParsed(cloneUrl, ref, subpath) {
|
|
92
|
-
const result = { cloneUrl };
|
|
93
|
-
if (ref !== undefined && ref !== '')
|
|
94
|
-
result.ref = ref;
|
|
95
|
-
if (subpath !== undefined && subpath !== '')
|
|
96
|
-
result.subpath = subpath;
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Detect whether a string should be treated as a git URL (for the polymorphic
|
|
101
|
-
* `[git-url-or-path]` audit argument). True for:
|
|
102
|
-
* - http(s):// URLs
|
|
103
|
-
* - ssh:// URLs
|
|
104
|
-
* - file:// URLs (used by integration tests against local bare repos)
|
|
105
|
-
* - git@host:path scp-style URLs
|
|
106
|
-
* - GitHub shorthand `owner/repo` (strict — no extensions, no extra slashes)
|
|
107
|
-
*
|
|
108
|
-
* Everything else (including relative paths like `./foo/bar`, absolute paths,
|
|
109
|
-
* and multi-segment paths like `foo/bar/baz`) is treated as a filesystem path.
|
|
110
|
-
*/
|
|
111
|
-
export function isGitUrl(input) {
|
|
112
|
-
const trimmed = input.trim();
|
|
113
|
-
if (trimmed === '')
|
|
114
|
-
return false;
|
|
115
|
-
if (/^https?:\/\//.test(trimmed))
|
|
116
|
-
return true;
|
|
117
|
-
if (trimmed.startsWith('ssh://'))
|
|
118
|
-
return true;
|
|
119
|
-
if (trimmed.startsWith('file://'))
|
|
120
|
-
return true;
|
|
121
|
-
// Match the same scp-style pattern parseGitUrl uses, including the
|
|
122
|
-
// requirement of a non-empty path segment after the colon. Without the
|
|
123
|
-
// trailing `[^#\s]+`, `isGitUrl` would accept inputs like `foo@host:`
|
|
124
|
-
// that parseGitUrl then rejects with a less-helpful error.
|
|
125
|
-
if (/^[^@\s]+@[^:\s]+:[^#\s]+/.test(trimmed))
|
|
126
|
-
return true;
|
|
127
|
-
// Strict GitHub shorthand: exactly two segments, no extension on second,
|
|
128
|
-
// no path separators beyond the single /. Strip any `#ref[:subpath]`
|
|
129
|
-
// fragment first so `owner/repo#main` and `owner/repo#main:sub` are
|
|
130
|
-
// recognized — `parseGitUrl` handles fragments uniformly across forms.
|
|
131
|
-
const hashIndex = trimmed.indexOf('#');
|
|
132
|
-
const base = hashIndex === -1 ? trimmed : trimmed.slice(0, hashIndex);
|
|
133
|
-
return /^[A-Za-z0-9_-]+\/[A-Za-z0-9_-]+$/.test(base);
|
|
134
|
-
}
|
|
135
|
-
//# sourceMappingURL=git-url.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-url.js","sourceRoot":"","sources":["../../src/utils/git-url.ts"],"names":[],"mappings":"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"}
|