@vibe-agent-toolkit/cli 0.1.33 → 0.1.34

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 (68) hide show
  1. package/dist/bin.js +4 -0
  2. package/dist/bin.js.map +1 -1
  3. package/dist/commands/audit/git-url-clone.d.ts +32 -0
  4. package/dist/commands/audit/git-url-clone.d.ts.map +1 -0
  5. package/dist/commands/audit/git-url-clone.js +135 -0
  6. package/dist/commands/audit/git-url-clone.js.map +1 -0
  7. package/dist/commands/audit/hierarchical-output.js +2 -2
  8. package/dist/commands/audit/hierarchical-output.js.map +1 -1
  9. package/dist/commands/audit/provenance.d.ts +33 -0
  10. package/dist/commands/audit/provenance.d.ts.map +1 -0
  11. package/dist/commands/audit/provenance.js +57 -0
  12. package/dist/commands/audit/provenance.js.map +1 -0
  13. package/dist/commands/audit.d.ts.map +1 -1
  14. package/dist/commands/audit.js +257 -34
  15. package/dist/commands/audit.js.map +1 -1
  16. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  17. package/dist/commands/claude/marketplace/validate.js +2 -1
  18. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  19. package/dist/commands/claude/plugin/build.d.ts +4 -3
  20. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  21. package/dist/commands/claude/plugin/build.js +178 -71
  22. package/dist/commands/claude/plugin/build.js.map +1 -1
  23. package/dist/commands/claude/plugin/plugin-files.d.ts +19 -0
  24. package/dist/commands/claude/plugin/plugin-files.d.ts.map +1 -0
  25. package/dist/commands/claude/plugin/plugin-files.js +53 -0
  26. package/dist/commands/claude/plugin/plugin-files.js.map +1 -0
  27. package/dist/commands/claude/plugin/plugin-json-merge.d.ts +29 -0
  28. package/dist/commands/claude/plugin/plugin-json-merge.d.ts.map +1 -0
  29. package/dist/commands/claude/plugin/plugin-json-merge.js +76 -0
  30. package/dist/commands/claude/plugin/plugin-json-merge.js.map +1 -0
  31. package/dist/commands/claude/plugin/plugin-validators.d.ts +13 -0
  32. package/dist/commands/claude/plugin/plugin-validators.d.ts.map +1 -0
  33. package/dist/commands/claude/plugin/plugin-validators.js +59 -0
  34. package/dist/commands/claude/plugin/plugin-validators.js.map +1 -0
  35. package/dist/commands/claude/plugin/tree-copy.d.ts +23 -0
  36. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -0
  37. package/dist/commands/claude/plugin/tree-copy.js +68 -0
  38. package/dist/commands/claude/plugin/tree-copy.js.map +1 -0
  39. package/dist/commands/corpus/index.d.ts +6 -0
  40. package/dist/commands/corpus/index.d.ts.map +1 -0
  41. package/dist/commands/corpus/index.js +53 -0
  42. package/dist/commands/corpus/index.js.map +1 -0
  43. package/dist/commands/corpus/report.d.ts +75 -0
  44. package/dist/commands/corpus/report.d.ts.map +1 -0
  45. package/dist/commands/corpus/report.js +83 -0
  46. package/dist/commands/corpus/report.js.map +1 -0
  47. package/dist/commands/corpus/runner.d.ts +24 -0
  48. package/dist/commands/corpus/runner.d.ts.map +1 -0
  49. package/dist/commands/corpus/runner.js +246 -0
  50. package/dist/commands/corpus/runner.js.map +1 -0
  51. package/dist/commands/corpus/scan.d.ts +15 -0
  52. package/dist/commands/corpus/scan.d.ts.map +1 -0
  53. package/dist/commands/corpus/scan.js +90 -0
  54. package/dist/commands/corpus/scan.js.map +1 -0
  55. package/dist/commands/corpus/seed.d.ts +178 -0
  56. package/dist/commands/corpus/seed.d.ts.map +1 -0
  57. package/dist/commands/corpus/seed.js +63 -0
  58. package/dist/commands/corpus/seed.js.map +1 -0
  59. package/dist/commands/inventory.d.ts +17 -0
  60. package/dist/commands/inventory.d.ts.map +1 -0
  61. package/dist/commands/inventory.js +90 -0
  62. package/dist/commands/inventory.js.map +1 -0
  63. package/dist/utils/git-url.d.ts +43 -0
  64. package/dist/utils/git-url.d.ts.map +1 -0
  65. package/dist/utils/git-url.js +135 -0
  66. package/dist/utils/git-url.js.map +1 -0
  67. package/docs/audit.md +60 -3
  68. package/package.json +11 -11
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Per-plugin orchestrator for `vat corpus scan`.
3
+ *
4
+ * Phase 1 scope: resolve source (local or URL), optionally overlay a
5
+ * synthetic `vibe-agent-toolkit.config.yaml` from the entry's `validation:`
6
+ * block, run `vat audit` in-process, optionally invoke `vat skill review`,
7
+ * write per-plugin sibling files into the run directory, and return a
8
+ * PluginRow. Per-plugin failures never abort the loop.
9
+ *
10
+ * URL handling clones via Layer 1's `withClonedRepo` helper. Validation
11
+ * overlay (Task 5) is added on top of this base.
12
+ */
13
+ import { spawnSync } from 'node:child_process';
14
+ import { existsSync, writeFileSync } from 'node:fs';
15
+ import { dirname } from 'node:path';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { scan } from '@vibe-agent-toolkit/discovery';
18
+ import { safePath } from '@vibe-agent-toolkit/utils';
19
+ import * as yaml from 'js-yaml';
20
+ import { isGitUrl, parseGitUrl } from '../../utils/git-url.js';
21
+ import { createLogger } from '../../utils/logger.js';
22
+ import { withClonedRepo } from '../audit/git-url-clone.js';
23
+ import { getValidationResults } from '../audit.js';
24
+ const __dirname = dirname(fileURLToPath(import.meta.url));
25
+ /**
26
+ * Resolve the path to the built vat CLI entry. Works whether the runner is
27
+ * invoked from compiled dist (production) or from source under vitest. In
28
+ * either case we always invoke the *compiled* `dist/bin.js` — `node` cannot
29
+ * execute `.ts` directly, so the source-tree fallback walks across to
30
+ * `packages/cli/dist/bin.js`. A build is therefore required before tests that
31
+ * exercise the review path can pass.
32
+ */
33
+ function resolveVatBinPath() {
34
+ // Compiled tree: packages/cli/dist/commands/corpus/runner.js → packages/cli/dist/bin.js
35
+ const compiled = safePath.resolve(__dirname, '../../bin.js');
36
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- internal path
37
+ if (existsSync(compiled))
38
+ return compiled;
39
+ // Source tree (vitest): packages/cli/src/commands/corpus/runner.ts → packages/cli/dist/bin.js
40
+ return safePath.resolve(__dirname, '../../../dist/bin.js');
41
+ }
42
+ const SKIPPED_REVIEW = { status: 'skipped', duration_ms: 0 };
43
+ function statusFromCounts(errors, warnings) {
44
+ if (errors > 0)
45
+ return 'error';
46
+ if (warnings > 0)
47
+ return 'warning';
48
+ return 'success';
49
+ }
50
+ function summarizeResults(results) {
51
+ let errors = 0;
52
+ let warnings = 0;
53
+ let info = 0;
54
+ for (const r of results) {
55
+ for (const issue of r.issues ?? []) {
56
+ if (issue.severity === 'error')
57
+ errors += 1;
58
+ else if (issue.severity === 'warning')
59
+ warnings += 1;
60
+ else if (issue.severity === 'info')
61
+ info += 1;
62
+ }
63
+ }
64
+ return { errors, warnings, info, files_scanned: results.length };
65
+ }
66
+ /**
67
+ * Run audit + optional review against one plugin entry.
68
+ */
69
+ export async function auditOnePlugin(entry, opts) {
70
+ if (isGitUrl(entry.source)) {
71
+ return runUrlEntry(entry, opts);
72
+ }
73
+ return runLocalEntry(entry, opts);
74
+ }
75
+ async function runLocalEntry(entry, opts) {
76
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller-supplied seed entry
77
+ if (!existsSync(entry.source)) {
78
+ return unloadableRow(entry, `Source path not found: ${entry.source}`, 0);
79
+ }
80
+ return auditAndRecord(entry, entry.source, opts);
81
+ }
82
+ async function runUrlEntry(entry, opts) {
83
+ try {
84
+ return await withClonedRepo(parseGitUrl(entry.source), { keepTempForDebug: opts.debug }, async ({ targetDir }) => auditAndRecord(entry, targetDir, opts));
85
+ }
86
+ catch (err) {
87
+ return unloadableRow(entry, err instanceof Error ? err.message : String(err), 0);
88
+ }
89
+ }
90
+ async function auditAndRecord(entry, scanPath, opts) {
91
+ const logger = createLogger(opts.debug ? { debug: true } : {});
92
+ const start = Date.now();
93
+ const validationApplied = applyValidationOverlay(entry, scanPath);
94
+ let audit;
95
+ try {
96
+ const results = await getValidationResults(scanPath, true, {}, logger);
97
+ const summary = summarizeResults(results);
98
+ const status = statusFromCounts(summary.errors, summary.warnings);
99
+ const auditYamlPath = safePath.join(opts.runDir, `${entry.name}-audit.yaml`);
100
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- composed under run dir
101
+ writeFileSync(auditYamlPath, yaml.dump({ results }, { lineWidth: -1 }), 'utf-8');
102
+ audit = {
103
+ status,
104
+ duration_ms: Date.now() - start,
105
+ summary,
106
+ findings_emitted: summary.errors + summary.warnings + summary.info,
107
+ output_path: `${entry.name}-audit.yaml`,
108
+ };
109
+ }
110
+ catch (err) {
111
+ audit = {
112
+ status: 'unloadable',
113
+ duration_ms: Date.now() - start,
114
+ error: err instanceof Error ? err.message : String(err),
115
+ };
116
+ }
117
+ // Skip review when audit was unloadable — nothing meaningful to review.
118
+ const review = opts.withReview && audit.status !== 'unloadable'
119
+ ? await runSkillReview(entry, scanPath, opts.runDir)
120
+ : SKIPPED_REVIEW;
121
+ return {
122
+ source: entry.source,
123
+ name: entry.name,
124
+ validation_applied: validationApplied,
125
+ audit,
126
+ review,
127
+ };
128
+ }
129
+ /**
130
+ * Spawn `vat skill review <skillDir>` for one skill and return a markdown
131
+ * section describing the result. Subprocess failure is captured as an
132
+ * error section rather than thrown — one bad skill must not abort siblings.
133
+ */
134
+ function reviewOneSkill(bin, skillDir, relativePath) {
135
+ // eslint-disable-next-line sonarjs/no-os-command-from-path -- node is required for invoking vat
136
+ const result = spawnSync('node', [bin, 'skill', 'review', skillDir], {
137
+ encoding: 'utf-8',
138
+ stdio: ['ignore', 'pipe', 'pipe'],
139
+ });
140
+ // `vat skill review` exit semantics:
141
+ // 0 — review clean
142
+ // 1 — review completed but found warnings/errors (still a successful review for corpus purposes)
143
+ // 2 (or other non-zero / null) — system error, the review did not run to completion
144
+ const SKILL_REVIEW_FINDINGS_EXIT = 1;
145
+ const reviewRan = result.status === 0 || result.status === SKILL_REVIEW_FINDINGS_EXIT;
146
+ if (!reviewRan) {
147
+ const stderr = (result.stderr ?? '').trim();
148
+ const message = stderr || `vat skill review exited with code ${result.status ?? 'unknown'}`;
149
+ const stdout = (result.stdout ?? '').trim();
150
+ const stdoutBlock = stdout ? `\n\n${stdout}` : '';
151
+ const body = `**[review failed]**\n\n${message}${stdoutBlock}`;
152
+ return { relativePath, ok: false, body };
153
+ }
154
+ const body = ((result.stdout ?? '') + (result.stderr ?? '')).trim();
155
+ return { relativePath, ok: true, body };
156
+ }
157
+ function renderAggregatedReview(entry, sections, okCount) {
158
+ const header = `# Skill review: ${entry.name}\n\nReviewed ${okCount} of ${sections.length} skills (${sections.length - okCount} errors).\n`;
159
+ const rendered = sections
160
+ .map((s) => `\n---\n\n## ${s.relativePath}\n\n${s.body}\n`)
161
+ .join('');
162
+ return `${header}${rendered}`;
163
+ }
164
+ /**
165
+ * Discover every SKILL.md under `scanPath` (recursive, gitignore-aware) and
166
+ * invoke `vat skill review` once per skill directory. Concatenate the
167
+ * outputs into `<name>-review.md` with a section per skill keyed by the
168
+ * skill's path relative to the plugin root.
169
+ *
170
+ * Per-skill subprocess failures become error sections; the aggregate is
171
+ * still written so users can see which skills passed and which failed.
172
+ * Returns `status: 'error'` only when no skills were discovered or every
173
+ * subprocess failed.
174
+ */
175
+ async function runSkillReview(entry, scanPath, runDir) {
176
+ const start = Date.now();
177
+ const bin = resolveVatBinPath();
178
+ const reviewPath = safePath.join(runDir, `${entry.name}-review.md`);
179
+ const summary = await scan({ path: scanPath, recursive: true });
180
+ const skills = summary.results.filter((r) => r.format === 'agent-skill' && !r.isGitIgnored);
181
+ if (skills.length === 0) {
182
+ return {
183
+ status: 'error',
184
+ duration_ms: Date.now() - start,
185
+ error: `No SKILL.md files found under ${scanPath}`,
186
+ };
187
+ }
188
+ const sections = [];
189
+ for (const skill of skills) {
190
+ const skillDir = dirname(skill.path);
191
+ sections.push(reviewOneSkill(bin, skillDir, skill.relativePath));
192
+ }
193
+ const okCount = sections.filter((s) => s.ok).length;
194
+ const aggregated = renderAggregatedReview(entry, sections, okCount);
195
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- composed under run dir
196
+ writeFileSync(reviewPath, aggregated, 'utf-8');
197
+ if (okCount === 0) {
198
+ const errors = sections
199
+ .map((s) => `${s.relativePath}: ${s.body.replaceAll('\n', ' ').slice(0, 200)}`)
200
+ .join('; ');
201
+ return {
202
+ status: 'error',
203
+ duration_ms: Date.now() - start,
204
+ error: `All ${sections.length} skill reviews failed. ${errors}`,
205
+ output_path: `${entry.name}-review.md`,
206
+ };
207
+ }
208
+ return {
209
+ status: 'ok',
210
+ duration_ms: Date.now() - start,
211
+ output_path: `${entry.name}-review.md`,
212
+ };
213
+ }
214
+ /**
215
+ * Write a synthetic `vibe-agent-toolkit.config.yaml` at the audit target,
216
+ * placing the entry's `validation:` block under `skills.defaults.validation`.
217
+ * Returns true iff the overlay was written.
218
+ *
219
+ * Phase 1: clobbers any pre-existing config in the cloned tree. Merging
220
+ * with author-shipped configs is a follow-up.
221
+ */
222
+ function applyValidationOverlay(entry, scanPath) {
223
+ if (!entry.validation)
224
+ return false;
225
+ const overlayPath = safePath.join(scanPath, 'vibe-agent-toolkit.config.yaml');
226
+ const overlay = {
227
+ skills: {
228
+ defaults: {
229
+ validation: entry.validation,
230
+ },
231
+ },
232
+ };
233
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- composed under audit target
234
+ writeFileSync(overlayPath, yaml.dump(overlay, { lineWidth: -1 }), 'utf-8');
235
+ return true;
236
+ }
237
+ function unloadableRow(entry, error, durationMs) {
238
+ return {
239
+ source: entry.source,
240
+ name: entry.name,
241
+ validation_applied: false,
242
+ audit: { status: 'unloadable', duration_ms: durationMs, error },
243
+ review: SKIPPED_REVIEW,
244
+ };
245
+ }
246
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/commands/corpus/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAEhC,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAKnD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,SAAS,iBAAiB;IACxB,wFAAwF;IACxF,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAC7D,oFAAoF;IACpF,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1C,8FAA8F;IAC9F,OAAO,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC;AAC7D,CAAC;AAQD,MAAM,cAAc,GAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;AAE5E,SAAS,gBAAgB,CAAC,MAAc,EAAE,QAAgB;IACxD,IAAI,MAAM,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAC/B,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACnC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CACvB,OAA8D;IAE9D,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO;gBAAE,MAAM,IAAI,CAAC,CAAC;iBACvC,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS;gBAAE,QAAQ,IAAI,CAAC,CAAC;iBAChD,IAAI,KAAK,CAAC,QAAQ,KAAK,MAAM;gBAAE,IAAI,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,KAAkB,EAClB,IAAmB;IAEnB,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,KAAkB,EAAE,IAAmB;IAClE,iGAAiG;IACjG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,OAAO,aAAa,CAAC,KAAK,EAAE,0BAA0B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,KAAkB,EAAE,IAAmB;IAChE,IAAI,CAAC;QACH,OAAO,MAAM,cAAc,CACzB,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,EACzB,EAAE,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,EAChC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAChE,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,aAAa,CAAC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,KAAkB,EAClB,QAAgB,EAChB,IAAmB;IAEnB,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAElE,IAAI,KAAmB,CAAC;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,aAAa,CAAC,CAAC;QAC7E,6FAA6F;QAC7F,aAAa,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;QAEjF,KAAK,GAAG;YACN,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC/B,OAAO;YACP,gBAAgB,EAAE,OAAO,CAAC,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,OAAO,CAAC,IAAI;YAClE,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,aAAa;SACxC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,KAAK,GAAG;YACN,MAAM,EAAE,YAAY;YACpB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC/B,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,MAAM,MAAM,GACV,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY;QAC9C,CAAC,CAAC,MAAM,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC;QACpD,CAAC,CAAC,cAAc,CAAC;IAErB,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,kBAAkB,EAAE,iBAAiB;QACrC,KAAK;QACL,MAAM;KACP,CAAC;AACJ,CAAC;AAQD;;;;GAIG;AACH,SAAS,cAAc,CAAC,GAAW,EAAE,QAAgB,EAAE,YAAoB;IACzE,gGAAgG;IAChG,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE;QACnE,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAC;IAEH,qCAAqC;IACrC,qBAAqB;IACrB,mGAAmG;IACnG,sFAAsF;IACtF,MAAM,0BAA0B,GAAG,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,0BAA0B,CAAC;IAEtF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,IAAI,qCAAqC,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;QAC5F,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,0BAA0B,OAAO,GAAG,WAAW,EAAE,CAAC;QAC/D,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACpE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED,SAAS,sBAAsB,CAC7B,KAAkB,EAClB,QAA8B,EAC9B,OAAe;IAEf,MAAM,MAAM,GAAG,mBAAmB,KAAK,CAAC,IAAI,gBAAgB,OAAO,OAAO,QAAQ,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,GAAG,OAAO,aAAa,CAAC;IAC5I,MAAM,QAAQ,GAAG,QAAQ;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,YAAY,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC;SAC1D,IAAI,CAAC,EAAE,CAAC,CAAC;IACZ,OAAO,GAAG,MAAM,GAAG,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;;;;;GAUG;AACH,KAAK,UAAU,cAAc,CAC3B,KAAkB,EAClB,QAAgB,EAChB,MAAc;IAEd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,GAAG,GAAG,iBAAiB,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,YAAY,CAAC,CAAC;IAEpE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,CAAC,YAAY,CACrD,CAAC;IAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,MAAM,EAAE,OAAO;YACf,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC/B,KAAK,EAAE,iCAAiC,QAAQ,EAAE;SACnD,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IACpD,MAAM,UAAU,GAAG,sBAAsB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACpE,6FAA6F;IAC7F,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAE/C,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,QAAQ;aACpB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;aAC9E,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO;YACL,MAAM,EAAE,OAAO;YACf,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC/B,KAAK,EAAE,OAAO,QAAQ,CAAC,MAAM,0BAA0B,MAAM,EAAE;YAC/D,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,YAAY;SACvC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,MAAM,EAAE,IAAI;QACZ,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;QAC/B,WAAW,EAAE,GAAG,KAAK,CAAC,IAAI,YAAY;KACvC,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,sBAAsB,CAAC,KAAkB,EAAE,QAAgB;IAClE,IAAI,CAAC,KAAK,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAEpC,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,gCAAgC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG;QACd,MAAM,EAAE;YACN,QAAQ,EAAE;gBACR,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B;SACF;KACF,CAAC;IACF,kGAAkG;IAClG,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,KAAkB,EAAE,KAAa,EAAE,UAAkB;IAC1E,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,kBAAkB,EAAE,KAAK;QACzB,KAAK,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE;QAC/D,MAAM,EAAE,cAAc;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `vat corpus scan [seed-file] --out <dir>` — Phase 1 orchestrator.
3
+ *
4
+ * Reads the seed, delegates each entry to the runner sequentially,
5
+ * writes summary.yaml and per-plugin sibling files into a date-sha
6
+ * subdirectory of `--out`. Sequential by design — concurrency is a
7
+ * follow-up once the seed grows past ~50.
8
+ */
9
+ export interface CorpusScanOptions {
10
+ out?: string;
11
+ withReview?: boolean;
12
+ debug?: boolean;
13
+ }
14
+ export declare function corpusScanCommand(seedFileArg: string | undefined, options: CorpusScanOptions): Promise<void>;
15
+ //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/commands/corpus/scan.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAwBD,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Df"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * `vat corpus scan [seed-file] --out <dir>` — Phase 1 orchestrator.
3
+ *
4
+ * Reads the seed, delegates each entry to the runner sequentially,
5
+ * writes summary.yaml and per-plugin sibling files into a date-sha
6
+ * subdirectory of `--out`. Sequential by design — concurrency is a
7
+ * follow-up once the seed grows past ~50.
8
+ */
9
+ import { mkdirSync, readFileSync } from 'node:fs';
10
+ import { dirname } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { safeExecSync, safePath } from '@vibe-agent-toolkit/utils';
13
+ import { handleCommandError } from '../../utils/command-error.js';
14
+ import { createLogger } from '../../utils/logger.js';
15
+ import { writeRunReport } from './report.js';
16
+ import { auditOnePlugin } from './runner.js';
17
+ import { loadSeedFile } from './seed.js';
18
+ const DEFAULT_SEED_PATH = 'corpus/seed.yaml';
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ function readVatVersion() {
21
+ // packages/cli/dist/commands/corpus/scan.js → packages/cli/package.json
22
+ // packages/cli/src/commands/corpus/scan.ts → packages/cli/package.json
23
+ const pkgPath = safePath.resolve(__dirname, '../../../package.json');
24
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- internal package.json path
25
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
26
+ return pkg.version ?? 'unknown';
27
+ }
28
+ function readVatCommit() {
29
+ try {
30
+ const out = safeExecSync('git', ['rev-parse', '--short=8', 'HEAD'], { encoding: 'utf-8' });
31
+ return (typeof out === 'string' ? out : out.toString('utf-8')).trim();
32
+ }
33
+ catch {
34
+ return 'unknown';
35
+ }
36
+ }
37
+ export async function corpusScanCommand(seedFileArg, options) {
38
+ const logger = createLogger(options.debug ? { debug: true } : {});
39
+ const startTime = Date.now();
40
+ try {
41
+ if (!options.out) {
42
+ throw new Error('specify an output directory: --out <path>');
43
+ }
44
+ const seedPath = seedFileArg ?? DEFAULT_SEED_PATH;
45
+ const seed = loadSeedFile(seedPath);
46
+ // eslint-disable-next-line local/no-fs-mkdirSync, security/detect-non-literal-fs-filename -- caller-supplied output dir; recursive create is correct here
47
+ mkdirSync(options.out, { recursive: true });
48
+ // We need the run directory to write per-plugin files into during the
49
+ // loop. Build the report skeleton, derive the run dir name, create it,
50
+ // then run the loop.
51
+ const generatedAt = new Date().toISOString().replace(/\.\d+Z$/, 'Z');
52
+ const vatVersion = readVatVersion();
53
+ const vatCommit = readVatCommit();
54
+ const runDirName = `${generatedAt.slice(0, 10)}-${vatCommit}`;
55
+ const runDir = safePath.join(options.out, runDirName);
56
+ // eslint-disable-next-line local/no-fs-mkdirSync, security/detect-non-literal-fs-filename -- composed under user-supplied --out
57
+ mkdirSync(runDir, { recursive: true });
58
+ const rows = [];
59
+ for (const entry of seed.plugins) {
60
+ logger.info(`[${entry.name}] auditing ${entry.source}`);
61
+ const row = await auditOnePlugin(entry, {
62
+ runDir,
63
+ withReview: options.withReview === true,
64
+ debug: options.debug === true,
65
+ });
66
+ rows.push(row);
67
+ logger.info(`[${entry.name}] audit=${row.audit.status} review=${row.review.status}`);
68
+ }
69
+ const report = {
70
+ schema_version: 1,
71
+ generated_at: generatedAt,
72
+ vat_version: vatVersion,
73
+ vat_commit: vatCommit,
74
+ seed_file: seedPath,
75
+ flags: {
76
+ with_review: options.withReview === true,
77
+ debug: options.debug === true,
78
+ },
79
+ plugins: rows,
80
+ };
81
+ await writeRunReport(report, options.out);
82
+ logger.info(`Wrote run report to ${runDir}/summary.yaml`);
83
+ logger.info(` ${rows.length} plugins; durations recorded in summary.yaml`);
84
+ logger.debug(`Total scan duration: ${Date.now() - startTime}ms`);
85
+ }
86
+ catch (err) {
87
+ handleCommandError(err, logger, startTime, 'CorpusScan');
88
+ }
89
+ }
90
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/corpus/scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Seed schema + parser for `corpus/seed.yaml`. The seed is the committed
3
+ * config of plugins tracked by `vat corpus scan`. Per-entry `validation:`
4
+ * mirrors the `skills.defaults.validation` block of the project config
5
+ * schema (severity overrides + allow entries).
6
+ */
7
+ import { z } from 'zod';
8
+ declare const ValidationAllowEntrySchema: z.ZodObject<{
9
+ code: z.ZodString;
10
+ reason: z.ZodString;
11
+ }, "strip", z.ZodTypeAny, {
12
+ code: string;
13
+ reason: string;
14
+ }, {
15
+ code: string;
16
+ reason: string;
17
+ }>;
18
+ declare const ValidationBlockSchema: z.ZodObject<{
19
+ severity: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<["error", "warning", "info", "ignore"]>>>;
20
+ allow: z.ZodOptional<z.ZodArray<z.ZodObject<{
21
+ code: z.ZodString;
22
+ reason: z.ZodString;
23
+ }, "strip", z.ZodTypeAny, {
24
+ code: string;
25
+ reason: string;
26
+ }, {
27
+ code: string;
28
+ reason: string;
29
+ }>, "many">>;
30
+ }, "strict", z.ZodTypeAny, {
31
+ allow?: {
32
+ code: string;
33
+ reason: string;
34
+ }[] | undefined;
35
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
36
+ }, {
37
+ allow?: {
38
+ code: string;
39
+ reason: string;
40
+ }[] | undefined;
41
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
42
+ }>;
43
+ declare const PluginEntrySchema: z.ZodObject<{
44
+ source: z.ZodString;
45
+ name: z.ZodString;
46
+ validation: z.ZodOptional<z.ZodObject<{
47
+ severity: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<["error", "warning", "info", "ignore"]>>>;
48
+ allow: z.ZodOptional<z.ZodArray<z.ZodObject<{
49
+ code: z.ZodString;
50
+ reason: z.ZodString;
51
+ }, "strip", z.ZodTypeAny, {
52
+ code: string;
53
+ reason: string;
54
+ }, {
55
+ code: string;
56
+ reason: string;
57
+ }>, "many">>;
58
+ }, "strict", z.ZodTypeAny, {
59
+ allow?: {
60
+ code: string;
61
+ reason: string;
62
+ }[] | undefined;
63
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
64
+ }, {
65
+ allow?: {
66
+ code: string;
67
+ reason: string;
68
+ }[] | undefined;
69
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
70
+ }>>;
71
+ }, "strict", z.ZodTypeAny, {
72
+ name: string;
73
+ source: string;
74
+ validation?: {
75
+ allow?: {
76
+ code: string;
77
+ reason: string;
78
+ }[] | undefined;
79
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
80
+ } | undefined;
81
+ }, {
82
+ name: string;
83
+ source: string;
84
+ validation?: {
85
+ allow?: {
86
+ code: string;
87
+ reason: string;
88
+ }[] | undefined;
89
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
90
+ } | undefined;
91
+ }>;
92
+ declare const SeedSchema: z.ZodObject<{
93
+ plugins: z.ZodArray<z.ZodObject<{
94
+ source: z.ZodString;
95
+ name: z.ZodString;
96
+ validation: z.ZodOptional<z.ZodObject<{
97
+ severity: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<["error", "warning", "info", "ignore"]>>>;
98
+ allow: z.ZodOptional<z.ZodArray<z.ZodObject<{
99
+ code: z.ZodString;
100
+ reason: z.ZodString;
101
+ }, "strip", z.ZodTypeAny, {
102
+ code: string;
103
+ reason: string;
104
+ }, {
105
+ code: string;
106
+ reason: string;
107
+ }>, "many">>;
108
+ }, "strict", z.ZodTypeAny, {
109
+ allow?: {
110
+ code: string;
111
+ reason: string;
112
+ }[] | undefined;
113
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
114
+ }, {
115
+ allow?: {
116
+ code: string;
117
+ reason: string;
118
+ }[] | undefined;
119
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
120
+ }>>;
121
+ }, "strict", z.ZodTypeAny, {
122
+ name: string;
123
+ source: string;
124
+ validation?: {
125
+ allow?: {
126
+ code: string;
127
+ reason: string;
128
+ }[] | undefined;
129
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
130
+ } | undefined;
131
+ }, {
132
+ name: string;
133
+ source: string;
134
+ validation?: {
135
+ allow?: {
136
+ code: string;
137
+ reason: string;
138
+ }[] | undefined;
139
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
140
+ } | undefined;
141
+ }>, "many">;
142
+ }, "strict", z.ZodTypeAny, {
143
+ plugins: {
144
+ name: string;
145
+ source: string;
146
+ validation?: {
147
+ allow?: {
148
+ code: string;
149
+ reason: string;
150
+ }[] | undefined;
151
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
152
+ } | undefined;
153
+ }[];
154
+ }, {
155
+ plugins: {
156
+ name: string;
157
+ source: string;
158
+ validation?: {
159
+ allow?: {
160
+ code: string;
161
+ reason: string;
162
+ }[] | undefined;
163
+ severity?: Record<string, "error" | "warning" | "info" | "ignore"> | undefined;
164
+ } | undefined;
165
+ }[];
166
+ }>;
167
+ export type ValidationAllowEntry = z.infer<typeof ValidationAllowEntrySchema>;
168
+ export type ValidationBlock = z.infer<typeof ValidationBlockSchema>;
169
+ export type PluginEntry = z.infer<typeof PluginEntrySchema>;
170
+ export type Seed = z.infer<typeof SeedSchema>;
171
+ /**
172
+ * Load and validate `corpus/seed.yaml` (or another seed-shaped YAML file).
173
+ * Throws on missing file, malformed YAML, schema violations, duplicate
174
+ * `source` keys, or duplicate `name` labels.
175
+ */
176
+ export declare function loadSeedFile(path: string): Seed;
177
+ export {};
178
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../../src/commands/corpus/seed.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,0BAA0B;;;;;;;;;EAG9B,CAAC;AAEH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;EAKhB,CAAC;AAEZ,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EASZ,CAAC;AAEZ,QAAA,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIL,CAAC;AAEZ,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAyB/C"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Seed schema + parser for `corpus/seed.yaml`. The seed is the committed
3
+ * config of plugins tracked by `vat corpus scan`. Per-entry `validation:`
4
+ * mirrors the `skills.defaults.validation` block of the project config
5
+ * schema (severity overrides + allow entries).
6
+ */
7
+ import { existsSync, readFileSync } from 'node:fs';
8
+ import * as yaml from 'js-yaml';
9
+ import { z } from 'zod';
10
+ const ValidationAllowEntrySchema = z.object({
11
+ code: z.string().min(1),
12
+ reason: z.string().min(1),
13
+ });
14
+ const ValidationBlockSchema = z
15
+ .object({
16
+ severity: z.record(z.string(), z.enum(['error', 'warning', 'info', 'ignore'])).optional(),
17
+ allow: z.array(ValidationAllowEntrySchema).optional(),
18
+ })
19
+ .strict();
20
+ const PluginEntrySchema = z
21
+ .object({
22
+ source: z.string().min(1),
23
+ name: z
24
+ .string()
25
+ .min(1)
26
+ .regex(/^[A-Za-z0-9_-]+$/, 'name must be [A-Za-z0-9_-]+ (presentation label)'),
27
+ validation: ValidationBlockSchema.optional(),
28
+ })
29
+ .strict();
30
+ const SeedSchema = z
31
+ .object({
32
+ plugins: z.array(PluginEntrySchema).min(1),
33
+ })
34
+ .strict();
35
+ /**
36
+ * Load and validate `corpus/seed.yaml` (or another seed-shaped YAML file).
37
+ * Throws on missing file, malformed YAML, schema violations, duplicate
38
+ * `source` keys, or duplicate `name` labels.
39
+ */
40
+ export function loadSeedFile(path) {
41
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller-supplied seed file path
42
+ if (!existsSync(path)) {
43
+ throw new Error(`Seed file not found: ${path}`);
44
+ }
45
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- caller-supplied seed file path
46
+ const raw = readFileSync(path, 'utf-8');
47
+ const parsed = yaml.load(raw);
48
+ const seed = SeedSchema.parse(parsed);
49
+ const sources = new Set();
50
+ const names = new Set();
51
+ for (const entry of seed.plugins) {
52
+ if (sources.has(entry.source)) {
53
+ throw new Error(`Seed has duplicate source: ${entry.source}`);
54
+ }
55
+ if (names.has(entry.name)) {
56
+ throw new Error(`Seed has duplicate name: ${entry.name}`);
57
+ }
58
+ sources.add(entry.source);
59
+ names.add(entry.name);
60
+ }
61
+ return seed;
62
+ }
63
+ //# sourceMappingURL=seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../src/commands/corpus/seed.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1B,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,CAAC;KAC5B,MAAM,CAAC;IACN,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACzF,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;CACtD,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,iBAAiB,GAAG,CAAC;KACxB,MAAM,CAAC;IACN,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,KAAK,CAAC,kBAAkB,EAAE,kDAAkD,CAAC;IAChF,UAAU,EAAE,qBAAqB,CAAC,QAAQ,EAAE;CAC7C,CAAC;KACD,MAAM,EAAE,CAAC;AAEZ,MAAM,UAAU,GAAG,CAAC;KACjB,MAAM,CAAC;IACN,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3C,CAAC;KACD,MAAM,EAAE,CAAC;AAOZ;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,qGAAqG;IACrG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,qGAAqG;IACrG,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Command } from 'commander';
2
+ export interface InventoryCommandOptions {
3
+ user?: boolean;
4
+ system?: boolean;
5
+ format?: 'yaml' | 'json';
6
+ shallow?: boolean;
7
+ debug?: boolean;
8
+ }
9
+ /**
10
+ * Create and configure the `vat inventory` command.
11
+ */
12
+ export declare function createInventoryCommand(): Command;
13
+ /**
14
+ * Action handler for `vat inventory [path]`.
15
+ */
16
+ export declare function inventoryCommand(pathArg: string | undefined, options: InventoryCommandOptions): Promise<void>;
17
+ //# sourceMappingURL=inventory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../../src/commands/inventory.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,MAAM,WAAW,uBAAuB;IACvC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAgChD;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf"}