@vibe-agent-toolkit/cli 0.2.0-rc.5 → 0.2.0-rc.7

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 (220) hide show
  1. package/README.md +4 -4
  2. package/dist/bin.js +41 -158
  3. package/dist/bin.js.map +1 -1
  4. package/dist/command-loaders.d.ts +2 -2
  5. package/dist/command-loaders.d.ts.map +1 -1
  6. package/dist/command-loaders.js +4 -2
  7. package/dist/command-loaders.js.map +1 -1
  8. package/dist/commands/ard/emit.d.ts +104 -0
  9. package/dist/commands/ard/emit.d.ts.map +1 -0
  10. package/dist/commands/ard/emit.js +223 -0
  11. package/dist/commands/ard/emit.js.map +1 -0
  12. package/dist/commands/ard/index.d.ts +12 -0
  13. package/dist/commands/ard/index.d.ts.map +1 -0
  14. package/dist/commands/ard/index.js +79 -0
  15. package/dist/commands/ard/index.js.map +1 -0
  16. package/dist/commands/ard/surfaces.d.ts +56 -0
  17. package/dist/commands/ard/surfaces.d.ts.map +1 -0
  18. package/dist/commands/ard/surfaces.js +150 -0
  19. package/dist/commands/ard/surfaces.js.map +1 -0
  20. package/dist/commands/audit.d.ts +75 -8
  21. package/dist/commands/audit.d.ts.map +1 -1
  22. package/dist/commands/audit.js +726 -127
  23. package/dist/commands/audit.js.map +1 -1
  24. package/dist/commands/claude/budget.d.ts +13 -0
  25. package/dist/commands/claude/budget.d.ts.map +1 -1
  26. package/dist/commands/claude/budget.js +80 -28
  27. package/dist/commands/claude/budget.js.map +1 -1
  28. package/dist/commands/claude/claude-config.d.ts.map +1 -1
  29. package/dist/commands/claude/claude-config.js +6 -0
  30. package/dist/commands/claude/claude-config.js.map +1 -1
  31. package/dist/commands/claude/context.js +1 -1
  32. package/dist/commands/claude/context.js.map +1 -1
  33. package/dist/commands/claude/marketplace/validate.d.ts +55 -22
  34. package/dist/commands/claude/marketplace/validate.d.ts.map +1 -1
  35. package/dist/commands/claude/marketplace/validate.js +380 -75
  36. package/dist/commands/claude/marketplace/validate.js.map +1 -1
  37. package/dist/commands/claude/org/helpers.d.ts +59 -1
  38. package/dist/commands/claude/org/helpers.d.ts.map +1 -1
  39. package/dist/commands/claude/org/helpers.js +58 -7
  40. package/dist/commands/claude/org/helpers.js.map +1 -1
  41. package/dist/commands/claude/org/index.d.ts.map +1 -1
  42. package/dist/commands/claude/org/index.js +24 -16
  43. package/dist/commands/claude/org/index.js.map +1 -1
  44. package/dist/commands/claude/org/skills.d.ts +509 -0
  45. package/dist/commands/claude/org/skills.d.ts.map +1 -1
  46. package/dist/commands/claude/org/skills.js +1364 -94
  47. package/dist/commands/claude/org/skills.js.map +1 -1
  48. package/dist/commands/claude/org/users.d.ts.map +1 -1
  49. package/dist/commands/claude/org/users.js +3 -1
  50. package/dist/commands/claude/org/users.js.map +1 -1
  51. package/dist/commands/claude/org/workspaces.d.ts.map +1 -1
  52. package/dist/commands/claude/org/workspaces.js +5 -2
  53. package/dist/commands/claude/org/workspaces.js.map +1 -1
  54. package/dist/commands/claude/plugin/build.d.ts +8 -0
  55. package/dist/commands/claude/plugin/build.d.ts.map +1 -1
  56. package/dist/commands/claude/plugin/build.js +16 -2
  57. package/dist/commands/claude/plugin/build.js.map +1 -1
  58. package/dist/commands/claude/plugin/tree-copy.d.ts +72 -0
  59. package/dist/commands/claude/plugin/tree-copy.d.ts.map +1 -1
  60. package/dist/commands/claude/plugin/tree-copy.js +215 -10
  61. package/dist/commands/claude/plugin/tree-copy.js.map +1 -1
  62. package/dist/commands/corpus/index.d.ts.map +1 -1
  63. package/dist/commands/corpus/index.js +3 -0
  64. package/dist/commands/corpus/index.js.map +1 -1
  65. package/dist/commands/corpus/report.d.ts +0 -1
  66. package/dist/commands/corpus/report.d.ts.map +1 -1
  67. package/dist/commands/corpus/report.js +0 -1
  68. package/dist/commands/corpus/report.js.map +1 -1
  69. package/dist/commands/corpus/runner.d.ts +58 -1
  70. package/dist/commands/corpus/runner.d.ts.map +1 -1
  71. package/dist/commands/corpus/runner.js +90 -15
  72. package/dist/commands/corpus/runner.js.map +1 -1
  73. package/dist/commands/corpus/scan.d.ts.map +1 -1
  74. package/dist/commands/corpus/scan.js +0 -1
  75. package/dist/commands/corpus/scan.js.map +1 -1
  76. package/dist/commands/doctor.d.ts +14 -0
  77. package/dist/commands/doctor.d.ts.map +1 -1
  78. package/dist/commands/doctor.js +96 -18
  79. package/dist/commands/doctor.js.map +1 -1
  80. package/dist/commands/okf/index.d.ts +11 -0
  81. package/dist/commands/okf/index.d.ts.map +1 -0
  82. package/dist/commands/okf/index.js +102 -0
  83. package/dist/commands/okf/index.js.map +1 -0
  84. package/dist/commands/okf/validate.d.ts +82 -0
  85. package/dist/commands/okf/validate.d.ts.map +1 -0
  86. package/dist/commands/okf/validate.js +157 -0
  87. package/dist/commands/okf/validate.js.map +1 -0
  88. package/dist/commands/phase-utils.d.ts +19 -3
  89. package/dist/commands/phase-utils.d.ts.map +1 -1
  90. package/dist/commands/phase-utils.js +26 -5
  91. package/dist/commands/phase-utils.js.map +1 -1
  92. package/dist/commands/rag/index-command.d.ts +27 -2
  93. package/dist/commands/rag/index-command.d.ts.map +1 -1
  94. package/dist/commands/rag/index-command.js +44 -7
  95. package/dist/commands/rag/index-command.js.map +1 -1
  96. package/dist/commands/rag/index.d.ts.map +1 -1
  97. package/dist/commands/rag/index.js +2 -0
  98. package/dist/commands/rag/index.js.map +1 -1
  99. package/dist/commands/resources/check-progress.d.ts +3 -0
  100. package/dist/commands/resources/check-progress.d.ts.map +1 -1
  101. package/dist/commands/resources/check-progress.js +6 -0
  102. package/dist/commands/resources/check-progress.js.map +1 -1
  103. package/dist/commands/resources/check.d.ts +33 -4
  104. package/dist/commands/resources/check.d.ts.map +1 -1
  105. package/dist/commands/resources/check.js +131 -44
  106. package/dist/commands/resources/check.js.map +1 -1
  107. package/dist/commands/resources/index.d.ts.map +1 -1
  108. package/dist/commands/resources/index.js +41 -9
  109. package/dist/commands/resources/index.js.map +1 -1
  110. package/dist/commands/resources/query.d.ts +18 -1
  111. package/dist/commands/resources/query.d.ts.map +1 -1
  112. package/dist/commands/resources/query.js +29 -4
  113. package/dist/commands/resources/query.js.map +1 -1
  114. package/dist/commands/resources/validate.d.ts +29 -0
  115. package/dist/commands/resources/validate.d.ts.map +1 -1
  116. package/dist/commands/resources/validate.js +116 -13
  117. package/dist/commands/resources/validate.js.map +1 -1
  118. package/dist/commands/skill/review-checklist.d.ts.map +1 -1
  119. package/dist/commands/skill/review-checklist.js +35 -0
  120. package/dist/commands/skill/review-checklist.js.map +1 -1
  121. package/dist/commands/skill/review.d.ts.map +1 -1
  122. package/dist/commands/skill/review.js +9 -2
  123. package/dist/commands/skill/review.js.map +1 -1
  124. package/dist/commands/skill/test/configure.d.ts +37 -0
  125. package/dist/commands/skill/test/configure.d.ts.map +1 -1
  126. package/dist/commands/skill/test/configure.js +57 -12
  127. package/dist/commands/skill/test/configure.js.map +1 -1
  128. package/dist/commands/skill/test/run.d.ts.map +1 -1
  129. package/dist/commands/skill/test/run.js +21 -6
  130. package/dist/commands/skill/test/run.js.map +1 -1
  131. package/dist/commands/skills/build.d.ts.map +1 -1
  132. package/dist/commands/skills/build.js +16 -3
  133. package/dist/commands/skills/build.js.map +1 -1
  134. package/dist/commands/skills/list.d.ts +2 -1
  135. package/dist/commands/skills/list.d.ts.map +1 -1
  136. package/dist/commands/skills/list.js +31 -9
  137. package/dist/commands/skills/list.js.map +1 -1
  138. package/dist/commands/skills/skill-discovery.d.ts +40 -1
  139. package/dist/commands/skills/skill-discovery.d.ts.map +1 -1
  140. package/dist/commands/skills/skill-discovery.js +32 -3
  141. package/dist/commands/skills/skill-discovery.js.map +1 -1
  142. package/dist/commands/skills/validate-command.d.ts.map +1 -1
  143. package/dist/commands/skills/validate-command.js +11 -3
  144. package/dist/commands/skills/validate-command.js.map +1 -1
  145. package/dist/commands/skills/validate.d.ts +66 -7
  146. package/dist/commands/skills/validate.d.ts.map +1 -1
  147. package/dist/commands/skills/validate.js +133 -29
  148. package/dist/commands/skills/validate.js.map +1 -1
  149. package/dist/commands/verify.d.ts +94 -3
  150. package/dist/commands/verify.d.ts.map +1 -1
  151. package/dist/commands/verify.js +192 -45
  152. package/dist/commands/verify.js.map +1 -1
  153. package/dist/skill-resolution/packaging-config.d.ts +49 -5
  154. package/dist/skill-resolution/packaging-config.d.ts.map +1 -1
  155. package/dist/skill-resolution/packaging-config.js +59 -19
  156. package/dist/skill-resolution/packaging-config.js.map +1 -1
  157. package/dist/skill-resolution/resolve-skill-reference.d.ts.map +1 -1
  158. package/dist/skill-resolution/resolve-skill-reference.js +6 -3
  159. package/dist/skill-resolution/resolve-skill-reference.js.map +1 -1
  160. package/dist/utils/command-error.d.ts +31 -0
  161. package/dist/utils/command-error.d.ts.map +1 -1
  162. package/dist/utils/command-error.js +45 -0
  163. package/dist/utils/command-error.js.map +1 -1
  164. package/dist/utils/config-loader.d.ts.map +1 -1
  165. package/dist/utils/config-loader.js +22 -6
  166. package/dist/utils/config-loader.js.map +1 -1
  167. package/dist/utils/edge-lens-evaluation.d.ts +83 -0
  168. package/dist/utils/edge-lens-evaluation.d.ts.map +1 -0
  169. package/dist/utils/edge-lens-evaluation.js +110 -0
  170. package/dist/utils/edge-lens-evaluation.js.map +1 -0
  171. package/dist/utils/optional-backend.d.ts +5 -4
  172. package/dist/utils/optional-backend.d.ts.map +1 -1
  173. package/dist/utils/optional-backend.js +5 -4
  174. package/dist/utils/optional-backend.js.map +1 -1
  175. package/dist/utils/project-root-policy.d.ts +20 -0
  176. package/dist/utils/project-root-policy.d.ts.map +1 -1
  177. package/dist/utils/project-root-policy.js +32 -0
  178. package/dist/utils/project-root-policy.js.map +1 -1
  179. package/dist/utils/projection-query.d.ts +41 -4
  180. package/dist/utils/projection-query.d.ts.map +1 -1
  181. package/dist/utils/projection-query.js +44 -10
  182. package/dist/utils/projection-query.js.map +1 -1
  183. package/dist/utils/projection-store.d.ts +41 -15
  184. package/dist/utils/projection-store.d.ts.map +1 -1
  185. package/dist/utils/projection-store.js +65 -18
  186. package/dist/utils/projection-store.js.map +1 -1
  187. package/dist/utils/repeatable-option.d.ts +37 -0
  188. package/dist/utils/repeatable-option.d.ts.map +1 -0
  189. package/dist/utils/repeatable-option.js +39 -0
  190. package/dist/utils/repeatable-option.js.map +1 -0
  191. package/dist/utils/resource-loader.d.ts +4 -3
  192. package/dist/utils/resource-loader.d.ts.map +1 -1
  193. package/dist/utils/resource-loader.js +61 -30
  194. package/dist/utils/resource-loader.js.map +1 -1
  195. package/dist/utils/root-argv.d.ts +53 -0
  196. package/dist/utils/root-argv.d.ts.map +1 -0
  197. package/dist/utils/root-argv.js +215 -0
  198. package/dist/utils/root-argv.js.map +1 -0
  199. package/dist/utils/run-integrity.d.ts +95 -0
  200. package/dist/utils/run-integrity.d.ts.map +1 -0
  201. package/dist/utils/run-integrity.js +102 -0
  202. package/dist/utils/run-integrity.js.map +1 -0
  203. package/dist/utils/sqlite-experimental-warning.d.ts +69 -0
  204. package/dist/utils/sqlite-experimental-warning.d.ts.map +1 -0
  205. package/dist/utils/sqlite-experimental-warning.js +144 -0
  206. package/dist/utils/sqlite-experimental-warning.js.map +1 -0
  207. package/dist/utils/user-context-scanner.d.ts +8 -0
  208. package/dist/utils/user-context-scanner.d.ts.map +1 -1
  209. package/dist/utils/user-context-scanner.js +4 -0
  210. package/dist/utils/user-context-scanner.js.map +1 -1
  211. package/dist/utils/validate-help-files.d.ts.map +1 -1
  212. package/dist/utils/validate-help-files.js +9 -2
  213. package/dist/utils/validate-help-files.js.map +1 -1
  214. package/docs/audit.md +120 -7
  215. package/docs/doctor.md +6 -6
  216. package/docs/index.md +1 -1
  217. package/docs/rag.md +3 -1
  218. package/docs/resources.md +5 -1
  219. package/docs/skills.md +47 -62
  220. package/package.json +18 -18
