@vibe-agent-toolkit/cli 0.1.38 → 0.1.39-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +6 -3
  2. package/dist/commands/audit/git-url-clone.d.ts +1 -1
  3. package/dist/commands/audit/git-url-clone.d.ts.map +1 -1
  4. package/dist/commands/audit/git-url-clone.js +3 -67
  5. package/dist/commands/audit/git-url-clone.js.map +1 -1
  6. package/dist/commands/audit/hierarchical-output.d.ts +2 -1
  7. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  8. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  9. package/dist/commands/audit.d.ts.map +1 -1
  10. package/dist/commands/audit.js +1 -2
  11. package/dist/commands/audit.js.map +1 -1
  12. package/dist/commands/claude/marketplace/git-publish.d.ts +5 -12
  13. package/dist/commands/claude/marketplace/git-publish.d.ts.map +1 -1
  14. package/dist/commands/claude/marketplace/git-publish.js +7 -80
  15. package/dist/commands/claude/marketplace/git-publish.js.map +1 -1
  16. package/dist/commands/claude/marketplace/publish-tree.d.ts +12 -4
  17. package/dist/commands/claude/marketplace/publish-tree.d.ts.map +1 -1
  18. package/dist/commands/claude/marketplace/publish-tree.js +54 -24
  19. package/dist/commands/claude/marketplace/publish-tree.js.map +1 -1
  20. package/dist/commands/claude/marketplace/publish.d.ts.map +1 -1
  21. package/dist/commands/claude/marketplace/publish.js +14 -39
  22. package/dist/commands/claude/marketplace/publish.js.map +1 -1
  23. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  24. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  25. package/dist/commands/claude/plugin/build.js +68 -4
  26. package/dist/commands/claude/plugin/build.js.map +1 -1
  27. package/dist/commands/consistency-check.d.ts +13 -0
  28. package/dist/commands/consistency-check.d.ts.map +1 -1
  29. package/dist/commands/consistency-check.js +98 -1
  30. package/dist/commands/consistency-check.js.map +1 -1
  31. package/dist/commands/corpus/runner.d.ts.map +1 -1
  32. package/dist/commands/corpus/runner.js +1 -2
  33. package/dist/commands/corpus/runner.js.map +1 -1
  34. package/dist/commands/corpus/seed.d.ts +24 -0
  35. package/dist/commands/corpus/seed.d.ts.map +1 -1
  36. package/dist/commands/corpus/seed.js +5 -0
  37. package/dist/commands/corpus/seed.js.map +1 -1
  38. package/dist/commands/resources/index.d.ts.map +1 -1
  39. package/dist/commands/resources/index.js +4 -1
  40. package/dist/commands/resources/index.js.map +1 -1
  41. package/dist/commands/resources/validate.d.ts.map +1 -1
  42. package/dist/commands/resources/validate.js +155 -112
  43. package/dist/commands/resources/validate.js.map +1 -1
  44. package/dist/commands/skill/index.d.ts.map +1 -1
  45. package/dist/commands/skill/index.js +2 -0
  46. package/dist/commands/skill/index.js.map +1 -1
  47. package/dist/commands/skill/review.js.map +1 -1
  48. package/dist/commands/skill/test/configure.d.ts +22 -0
  49. package/dist/commands/skill/test/configure.d.ts.map +1 -0
  50. package/dist/commands/skill/test/configure.js +127 -0
  51. package/dist/commands/skill/test/configure.js.map +1 -0
  52. package/dist/commands/skill/test/index.d.ts +6 -0
  53. package/dist/commands/skill/test/index.d.ts.map +1 -0
  54. package/dist/commands/skill/test/index.js +16 -0
  55. package/dist/commands/skill/test/index.js.map +1 -0
  56. package/dist/commands/skill/test/run.d.ts +40 -0
  57. package/dist/commands/skill/test/run.d.ts.map +1 -0
  58. package/dist/commands/skill/test/run.js +381 -0
  59. package/dist/commands/skill/test/run.js.map +1 -0
  60. package/dist/commands/skills/skill-discovery.d.ts +9 -2
  61. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  62. package/dist/commands/skills/skill-discovery.js +83 -18
  63. package/dist/commands/skills/skill-discovery.js.map +1 -1
  64. package/dist/utils/verdict-helpers.d.ts +2 -1
  65. package/dist/utils/verdict-helpers.d.ts.map +1 -1
  66. package/dist/utils/verdict-helpers.js +1 -1
  67. package/dist/utils/verdict-helpers.js.map +1 -1
  68. package/docs/resources.md +7 -3
  69. package/package.json +11 -11
  70. package/dist/commands/claude/marketplace/tag-utils.d.ts +0 -11
  71. package/dist/commands/claude/marketplace/tag-utils.d.ts.map +0 -1
  72. package/dist/commands/claude/marketplace/tag-utils.js +0 -17
  73. package/dist/commands/claude/marketplace/tag-utils.js.map +0 -1
  74. package/dist/utils/git-url.d.ts +0 -43
  75. package/dist/utils/git-url.d.ts.map +0 -1
  76. package/dist/utils/git-url.js +0 -135
  77. package/dist/utils/git-url.js.map +0 -1