@@ -0,0 +1,223 @@
1
+ /**
2
+ * `vat ard emit` — write the project's `/.well-known/ard.json`.
3
+ *
4
+ * **Emit, never depend.** This command produces a document and stops. Nothing
5
+ * in VAT reads one back, and no VAT behaviour is derived from one — ARD is
6
+ * v0.91, status Proposal, and wiring internals to a moving shape is the cost
7
+ * this rule avoids.
8
+ */
9
+ import { existsSync, readFileSync } from 'node:fs';
10
+ import { ArdDerivationError, buildArdEntries, buildArdManifest, findShadowedArdOverrideKeys, writeArdManifest, } from '@vibe-agent-toolkit/resources';
11
+ import { safePath } from '@vibe-agent-toolkit/utils';
12
+ import { handleCommandError, handleExpectedFailure } from '../../utils/command-error.js';
13
+ import { loadConfig } from '../../utils/config-loader.js';
14
+ import { createLogger } from '../../utils/logger.js';
15
+ import { writeJsonOutput } from '../../utils/output.js';
16
+ import { discoverSkillsFromConfig } from '../skills/skill-discovery.js';
17
+ import { collectArdSurfaces } from './surfaces.js';
18
+ /** Default destination, relative to the project root — the path ARD publishes at. */
19
+ export const DEFAULT_ARD_OUTPUT = '.well-known/ard.json';
20
+ /** The config filename every VAT project declares its surfaces in. */
21
+ const CONFIG_FILENAME = 'vibe-agent-toolkit.config.yaml';
22
+ /** No manifest could be built, and this says which absence caused it. */
23
+ export class ArdConfigMissingError extends Error {
24
+ projectRoot;
25
+ absence;
26
+ constructor(projectRoot, absence) {
27
+ super(ABSENCE_MESSAGES[absence](projectRoot));
28
+ this.name = 'ArdConfigMissingError';
29
+ this.projectRoot = projectRoot;
30
+ this.absence = absence;
31
+ }
32
+ }
33
+ const ABSENCE_MESSAGES = {
34
+ 'no-project-root': (projectRoot) => `Project root ${projectRoot} does not exist. Pass --project-root a directory that does, or ` +
35
+ 'run `vat ard emit` from inside the project.',
36
+ 'no-config-file': (projectRoot) => `No ${CONFIG_FILENAME} found in ${projectRoot}. ` +
37
+ 'ARD entries are derived from the surfaces that file declares, so there is nothing to emit.',
38
+ 'no-ard-block': (projectRoot) => `No \`ard:\` configuration found for ${projectRoot}. ` +
39
+ `Add an \`ard:\` block with a \`publisher\` domain to ${CONFIG_FILENAME}.`,
40
+ };
41
+ /**
42
+ * The project's own package version, when it has one.
43
+ *
44
+ * The npm package version is the only version this project recognises, and an
45
+ * adopter's is the only one VAT can honestly stamp on an entry. Absent or
46
+ * unreadable, the field is simply omitted.
47
+ */
48
+ function readProjectVersion(projectRoot) {
49
+ const packagePath = safePath.join(projectRoot, 'package.json');
50
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- path derives from the caller's project root
51
+ if (!existsSync(packagePath))
52
+ return undefined;
53
+ try {
54
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- existence just confirmed above; same path
55
+ const parsed = JSON.parse(readFileSync(packagePath, 'utf-8'));
56
+ // `""` is ABSENT, not a version. A `package.json` carrying it emitted
57
+ // `"version": ""` on every entry at exit 0 — a field asserting a version
58
+ // that does not exist. The entry schema now refuses it too, so leaving this
59
+ // would turn a blank field into a hard emission failure instead.
60
+ if (typeof parsed.version !== 'string' || parsed.version === '')
61
+ return undefined;
62
+ return parsed.version;
63
+ }
64
+ catch {
65
+ // A package.json VAT cannot read is not a reason to refuse a manifest; the
66
+ // entry is emitted without a `version`, which is a conformant entry.
67
+ return undefined;
68
+ }
69
+ }
70
+ /**
71
+ * Build and write the manifest.
72
+ *
73
+ * @throws {ArdConfigMissingError} when no config, or no `ard:` block, is found.
74
+ * @throws {ArdDerivationError} when a surface cannot be turned into a
75
+ * conformant entry — a missing `ard.baseUrl`, an unusable URN segment, or a
76
+ * trust identity that does not align with the publisher.
77
+ */
78
+ export async function runArdEmit(options) {
79
+ const projectRoot = options.projectRoot ?? process.cwd();
80
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- projectRoot is the caller's declared root
81
+ if (!existsSync(projectRoot)) {
82
+ throw new ArdConfigMissingError(projectRoot, 'no-project-root');
83
+ }
84
+ const config = loadConfig(projectRoot);
85
+ if (config === undefined) {
86
+ throw new ArdConfigMissingError(projectRoot, 'no-config-file');
87
+ }
88
+ const ard = config.ard;
89
+ if (ard === undefined) {
90
+ throw new ArdConfigMissingError(projectRoot, 'no-ard-block');
91
+ }
92
+ const { surfaces, skipped } = collectArdSurfaces(config, {
93
+ version: readProjectVersion(projectRoot),
94
+ // The SAME discovery `vat verify` runs, so the two commands cannot disagree
95
+ // about which skills this project has. Omitted entirely when the project
96
+ // declares no `skills` block: there is nothing to cross-check, and passing
97
+ // `[]` would claim discovery ran and found nothing.
98
+ ...(config.skills === undefined
99
+ ? {}
100
+ : {
101
+ // `'refuse'`: a manifest cross-checked against a partial skill list
102
+ // would advertise or omit entries on a population it never saw. The
103
+ // throw is an invocation failure → exit 2 (see the catch in
104
+ // `ardEmitCommand`).
105
+ discoveredSkills: (await discoverSkillsFromConfig(config.skills, projectRoot, 'refuse')).map((skill) => skill.name),
106
+ }),
107
+ });
108
+ const manifest = buildArdManifest(buildArdEntries(surfaces, ard));
109
+ const outputPath = safePath.resolve(projectRoot, options.output ?? DEFAULT_ARD_OUTPUT);
110
+ await writeArdManifest(manifest, outputPath);
111
+ return {
112
+ outputPath,
113
+ entryCount: manifest.entries.length,
114
+ skipped,
115
+ shadowed: findShadowedArdOverrideKeys(surfaces, ard),
116
+ };
117
+ }
118
+ /** Pure: the report a result becomes, so the status rule is unit-testable. */
119
+ export function buildArdEmitReport(result) {
120
+ return {
121
+ status: result.entryCount > 0 ? 'written' : 'empty',
122
+ outputPath: result.outputPath,
123
+ entryCount: result.entryCount,
124
+ skippedCount: result.skipped.length,
125
+ shadowedCount: result.shadowed.length,
126
+ skipped: result.skipped,
127
+ shadowed: result.shadowed,
128
+ };
129
+ }
130
+ /**
131
+ * Why `--strict` fails this run, or `undefined` when it does not.
132
+ *
133
+ * ⚠️ A shadowed override key is deliberately NOT a strict failure: the
134
+ * precedence is deterministic and documented, the entry is still emitted, and
135
+ * nothing about the published manifest is wrong. What `--strict` gates is the
136
+ * manifest's CONTENT — a surface an author declared and a consumer will never
137
+ * see, and the empty document that is the limit case of that.
138
+ */
139
+ function strictFailure(report) {
140
+ if (report.skippedCount > 0) {
141
+ const surfaces = report.skippedCount === 1 ? '1 configured surface was' : `${report.skippedCount} configured surfaces were`;
142
+ // Not "see above": in `--format json` the reasons are IN the report, not on
143
+ // stderr, so a message naming a position would be wrong on one of the two
144
+ // channels.
145
+ return `--strict: ${surfaces} not advertised — each is named, with its reason, in this run's \`skipped\` report.`;
146
+ }
147
+ if (report.status === 'empty') {
148
+ return '--strict: the manifest advertises nothing. Nothing this project declares became an ARD entry.';
149
+ }
150
+ return undefined;
151
+ }
152
+ /** The human rendering: findings on stderr, the one summary line on stdout. */
153
+ function writeArdEmitText(report) {
154
+ for (const item of report.skipped) {
155
+ process.stderr.write(`skipped ${item.kind} "${item.name}": ${item.reason}\n`);
156
+ }
157
+ for (const item of report.shadowed) {
158
+ process.stderr.write(`ignored \`ard.entries.${item.shadowedKey}\`: the ${item.kind} "${item.name}" is also named ` +
159
+ `by \`ard.entries."${item.winningKey}"\`, and the kind-qualified key wins. Nothing in the ` +
160
+ 'bare block was read — fold it into the qualified one or delete it.\n');
161
+ }
162
+ process.stdout.write(`Wrote ${report.entryCount} ARD entr${report.entryCount === 1 ? 'y' : 'ies'} to ${report.outputPath}\n`);
163
+ }
164
+ /** Action handler for `vat ard emit`. */
165
+ export async function ardEmitCommand(options) {
166
+ const logger = createLogger(options.debug === true ? { debug: true } : {});
167
+ const startTime = Date.now();
168
+ try {
169
+ const report = buildArdEmitReport(await runArdEmit(options));
170
+ if (options.format === 'json') {
171
+ // The report carries every skipped and shadowed surface in full, so the
172
+ // stderr lines would be the same facts twice on two channels.
173
+ writeJsonOutput(report);
174
+ }
175
+ else {
176
+ writeArdEmitText(report);
177
+ }
178
+ const failure = options.strict === true ? strictFailure(report) : undefined;
179
+ if (failure !== undefined) {
180
+ process.stderr.write(`${failure}\n`);
181
+ process.exit(1);
182
+ }
183
+ }
184
+ catch (error) {
185
+ // 🔑 THE RULE, in one sentence: **exit 1 means VAT read this project and
186
+ // produced no manifest by its own rules — it declares no `ard:` block, or a
187
+ // surface could not be derived into a conformant entry; exit 2 means VAT
188
+ // never got that far — no project root, no config file, a config it cannot
189
+ // parse, or an unexpected internal failure.**
190
+ //
191
+ // ⚠️ Not "1 is reserved for a check that ran and failed": `ard emit` is not
192
+ // a check, and "no `ard:` block" is not a failed one. The distinction that
193
+ // matters to a caller is whether the PROJECT is the subject (1) or the
194
+ // INVOCATION is (2) — the first is fixed by editing config, the second by
195
+ // fixing the command line or the file itself. A CI job that tolerates
196
+ // repositories which have not opted into ARD keys on exactly that split.
197
+ //
198
+ // Exit 2 is also what `vat okf validate` documents for the same conditions,
199
+ // and what an invalid config already did here through `handleCommandError`.
200
+ // The old split had a missing config file exiting 1 and an invalid one
201
+ // exiting 2 while the help called 2 "Unexpected internal failure" — so a CI
202
+ // job reading 2 as a crash was paged for a typo.
203
+ //
204
+ // ⚠️ Both endings publish their document through `handleExpectedFailure`,
205
+ // in the format the operator asked for. Written inline they published
206
+ // NOTHING — a `--format json` run of the commonest case of all, a
207
+ // repository that never opted into ARD, wrote zero bytes to stdout and left
208
+ // a CI wrapper parsing stderr for a fact the report is supposed to carry.
209
+ //
210
+ // 🪤 `return` the call, though its type is `never`: under test `process.exit`
211
+ // is a spy that RETURNS, so a bare call falls through to the handler below
212
+ // and the run records a second exit — the same reason the inline endings
213
+ // this replaced each carried a `return`.
214
+ if (error instanceof ArdConfigMissingError) {
215
+ return handleExpectedFailure(error.message, error.absence === 'no-ard-block' ? 1 : 2, startTime, options.format);
216
+ }
217
+ if (error instanceof ArdDerivationError) {
218
+ return handleExpectedFailure(error.message, 1, startTime, options.format);
219
+ }
220
+ handleCommandError(error, logger, startTime, 'ARD emit', options.format);
221
+ }
222
+ }
223
+ //# sourceMappingURL=emit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../../src/commands/ard/emit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `vat ard` — Agentic Resource Discovery emission.
3
+ *
4
+ * Not registered in `command-loaders.ts` by this module: the loader table is
5
+ * owned elsewhere, and this file only builds the command.
6
+ */
7
+ import { Command } from 'commander';
8
+ export { ardEmitCommand, buildArdEmitReport, runArdEmit, ArdConfigMissingError, DEFAULT_ARD_OUTPUT, type ArdEmitReport, type ArdEmitStatus, } from './emit.js';
9
+ export { collectArdSurfaces, type ArdSurfaceCollection, type SkippedArdSurface } from './surfaces.js';
10
+ /** Build the `vat ard` command group. */
11
+ export declare function createArdCommand(): Command;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/ard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAI5C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEtG,yCAAyC;AACzC,wBAAgB,gBAAgB,IAAI,OAAO,CA+E1C"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * `vat ard` — Agentic Resource Discovery emission.
3
+ *
4
+ * Not registered in `command-loaders.ts` by this module: the loader table is
5
+ * owned elsewhere, and this file only builds the command.
6
+ */
7
+ import { Command, Option } from 'commander';
8
+ import { ardEmitCommand, DEFAULT_ARD_OUTPUT } from './emit.js';
9
+ export { ardEmitCommand, buildArdEmitReport, runArdEmit, ArdConfigMissingError, DEFAULT_ARD_OUTPUT, } from './emit.js';
10
+ export { collectArdSurfaces } from './surfaces.js';
11
+ /** Build the `vat ard` command group. */
12
+ export function createArdCommand() {
13
+ const ard = new Command('ard');
14
+ ard.description('Emit an Agentic Resource Discovery (ARD) manifest for this project').addHelpText('after', `
15
+ Description:
16
+ ARD has no registry and no upload: a publisher hosts a JSON-LD document at
17
+ https://{domain}/.well-known/ard.json and registries crawl it. VAT builds that
18
+ document out of the surfaces this project already declares.
19
+
20
+ ⚠️ ARD is v0.91, status Proposal. VAT emits against it and reads nothing back.
21
+ `);
22
+ ard
23
+ .command('emit')
24
+ .description('Build the ARD manifest and write it to disk')
25
+ .option('-o, --output <path>', `Output path (default: ${DEFAULT_ARD_OUTPUT})`)
26
+ .option('--project-root <dir>', 'Project root to read the config from (default: cwd)')
27
+ .addOption(
28
+ // Rejected by Commander rather than falling through to `text`, as the
29
+ // sibling `vat okf validate` does: `--format Json` in a pipeline must
30
+ // fail HERE, where the mistake is, not downstream in `jq`.
31
+ new Option('--format <format>', 'Output format: text (default) or json')
32
+ .choices(['text', 'json'])
33
+ .default('text'))
34
+ .option('--strict', 'Exit 1 when the manifest advertises nothing, or a configured surface was skipped')
35
+ .option('--debug', 'Verbose logging to stderr')
36
+ .action(ardEmitCommand)
37
+ .addHelpText('after', `
38
+ Derivation:
39
+ Every published skill in \`skills.config\` becomes an entry, typed
40
+ application/ai-skill+md — a media type VAT COINS, since the specification
41
+ names none for a skill (it occurs once, in an example).
42
+
43
+ A marketplace, an OKF bundle and an MCP server are emitted ONLY when the
44
+ author supplies \`ard.entries."<kind>:<name>".type\`; the specification names
45
+ no media type for any of them, and VAT does not guess. Skipped surfaces are
46
+ reported on stderr — including a \`skills.config\` key that discovery does not
47
+ find, which is never advertised.
48
+
49
+ \`ard.entries\` is keyed by "<kind>:<name>" — skills, marketplaces and OKF
50
+ bundles are independent key spaces, so a bare name that matches two of them
51
+ is REFUSED rather than applied to both.
52
+
53
+ \`representativeQueries\` is authored, never generated. Its absence is a
54
+ conformance WARNING upstream, not an error — an honest gap beats a
55
+ fabricated query that makes a resource discoverable for the wrong task.
56
+
57
+ Requirements:
58
+ ard.publisher Required — anchors every entry URN.
59
+ ard.baseUrl Required in practice — VAT has no inline artifact document for
60
+ these surfaces, so without it no entry has a \`url\` or a
61
+ \`data\` and emission fails.
62
+
63
+ Exit Codes:
64
+ 0 - Manifest written — INCLUDING one that advertises nothing. An empty
65
+ \`entries\` list is a legal ARD document, and skipped surfaces are reported
66
+ on stderr at this exit code. Gate on \`--format json\` (\`status\`,
67
+ \`entryCount\`, \`skippedCount\`), or make both conditions fail with
68
+ \`--strict\`
69
+ 1 - No \`ard:\` block in the config, or a surface could not be derived. Under
70
+ \`--strict\`, also an empty manifest or a skipped surface
71
+ 2 - System error (no project root, no config file, invalid config, unexpected
72
+ internal failure)
73
+
74
+ Example:
75
+ $ vat ard emit --format json --strict
76
+ `);
77
+ return ard;
78
+ }
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/ard/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/D,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,qBAAqB,EACrB,kBAAkB,GAGnB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAqD,MAAM,eAAe,CAAC;AAEtG,yCAAyC;AACzC,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IAE/B,GAAG,CAAC,WAAW,CAAC,oEAAoE,CAAC,CAAC,WAAW,CAC/F,OAAO,EACP;;;;;;;CAOH,CACE,CAAC;IAEF,GAAG;SACA,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6CAA6C,CAAC;SAC1D,MAAM,CAAC,qBAAqB,EAAE,yBAAyB,kBAAkB,GAAG,CAAC;SAC7E,MAAM,CAAC,sBAAsB,EAAE,qDAAqD,CAAC;SACrF,SAAS;IACR,sEAAsE;IACtE,sEAAsE;IACtE,2DAA2D;IAC3D,IAAI,MAAM,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;SACrE,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACzB,OAAO,CAAC,MAAM,CAAC,CACnB;SACA,MAAM,CACL,UAAU,EACV,kFAAkF,CACnF;SACA,MAAM,CAAC,SAAS,EAAE,2BAA2B,CAAC;SAC9C,MAAM,CAAC,cAAc,CAAC;SACtB,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCL,CACI,CAAC;IAEJ,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Reading the project config for the surfaces an ARD manifest can advertise.
3
+ *
4
+ * Everything here is pure — config in, surfaces out — so the derivation rules
5
+ * are unit-testable without touching a filesystem or a manifest.
6
+ *
7
+ * ## Two collectors, because two rules
8
+ *
9
+ * A **skill** derives its media type from the surface kind alone, so every
10
+ * published skill becomes an entry with no author action. A **marketplace**, an
11
+ * **OKF bundle** and an MCP server derive nothing: the ARD specification names
12
+ * no media type for any of them (see `deriveArdMediaType`), so they are emitted
13
+ * only when the author supplies `ard.entries.<name>.type`, and are otherwise
14
+ * *reported as skipped* — never silently dropped, and never guessed at.
15
+ */
16
+ import { type ArdSurface, type ArdSurfaceKind, type ProjectConfig } from '@vibe-agent-toolkit/resources';
17
+ /** A surface VAT declined to emit, and the reason a reader can act on. */
18
+ export interface SkippedArdSurface {
19
+ readonly name: string;
20
+ readonly kind: ArdSurfaceKind;
21
+ readonly reason: string;
22
+ }
23
+ export interface ArdSurfaceCollection {
24
+ readonly surfaces: readonly ArdSurface[];
25
+ readonly skipped: readonly SkippedArdSurface[];
26
+ }
27
+ /** Facts that apply to every surface in a run, derived once by the caller. */
28
+ export interface ArdSurfaceDefaults {
29
+ /** The project's own package version, when it has one. */
30
+ readonly version?: string | undefined;
31
+ /**
32
+ * Names of the skills `skills.include` discovery actually found.
33
+ *
34
+ * 🚨 Without this, every `skills.config` key was advertised on the author's
35
+ * word alone: a project with NO `skills/` directory and two config keys
36
+ * emitted two entries carrying real URLs at exit 0, with nothing on stderr —
37
+ * a published discovery document that is entirely 404s. The `skipped` channel
38
+ * exists so a surface is never silently DROPPED; the mirror case, silently
39
+ * INVENTING one, had no guard at all.
40
+ *
41
+ * Supplied by the caller rather than crawled here so this module stays pure,
42
+ * and `undefined` rather than `[]` when discovery did not run — an empty
43
+ * array is the answer "nothing exists", which must not be spelled the same
44
+ * way as "nobody asked".
45
+ */
46
+ readonly discoveredSkills?: readonly string[] | undefined;
47
+ }
48
+ /**
49
+ * Every surface the project config declares, split into what VAT will emit and
50
+ * what it declined to.
51
+ *
52
+ * @throws never — a config with no `ard` block yields an empty collection; the
53
+ * caller decides whether that is a failure (`runArdEmit` does).
54
+ */
55
+ export declare function collectArdSurfaces(config: ProjectConfig, defaults: ArdSurfaceDefaults): ArdSurfaceCollection;
56
+ //# sourceMappingURL=surfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.d.ts","sourceRoot":"","sources":["../../../src/commands/ard/surfaces.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,+BAA+B,CAAC;AAEvC,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAChD;AAED,8EAA8E;AAC9E,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC3D;AA+ID;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,kBAAkB,GAC3B,oBAAoB,CAwBtB"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Reading the project config for the surfaces an ARD manifest can advertise.
3
+ *
4
+ * Everything here is pure — config in, surfaces out — so the derivation rules
5
+ * are unit-testable without touching a filesystem or a manifest.
6
+ *
7
+ * ## Two collectors, because two rules
8
+ *
9
+ * A **skill** derives its media type from the surface kind alone, so every
10
+ * published skill becomes an entry with no author action. A **marketplace**, an
11
+ * **OKF bundle** and an MCP server derive nothing: the ARD specification names
12
+ * no media type for any of them (see `deriveArdMediaType`), so they are emitted
13
+ * only when the author supplies `ard.entries.<name>.type`, and are otherwise
14
+ * *reported as skipped* — never silently dropped, and never guessed at.
15
+ */
16
+ import { ardEntryOverrideKey, defaultArdNamespace, findArdEntryOverride, } from '@vibe-agent-toolkit/resources';
17
+ /**
18
+ * The path appended to `ard.baseUrl`, mirroring the URN's namespace segment.
19
+ *
20
+ * A convention, not a discovered fact: VAT knows what it publishes but not how
21
+ * an adopter hosts it. `ard.baseUrl` is the knob that makes it right, and it is
22
+ * the one field an author must set for URLs to be derivable at all.
23
+ */
24
+ function urlPathFor(kind, name, ard) {
25
+ return `${ard.namespace ?? defaultArdNamespace(kind)}/${name}`;
26
+ }
27
+ /**
28
+ * Build one surface.
29
+ *
30
+ * ⚠️ `displayName` is the config key **verbatim**. De-slugging it into
31
+ * `Vat Skill Authoring` would invent capitalisation VAT has no source for, and
32
+ * this lane's whole discipline is that a plausible fabrication is worse than an
33
+ * honest plain value. A richer caller that has read a `SKILL.md` title should
34
+ * pass a better one — `buildArdEntry` takes whatever it is given.
35
+ */
36
+ function makeSurface(kind, name, ard, defaults) {
37
+ return {
38
+ kind,
39
+ name,
40
+ displayName: name,
41
+ urlPath: urlPathFor(kind, name, ard),
42
+ ...(defaults.version === undefined ? {} : { version: defaults.version }),
43
+ };
44
+ }
45
+ /** Skills the project actually publishes, in config order. */
46
+ function collectSkillSurfaces(config, ard, defaults, surfaces, skipped) {
47
+ const skills = config.skills;
48
+ if (skills === undefined)
49
+ return;
50
+ // 🪤 `skills.config` is OPTIONAL in VAT — glob discovery via `skills.include`
51
+ // is the ordinary way to declare skills, and this repo's own config uses it.
52
+ // Returning quietly here meant a project with discovered-but-unconfigured
53
+ // skills emitted `{"entries": []}` and exited 0, saying nothing: the headline
54
+ // use case producing nothing, silently, for the common shape. Found by
55
+ // running the command, not by reading it.
56
+ //
57
+ // Reported through the existing `skipped` channel rather than as an error,
58
+ // because an empty manifest is a legal artifact and the run did not fail —
59
+ // what was wrong was the silence. Absence of a `skills` block entirely is NOT
60
+ // reported: there is nothing to advertise and no mistake to point at, and a
61
+ // warning there would train people to ignore this one.
62
+ if (skills.config === undefined || Object.keys(skills.config).length === 0) {
63
+ skipped.push({
64
+ name: '(discovered skills)',
65
+ kind: 'skill',
66
+ reason: 'skills.config is empty, so no skill was advertised. ARD entries are derived per named skill; add `skills.config.<name>` for each skill you want announced. Discovery globs alone (`skills.include`) do not name them.',
67
+ });
68
+ return;
69
+ }
70
+ const fallbackPublish = skills.defaults?.publish ?? true;
71
+ // `undefined` means discovery did not run, which is NOT the same claim as
72
+ // "discovery found nothing" — see `ArdSurfaceDefaults.discoveredSkills`.
73
+ const discovered = defaults.discoveredSkills === undefined ? undefined : new Set(defaults.discoveredSkills);
74
+ for (const [name, packaging] of Object.entries(skills.config)) {
75
+ if ((packaging.publish ?? fallbackPublish) === false) {
76
+ skipped.push({
77
+ name,
78
+ kind: 'skill',
79
+ reason: 'skills.config.' + name + '.publish is false — an unpublished skill is not advertised.',
80
+ });
81
+ continue;
82
+ }
83
+ // Checked AFTER the publish opt-out, so an unpublished skill is reported
84
+ // once, for the reason its author chose, rather than twice.
85
+ if (discovered !== undefined && !discovered.has(name)) {
86
+ skipped.push({
87
+ name,
88
+ kind: 'skill',
89
+ reason: `skills.config.${name} names a skill that \`skills.include\` discovery did not find, so ` +
90
+ 'VAT will not advertise a URL for it — a discovery document must not publish a 404. ' +
91
+ 'Either add the SKILL.md the globs reach, or remove the config key.',
92
+ });
93
+ continue;
94
+ }
95
+ surfaces.push(makeSurface('skill', name, ard, defaults));
96
+ }
97
+ }
98
+ /**
99
+ * Surfaces the specification names no media type for.
100
+ *
101
+ * Emitted only on an explicit `ard.entries.<name>.type`. The skip reason names
102
+ * the config key, so the fix is readable from the terminal without opening
103
+ * documentation.
104
+ */
105
+ function collectOverrideOnlySurfaces(names, kind, ard, defaults, surfaces, skipped) {
106
+ for (const name of names) {
107
+ // Looked up through the builder's OWN function, not a second copy of the
108
+ // rule. 🚨 This site used to restate `qualified ?? bare` inline, and neither
109
+ // copy was pinned — two mutations reversing them to bare-first stayed green
110
+ // — so the two could disagree about which block a surface gets while every
111
+ // test passed. Here the answer decides EMITTABILITY: a lookup that read the
112
+ // bare key first would advertise a marketplace on the strength of a SKILL's
113
+ // override.
114
+ const overrides = findArdEntryOverride(ard, kind, name);
115
+ if (overrides?.type === undefined) {
116
+ skipped.push({
117
+ name,
118
+ kind,
119
+ reason:
120
+ // No indefinite article: `kind` interpolates to `mcp-server` and
121
+ // `okf-bundle` as well as `skill`, so a hardcoded "a" is wrong for
122
+ // half the vocabulary and "a/an" cannot be chosen from the kind
123
+ // without a rule this message does not deserve.
124
+ `the ARD specification names no media type for surface kind "${kind}", so VAT derives none. ` +
125
+ `Set \`ard.entries."${ardEntryOverrideKey(kind, name)}".type\` to advertise it.`,
126
+ });
127
+ continue;
128
+ }
129
+ surfaces.push(makeSurface(kind, name, ard, defaults));
130
+ }
131
+ }
132
+ /**
133
+ * Every surface the project config declares, split into what VAT will emit and
134
+ * what it declined to.
135
+ *
136
+ * @throws never — a config with no `ard` block yields an empty collection; the
137
+ * caller decides whether that is a failure (`runArdEmit` does).
138
+ */
139
+ export function collectArdSurfaces(config, defaults) {
140
+ const surfaces = [];
141
+ const skipped = [];
142
+ const ard = config.ard;
143
+ if (ard === undefined)
144
+ return { surfaces, skipped };
145
+ collectSkillSurfaces(config, ard, defaults, surfaces, skipped);
146
+ collectOverrideOnlySurfaces(Object.keys(config.claude?.marketplaces ?? {}), 'marketplace', ard, defaults, surfaces, skipped);
147
+ collectOverrideOnlySurfaces(Object.keys(config.okf?.bundles ?? {}), 'okf-bundle', ard, defaults, surfaces, skipped);
148
+ return { surfaces, skipped };
149
+ }
150
+ //# sourceMappingURL=surfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surfaces.js","sourceRoot":"","sources":["../../../src/commands/ard/surfaces.ts"],"names":[],"mappings":"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"}