@@ -0,0 +1,16 @@
1
+ /**
2
+ * `vat skill test` command group — behavioral testing of packaged skills in isolation.
3
+ */
4
+ import { Command } from 'commander';
5
+ import { createSkillTestConfigureCommand } from './configure.js';
6
+ import { createSkillTestRunCommand } from './run.js';
7
+ export function createSkillTestCommand() {
8
+ const command = new Command('test');
9
+ command
10
+ .description('Behaviorally test a packaged skill in isolation (run) or configure its test block (configure)')
11
+ .helpCommand(false);
12
+ command.addCommand(createSkillTestRunCommand());
13
+ command.addCommand(createSkillTestConfigureCommand());
14
+ return command;
15
+ }
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/commands/skill/test/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAErD,MAAM,UAAU,sBAAsB;IACpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO;SACJ,WAAW,CACV,+FAA+F,CAChG;SACA,WAAW,CAAC,KAAK,CAAC,CAAC;IACtB,OAAO,CAAC,UAAU,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,UAAU,CAAC,+BAA+B,EAAE,CAAC,CAAC;IACtD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,40 @@
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 { Command } from 'commander';
9
+ export interface SkillTestRunOptions {
10
+ with?: string[];
11
+ withOptional?: string[];
12
+ refresh?: boolean;
13
+ workdir?: string;
14
+ out?: string;
15
+ keep?: boolean;
16
+ dryRun?: boolean;
17
+ auth?: string;
18
+ requireAuth?: string;
19
+ baseline?: boolean;
20
+ allowUnverifiedSkillSource?: boolean;
21
+ iUnderstandThisRunsSkillCode?: boolean;
22
+ model?: string;
23
+ maxTurns?: string;
24
+ maxBudgetUsd?: string;
25
+ timeout?: string;
26
+ stall?: string;
27
+ debug?: boolean;
28
+ env?: string[];
29
+ passEnv?: string[];
30
+ }
31
+ /**
32
+ * The unit-testable action for `vat skill test run`. Exported so tests can
33
+ * call it directly without parsing CLI args. Calls process.exit on completion.
34
+ *
35
+ * Note: the security ack enforcement lives inside runSkillTestHarness (domain),
36
+ * NOT here — this ensures the mock in tests can bypass it cleanly.
37
+ */
38
+ export declare function runSkillTestRun(skills: string[], options: SkillTestRunOptions): Promise<void>;
39
+ export declare function createSkillTestRunCommand(): Command;
40
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../../src/commands/skill/test/run.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAuSD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAMD,wBAAgB,yBAAyB,IAAI,OAAO,CAkEnD"}
@@ -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":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAEjH,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAE7D,kFAAkF;AAClF,SAAS,eAAe,CAAC,CAAS;IAChC,OAAO,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,MAAM,gBAAgB,GAAG;;;;;CAKxB,CAAC,IAAI,EAAE,CAAC;AAET,SAAS,oBAAoB;IAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,GAAG,MAAM,CAAC,CAAC;AAClD,CAAC;AA6BD,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,SAAS,iBAAiB,CAAC,KAAyB,EAAE,QAAgB;IACpE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,qCAAqC,KAAK,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAyB,EAAE,QAAgB;IACtE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,oCAAoC,KAAK,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,WAAW,CAAC,OAA4B;IAM/C,MAAM,MAAM,GAKR,EAAE,CAAC;IAEP,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IACpE,IAAI,QAAQ,KAAK,SAAS;QAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAEvD,MAAM,YAAY,GAAG,mBAAmB,CAAC,OAAO,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC;IACnF,IAAI,YAAY,KAAK,SAAS;QAAE,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;IAEnE,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChE,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;IAEpD,MAAM,KAAK,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC1D,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC;IAE9C,OAAO,MAAM,CAAC;AAChB,CAAC;AASD;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,iHAAiH,IAAI,EAAE,CACxH,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,kFAAkF;AAClF,SAAS,eAAe,CAAC,GAAW,EAAE,QAAgB;IACpD,IAAI,GAAG,KAAK,UAAU;QAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAClD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACvD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACrF,KAAK,KAAK,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACzE,KAAK,MAAM,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3E,KAAK,KAAK,CAAC,CAAC,OAAO,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QACzE;YACE,MAAM,IAAI,KAAK,CACb,2EAA2E,QAAQ,EAAE,CACtF,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAa,EAAE,QAAgB,EAAE,KAA4B;IACjF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,KAAK,EAAE,CAAC;AACjB,CAAC;AAED,wEAAwE;AACxE,SAAS,cAAc,CAAC,KAA2B;IACjD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qFAAqF;AACrF,SAAS,cAAc,CAAC,CAAwB;IAC9C,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,SAAS,CAAC;IACzC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACrD,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;IAC1D,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,SAAS,CAAC;IACjC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,6EAA6E;AAC7E,SAAS,mBAAmB,CAC1B,IAAyC;IAEzC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9D,MAAM,MAAM,GAAoC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAoB,CAAC;IACvE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,iDAAiD;AACjD,8EAA8E;AAE9E;;;;;GAKG;AACH,SAAS,cAAc,CAAC,MAAgB;IACtC,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IAC3C,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC,CAAC,6CAA6C;IACjE,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IACxC,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC;IACjD,OAAO,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC;AACzD,CAAC;AAED,oEAAoE;AACpE,SAAS,eAAe;IACtB,OAAO,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;AACzD,CAAC;AAED,4EAA4E;AAC5E,SAAS,oBAAoB,CAAC,IAAiB,EAAE,OAA4B;IAC3E,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAClE,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAClE,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IACtD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS;QAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/D,IAAI,OAAO,CAAC,0BAA0B,KAAK,SAAS;QAAE,IAAI,CAAC,0BAA0B,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAC3H,IAAI,OAAO,CAAC,4BAA4B,KAAK,SAAS;QAAE,IAAI,CAAC,yBAAyB,GAAG,OAAO,CAAC,4BAA4B,CAAC;AAChI,CAAC;AAED,sFAAsF;AACtF,SAAS,iBAAiB,CAAC,IAAiB,EAAE,OAA4B,EAAE,MAA8B;IACxG,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,IAAI,MAAM,EAAE,IAAI,CAAC;IAC9C,IAAI,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,IAAI,GAAG,QAA2D,CAAC;IACpG,MAAM,eAAe,GAAG,OAAO,CAAC,WAAW,IAAI,MAAM,EAAE,WAAW,CAAC;IACnE,IAAI,eAAe,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,eAA6C,CAAC;IACpG,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ,CAAC;IACtD,IAAI,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,EAAE,KAAK,CAAC;IAC7C,IAAI,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAC5C,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;IAClE,IAAI,MAAM,EAAE,kBAAkB,KAAK,SAAS;QAAE,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,kBAAkB,CAAC;IAC9F,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AAC7D,CAAC;AAED,+EAA+E;AAC/E,SAAS,eAAe,CACtB,IAAiB,EACjB,KAAqC,EACrC,MAA8B;IAE9B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,MAAM,EAAE,QAAQ,CAAC;IACpD,IAAI,QAAQ,KAAK,SAAS;QAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACrD,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,MAAM,EAAE,YAAY,CAAC;IAChE,IAAI,YAAY,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACjE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,EAAE,OAAO,CAAC;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAClD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,MAAM,EAAE,KAAK,CAAC;IAC3C,IAAI,KAAK,KAAK,SAAS;QAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,uGAAuG,IAAI,EAAE,CAC9G,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,kFAAkF;AAClF,SAAS,aAAa,CAAC,KAA2B;IAChD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAChE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,SAAS,QAAQ,CACf,SAA6C,EAC7C,MAA0C;IAE1C,IAAI,SAAS,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtE,OAAO,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;AACrD,CAAC;AAED,wEAAwE;AACxE,SAAS,YAAY,CACnB,UAAgC,EAChC,OAA6B;IAE7B,IAAI,UAAU,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AAED,2EAA2E;AAC3E,SAAS,cAAc,CAAC,IAAiB,EAAE,OAA4B,EAAE,MAA8B;IACrG,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,IAAI,GAAG,KAAK,SAAS;QAAE,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACtC,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D,IAAI,OAAO,KAAK,SAAS;QAAE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;AACpD,CAAC;AAED,gEAAgE;AAChE,SAAS,cAAc,CAAC,IAAiB,EAAE,OAA4B,EAAE,MAA8B;IACrG,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACtF,IAAI,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IAC9D,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnG,IAAI,YAAY,KAAK,SAAS;QAAE,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;AACnE,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,MAAgB,EAChB,OAA4B,EAC5B,KAAqC,EACrC,MAA8B;IAE9B,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,MAAM,IAAI,GAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC/C,+EAA+E;IAC/E,kFAAkF;IAClF,kFAAkF;IAClF,8DAA8D;IAC9D,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;IAC3B,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACpC,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACzC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACrC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAgB,EAChB,OAA4B;IAE5B,oBAAoB,EAAE,CAAC;IAEvB,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,WAAW,CAAC,CAAC;QAEtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC;QACzD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;QACzC,2EAA2E;QAC3E,0EAA0E;QAC1E,IAAI,GAAG,YAAY,oBAAoB,EAAE,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO;IACT,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,MAAM,UAAU,yBAAyB;IACvC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAEnC,OAAO;SACJ,WAAW,CAAC,0EAA0E,CAAC;SACvF,QAAQ,CAAC,YAAY,EAAE,6CAA6C,CAAC;SACrE,MAAM,CACL,kBAAkB,EAClB,iKAAiK,CAClK;SACA,MAAM,CACL,2BAA2B,EAC3B,gEAAgE,CACjE;SACA,MAAM,CACL,iBAAiB,EACjB,kMAAkM,CACnM;SACA,MAAM,CACL,qBAAqB,EACrB,oIAAoI,CACrI;SACA,MAAM,CAAC,WAAW,EAAE,wDAAwD,CAAC;SAC7E,MAAM,CAAC,iBAAiB,EAAE,wCAAwC,CAAC;SACnE,MAAM,CAAC,aAAa,EAAE,uCAAuC,CAAC;SAC9D,MAAM,CAAC,QAAQ,EAAE,0CAA0C,CAAC;SAC5D,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;SACnE,MAAM,CAAC,eAAe,EAAE,yDAAyD,CAAC;SAClF,MAAM,CAAC,uBAAuB,EAAE,2DAA2D,CAAC;SAC5F,MAAM,CAAC,YAAY,EAAE,8CAA8C,CAAC;SACpE,MAAM,CAAC,iCAAiC,EAAE,4CAA4C,CAAC;SACvF,MAAM,CAAC,qCAAqC,EAAE,yDAAyD,CAAC;SACxG,MAAM,CAAC,cAAc,EAAE,0BAA0B,CAAC;SAClD,MAAM,CAAC,iBAAiB,EAAE,8CAA8C,CAAC;SACzE,MAAM,CAAC,sBAAsB,EAAE,uCAAuC,CAAC;SACvE,MAAM,CAAC,eAAe,EAAE,kDAAkD,CAAC;SAC3E,MAAM,CAAC,aAAa,EAAE,8CAA8C,CAAC;SACrE,MAAM,CAAC,SAAS,EAAE,sBAAsB,CAAC;SACzC,MAAM,CAAC,eAAe,CAAC;SACvB,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;CAqBL,CACI,CAAC;IAEJ,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -9,8 +9,15 @@ import type { DiscoveredSkill } from './command-helpers.js';
9
9
  /**
10
10
  * Discover skills from config yaml skills section.
11
11
  *
12
- * Uses crawlDirectory from utils for glob matching (picomatch-based,
13
- * cross-platform, no additional dependencies).
12
+ * Each include pattern is resolved against `projectRoot` and may step out of
13
+ * the package via `..` (e.g. `"../../docs/skills/*\/SKILL.md"` in a monorepo
14
+ * where SKILL.md files live alongside, not inside, the package). Patterns are
15
+ * grouped by their effective scan root so `crawlDirectory` is invoked once per
16
+ * root rather than blindly walking from `projectRoot`.
17
+ *
18
+ * User-supplied excludes are matched against paths relative to `projectRoot`
19
+ * so anchored excludes like `docs/private/**` keep their original meaning
20
+ * regardless of which scan root produced the candidate file.
14
21
  *
15
22
  * @param skillsConfig - The skills section from vibe-agent-toolkit.config.yaml
16
23
  * @param projectRoot - Absolute path to project root (where config yaml lives)
@@ -1 +1 @@
1
- {"version":3,"file":"skill-discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/skill-discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAiC5D;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,EAAE,CAAC,CA0B5B"}
1
+ {"version":3,"file":"skill-discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/skills/skill-discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAIlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AA2F5D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,YAAY,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,EAAE,CAAC,CA0B5B"}
@@ -4,10 +4,12 @@
4
4
  * Reads skills.include/exclude glob patterns from vibe-agent-toolkit.config.yaml,
5
5
  * finds matching SKILL.md files, and extracts skill names from frontmatter.
6
6
  */
7
+ import { existsSync } from 'node:fs';
7
8
  import { readFile } from 'node:fs/promises';
8
9
  import { basename } from 'node:path';
9
10
  import { parseMarkdown } from '@vibe-agent-toolkit/resources';
10
- import { crawlDirectory } from '@vibe-agent-toolkit/utils';
11
+ import { crawlDirectory, safePath, toForwardSlash } from '@vibe-agent-toolkit/utils';
12
+ import picomatch from 'picomatch';
11
13
  /**
12
14
  * Directories that should always be excluded from skill discovery for performance.
13
15
  */
@@ -37,11 +39,70 @@ async function readSkillName(skillPath) {
37
39
  }
38
40
  return basename(skillPath, '.md');
39
41
  }
42
+ /**
43
+ * Split an include pattern into its literal base directory and its glob
44
+ * remainder. `picomatch.scan` already does the heavy lifting for proper
45
+ * glob patterns; the manual split handles pure-literal paths so a single
46
+ * SKILL.md file is still crawlable from its parent directory.
47
+ */
48
+ function splitIncludePattern(pattern) {
49
+ const scanned = picomatch.scan(pattern);
50
+ if (scanned.isGlob) {
51
+ return { base: scanned.base, glob: scanned.glob };
52
+ }
53
+ // Literal path (no glob metachars): match the file from its parent.
54
+ const slash = pattern.lastIndexOf('/');
55
+ if (slash === -1) {
56
+ return { base: '', glob: pattern };
57
+ }
58
+ return { base: pattern.slice(0, slash), glob: pattern.slice(slash + 1) };
59
+ }
60
+ /**
61
+ * Group include patterns by their effective scan root. Each pattern's literal
62
+ * prefix (resolved against `projectRoot`) becomes the absolute scan root for
63
+ * its glob remainder, which is what lets `..` segments escape `projectRoot`.
64
+ */
65
+ function groupIncludePatternsByBase(include, projectRoot) {
66
+ const patternsByBase = new Map();
67
+ for (const pattern of include) {
68
+ const { base, glob } = splitIncludePattern(pattern);
69
+ const absBase = safePath.resolve(projectRoot, base || '.');
70
+ const effectiveGlob = glob.length > 0 ? glob : '**/*';
71
+ const existing = patternsByBase.get(absBase) ?? [];
72
+ existing.push(effectiveGlob);
73
+ patternsByBase.set(absBase, existing);
74
+ }
75
+ return patternsByBase;
76
+ }
77
+ /**
78
+ * Crawl one effective scan root. Returns absolute paths, or an empty array if
79
+ * the root does not exist (mirrors audit's filesystem-first tolerance for
80
+ * patterns pointing at nothing).
81
+ */
82
+ async function crawlOneBase(base, globs) {
83
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- base derived from validated config
84
+ if (!existsSync(base)) {
85
+ return [];
86
+ }
87
+ return crawlDirectory({
88
+ baseDir: base,
89
+ include: globs,
90
+ exclude: DISCOVERY_EXCLUDE,
91
+ dot: true,
92
+ });
93
+ }
40
94
  /**
41
95
  * Discover skills from config yaml skills section.
42
96
  *
43
- * Uses crawlDirectory from utils for glob matching (picomatch-based,
44
- * cross-platform, no additional dependencies).
97
+ * Each include pattern is resolved against `projectRoot` and may step out of
98
+ * the package via `..` (e.g. `"../../docs/skills/*\/SKILL.md"` in a monorepo
99
+ * where SKILL.md files live alongside, not inside, the package). Patterns are
100
+ * grouped by their effective scan root so `crawlDirectory` is invoked once per
101
+ * root rather than blindly walking from `projectRoot`.
102
+ *
103
+ * User-supplied excludes are matched against paths relative to `projectRoot`
104
+ * so anchored excludes like `docs/private/**` keep their original meaning
105
+ * regardless of which scan root produced the candidate file.
45
106
  *
46
107
  * @param skillsConfig - The skills section from vibe-agent-toolkit.config.yaml
47
108
  * @param projectRoot - Absolute path to project root (where config yaml lives)
@@ -49,23 +110,27 @@ async function readSkillName(skillPath) {
49
110
  */
50
111
  export async function discoverSkillsFromConfig(skillsConfig, projectRoot) {
51
112
  const { include, exclude } = skillsConfig;
52
- // Discover SKILL.md files using crawlDirectory (picomatch globs)
53
- const skillPaths = await crawlDirectory({
54
- baseDir: projectRoot,
55
- include,
56
- exclude: [
57
- ...DISCOVERY_EXCLUDE,
58
- ...(exclude ?? []),
59
- ],
60
- dot: true, // Match through dot-directories (e.g., .claude/worktrees/)
61
- });
113
+ const patternsByBase = groupIncludePatternsByBase(include, projectRoot);
114
+ const userExcludeMatcher = exclude && exclude.length > 0
115
+ ? picomatch(exclude, { dot: true })
116
+ : null;
117
+ const foundAbsPaths = new Set();
118
+ for (const [base, globs] of patternsByBase) {
119
+ const crawled = await crawlOneBase(base, globs);
120
+ for (const absPath of crawled) {
121
+ if (userExcludeMatcher) {
122
+ const relFromProject = toForwardSlash(safePath.relative(projectRoot, absPath));
123
+ if (userExcludeMatcher(relFromProject))
124
+ continue;
125
+ }
126
+ foundAbsPaths.add(safePath.resolve(absPath));
127
+ }
128
+ }
62
129
  const discovered = [];
63
- for (const skillPath of skillPaths) {
130
+ for (const skillPath of foundAbsPaths) {
64
131
  const name = await readSkillName(skillPath);
65
- if (!name) {
66
- continue;
67
- }
68
- discovered.push({ name, sourcePath: skillPath });
132
+ if (name)
133
+ discovered.push({ name, sourcePath: skillPath });
69
134
  }
70
135
  return discovered;
71
136
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skill-discovery.js","sourceRoot":"","sources":["../../../src/commands/skills/skill-discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D;;GAEG;AACH,MAAM,iBAAiB,GAAG;IACxB,oBAAoB;IACpB,YAAY;IACZ,YAAY;IACZ,gBAAgB;CACjB,CAAC;AAEF;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,SAAiB;IAC5C,oGAAoG;IACpG,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;IAC1C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,yBAAyB;IACzB,kGAAkG;IAClG,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChD,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjB,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IACD,OAAO,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,YAA0B,EAC1B,WAAmB;IAEnB,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC;IAE1C,iEAAiE;IACjE,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC;QACtC,OAAO,EAAE,WAAW;QACpB,OAAO;QACP,OAAO,EAAE;YACP,GAAG,iBAAiB;YACpB,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;SACnB;QACD,GAAG,EAAE,IAAI,EAAE,2DAA2D;KACvE,CAAC,CAAC;IAEH,MAAM,UAAU,GAAsB,EAAE,CAAC;IAEzC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS;QACX,CAAC;QAED,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"skill-discovery.js","sourceRoot":"","sources":["../../../src/commands/skills/skill-discovery.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,8 @@
12
12
  * nor in marketplace (which knows nothing about config-level packaging
13
13
  * options).
14
14
  */
15
- import { type Observation, type PackagingValidationResult, type ValidationIssue } from '@vibe-agent-toolkit/agent-skills';
15
+ import { type ValidationIssue } from '@vibe-agent-toolkit/agent-schema';
16
+ import { type Observation, type PackagingValidationResult } from '@vibe-agent-toolkit/agent-skills';
16
17
  import { type Target, type Verdict } from '@vibe-agent-toolkit/claude-marketplace';
17
18
  /**
18
19
  * Convert a verdict into a ValidationIssue using CODE_REGISTRY for severity,