@canonical/pragma-cli 0.32.0 → 0.34.0

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 (295) hide show
  1. package/README.md +72 -0
  2. package/dist/pragma +0 -0
  3. package/package.json +19 -15
  4. package/pragma.conf.ts +664 -0
  5. package/src/bin.ts +15 -6
  6. package/src/capabilities/block.parity.test.ts +250 -0
  7. package/src/capabilities/capabilities/capabilities.render.ts +3 -2
  8. package/src/capabilities/capabilities/capabilities.test.ts +10 -1
  9. package/src/capabilities/capabilities/capabilities.verb.ts +32 -14
  10. package/src/capabilities/capabilities/catalog.ts +20 -8
  11. package/src/capabilities/capabilities/hints.ts +21 -36
  12. package/src/capabilities/capabilities/types.ts +2 -0
  13. package/src/capabilities/colophon/collectColophon.ts +34 -19
  14. package/src/capabilities/colophon/colophon.render.test.ts +31 -4
  15. package/src/capabilities/colophon/colophon.render.ts +13 -4
  16. package/src/capabilities/colophon/colophon.test.ts +3 -3
  17. package/src/capabilities/colophon/colophon.verb.ts +11 -4
  18. package/src/capabilities/colophon/markdownTerminal.ts +33 -14
  19. package/src/capabilities/colophon/types.ts +16 -7
  20. package/src/capabilities/config/collectConfigShow.test.ts +57 -0
  21. package/src/capabilities/config/collectConfigShow.ts +41 -4
  22. package/src/capabilities/config/fields.ts +10 -108
  23. package/src/capabilities/config/set.test.ts +6 -6
  24. package/src/capabilities/config/set.verb.ts +12 -8
  25. package/src/capabilities/config/show.render.test.ts +137 -0
  26. package/src/capabilities/config/show.render.ts +57 -16
  27. package/src/capabilities/config/show.verb.ts +9 -8
  28. package/src/capabilities/config/types.ts +8 -0
  29. package/src/capabilities/create/byteEquality.subprocess.test.ts +1 -1
  30. package/src/capabilities/create/byteEquality.test.ts +82 -101
  31. package/src/capabilities/create/compiledCreate.subprocess.test.ts +53 -16
  32. package/src/capabilities/create/constants.ts +75 -0
  33. package/src/capabilities/create/create.mcp.test.ts +2 -2
  34. package/src/capabilities/create/create.test.ts +192 -16
  35. package/src/capabilities/create/create.verb.ts +208 -79
  36. package/src/capabilities/create/index.ts +2 -10
  37. package/src/capabilities/create/pickGenerator.ts +34 -28
  38. package/src/capabilities/create/templates.embedded.generated.ts +4 -29
  39. package/src/capabilities/create/types.ts +10 -6
  40. package/src/capabilities/{standard/parity.test.ts → distribution.parity.test.ts} +24 -14
  41. package/src/capabilities/distribution.test.ts +120 -0
  42. package/src/capabilities/distribution.ts +59 -0
  43. package/src/capabilities/doctor/checks/checkConfigFile.ts +6 -5
  44. package/src/capabilities/doctor/checks/checkKeStore.ts +2 -2
  45. package/src/capabilities/doctor/checks/checkMcpCommands.ts +6 -0
  46. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +15 -8
  47. package/src/capabilities/doctor/checks/checkPackageRefs.ts +79 -45
  48. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +3 -2
  49. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +61 -11
  50. package/src/capabilities/doctor/checks/checkShellCompletions.ts +63 -23
  51. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +3 -2
  52. package/src/capabilities/doctor/checks/deriveBand.test.ts +42 -0
  53. package/src/capabilities/doctor/checks/deriveBand.ts +28 -0
  54. package/src/capabilities/doctor/doctor.render.test.ts +170 -0
  55. package/src/capabilities/doctor/doctor.render.ts +117 -34
  56. package/src/capabilities/doctor/doctor.test.ts +68 -9
  57. package/src/capabilities/doctor/doctor.verb.ts +6 -2
  58. package/src/capabilities/doctor/runChecks.ts +33 -9
  59. package/src/capabilities/doctor/types.ts +16 -1
  60. package/src/capabilities/emptyRecovery.test.ts +32 -15
  61. package/src/capabilities/graph/inspect.verb.ts +3 -2
  62. package/src/capabilities/graph/query.verb.ts +3 -2
  63. package/src/capabilities/graph/runQuery.ts +8 -5
  64. package/src/capabilities/index.ts +22 -18
  65. package/src/capabilities/info/collectInfo.ts +10 -6
  66. package/src/capabilities/info/info.render.ts +3 -2
  67. package/src/capabilities/info/info.verb.ts +3 -2
  68. package/src/capabilities/lazy.test.ts +93 -2
  69. package/src/capabilities/ontology/index.ts +10 -3
  70. package/src/capabilities/ontology/ontology.test.ts +157 -5
  71. package/src/capabilities/ontology/verbs.ts +203 -104
  72. package/src/capabilities/prompt/prompt.render.test.ts +94 -0
  73. package/src/capabilities/prompt/prompt.render.ts +23 -6
  74. package/src/capabilities/prompt/prompt.test.ts +68 -1
  75. package/src/capabilities/prompt/verbs.ts +24 -11
  76. package/src/capabilities/reference.test.ts +32 -0
  77. package/src/capabilities/resources/provider.ts +58 -25
  78. package/src/capabilities/resources/resources.test.ts +176 -21
  79. package/src/capabilities/scopeTypeSync.test.ts +37 -0
  80. package/src/capabilities/setup/index.ts +7 -1
  81. package/src/capabilities/setup/operations/setupCompletions.ts +49 -16
  82. package/src/capabilities/setup/operations/setupGenerator.ts +166 -63
  83. package/src/capabilities/setup/operations/setupLsp.ts +56 -12
  84. package/src/capabilities/setup/operations/setupMcp.ts +216 -39
  85. package/src/capabilities/setup/operations/setupSkills.ts +10 -4
  86. package/src/capabilities/setup/setup.render.test.ts +109 -0
  87. package/src/capabilities/setup/setup.render.ts +61 -14
  88. package/src/capabilities/setup/setup.test.ts +352 -1
  89. package/src/capabilities/setup/setup.verb.ts +68 -9
  90. package/src/capabilities/setup/shell.ts +29 -3
  91. package/src/capabilities/setup/types.ts +59 -2
  92. package/src/capabilities/shared/bands.ts +16 -0
  93. package/src/capabilities/skill/discover.ts +11 -5
  94. package/src/capabilities/skill/render.ts +4 -5
  95. package/src/capabilities/skill/verbs.ts +7 -7
  96. package/src/capabilities/sources/collectStatus.ts +69 -49
  97. package/src/capabilities/sources/index.ts +1 -1
  98. package/src/capabilities/sources/installSkills.ts +2 -2
  99. package/src/capabilities/sources/runUpdate.ts +146 -98
  100. package/src/capabilities/sources/sources.test.ts +264 -84
  101. package/src/capabilities/sources/status.render.test.ts +94 -0
  102. package/src/capabilities/sources/status.render.ts +55 -33
  103. package/src/capabilities/sources/status.verb.ts +15 -8
  104. package/src/capabilities/sources/types.ts +18 -25
  105. package/src/capabilities/sources/update.render.ts +9 -2
  106. package/src/capabilities/sources/update.verb.ts +12 -23
  107. package/src/capabilities/surface.test.ts +65 -17
  108. package/src/capabilities/tier.parity.test.ts +144 -0
  109. package/src/capabilities/upgrade/upgrade.verb.ts +7 -3
  110. package/src/constants.test.ts +9 -7
  111. package/src/constants.ts +49 -23
  112. package/src/identity.test.ts +333 -0
  113. package/src/index.ts +2 -2
  114. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +18 -16
  115. package/src/kernel/completion/complete.test.ts +3 -5
  116. package/src/kernel/completion/emitScripts.test.ts +1 -1
  117. package/src/kernel/completion/emitScripts.ts +4 -2
  118. package/src/kernel/completion/entitySource.test.ts +185 -41
  119. package/src/kernel/completion/entitySource.ts +131 -113
  120. package/src/kernel/completion/model.test.ts +3 -3
  121. package/src/kernel/completion/model.ts +11 -1
  122. package/src/kernel/completion/parse.test.ts +2 -4
  123. package/src/kernel/completion/safety.test.ts +82 -36
  124. package/src/kernel/completion/shellDrive.test.ts +592 -0
  125. package/src/kernel/completion/templates/fish.ts +28 -6
  126. package/src/kernel/completion/types.ts +3 -3
  127. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +1 -1
  128. package/src/kernel/config/defaults.test.ts +85 -0
  129. package/src/kernel/config/defaults.ts +12 -23
  130. package/src/kernel/config/evaluateProjectConfig.ts +2 -3
  131. package/src/kernel/config/findProjectConfig.ts +4 -3
  132. package/src/kernel/config/firstRun.ts +12 -5
  133. package/src/kernel/config/globalConfig.ts +2 -2
  134. package/src/kernel/config/index.ts +4 -5
  135. package/src/kernel/config/paths.ts +17 -17
  136. package/src/kernel/config/readConfig.test.ts +242 -6
  137. package/src/kernel/config/readConfig.ts +8 -8
  138. package/src/kernel/config/schema.test.ts +50 -0
  139. package/src/kernel/config/schema.ts +97 -10
  140. package/src/kernel/config/types.ts +73 -19
  141. package/src/kernel/copy.test.ts +453 -0
  142. package/src/kernel/error/PragmaError.test.ts +5 -5
  143. package/src/kernel/error/constants.ts +3 -2
  144. package/src/kernel/error/index.ts +1 -1
  145. package/src/kernel/error/recovery.test.ts +22 -45
  146. package/src/kernel/error/recovery.ts +22 -27
  147. package/src/kernel/error/renderError.ts +1 -1
  148. package/src/kernel/error/types.ts +5 -4
  149. package/src/kernel/packs/collect.test.ts +195 -11
  150. package/src/kernel/packs/collect.ts +213 -58
  151. package/src/kernel/packs/compile.test.ts +163 -7
  152. package/src/kernel/packs/compile.ts +15 -12
  153. package/src/kernel/packs/disclosure.test.ts +5 -2
  154. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +11 -10
  155. package/src/kernel/packs/graphqlSource.test.ts +6 -3
  156. package/src/kernel/packs/iri.ts +5 -7
  157. package/src/kernel/packs/renderPack.ts +5 -3
  158. package/src/kernel/packs/resolveEntity.ts +21 -17
  159. package/src/kernel/packs/runBodies.ts +15 -14
  160. package/src/kernel/packs/schema.ts +96 -10
  161. package/src/kernel/packs/sparql/runSelect.test.ts +104 -10
  162. package/src/kernel/packs/sparql/runSelect.ts +73 -34
  163. package/src/kernel/packs/toolDescription.test.ts +10 -2
  164. package/src/kernel/packs/types.ts +39 -4
  165. package/src/kernel/packs/uniqueness.ts +4 -4
  166. package/src/kernel/project/cli/buildProgram.test.ts +60 -11
  167. package/src/kernel/project/cli/buildProgram.ts +11 -0
  168. package/src/kernel/project/cli/dispatch.test.ts +67 -0
  169. package/src/kernel/project/cli/dispatch.ts +34 -12
  170. package/src/kernel/project/cli/globalFlags.test.ts +12 -4
  171. package/src/kernel/project/cli/globalFlags.ts +14 -14
  172. package/src/kernel/project/cli/helpFormat.ts +1 -1
  173. package/src/kernel/project/cli/rootHelp.ts +109 -107
  174. package/src/kernel/project/mcp/buildServer.ts +11 -6
  175. package/src/kernel/project/mcp/instructions.ts +12 -7
  176. package/src/kernel/project/mcp/mcpError.ts +52 -0
  177. package/src/kernel/project/mcp/parity.test.ts +39 -1
  178. package/src/kernel/project/mcp/prompts/prompts.test.ts +128 -5
  179. package/src/kernel/project/mcp/prompts/provider.ts +51 -7
  180. package/src/kernel/project/mcp/prompts/source.ts +68 -67
  181. package/src/kernel/project/mcp/registerVerb.ts +25 -6
  182. package/src/kernel/project/mcp/serve.ts +11 -3
  183. package/src/kernel/project/mcp/toolDescriptions.test.ts +6 -2
  184. package/src/kernel/render/disclosure.ts +4 -2
  185. package/src/kernel/render/formatters.ts +5 -4
  186. package/src/kernel/render/prefixes.test.ts +36 -0
  187. package/src/kernel/render/prefixes.ts +40 -13
  188. package/src/kernel/render/renderers.test.ts +35 -1
  189. package/src/kernel/render/renderers.ts +25 -7
  190. package/src/kernel/render/style.test.ts +31 -0
  191. package/src/kernel/render/style.ts +74 -0
  192. package/src/kernel/runtime/graphpack/build.ts +57 -3
  193. package/src/kernel/runtime/graphpack/buildIndex.test.ts +149 -0
  194. package/src/kernel/runtime/graphpack/buildIndex.ts +173 -50
  195. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +5 -8
  196. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +3 -4
  197. package/src/kernel/runtime/graphpack/embedded/pack.stories.generated.ts +3 -0
  198. package/src/kernel/runtime/graphpack/embedded.ts +37 -11
  199. package/src/kernel/runtime/graphpack/graphpack.test.ts +274 -6
  200. package/src/kernel/runtime/graphpack/hash.ts +3 -2
  201. package/src/kernel/runtime/graphpack/index.ts +1 -1
  202. package/src/kernel/runtime/graphpack/manifest.ts +114 -12
  203. package/src/kernel/runtime/graphpack/read.ts +32 -22
  204. package/src/kernel/runtime/graphpack/schemas.ts +74 -0
  205. package/src/kernel/runtime/graphpack/stories.ts +84 -0
  206. package/src/kernel/runtime/graphpack/types.ts +72 -45
  207. package/src/kernel/runtime/loadSession.ts +4 -12
  208. package/src/kernel/runtime/paths.ts +64 -15
  209. package/src/kernel/runtime/probe.test.ts +8 -4
  210. package/src/kernel/runtime/readEntity.ts +6 -5
  211. package/src/kernel/runtime/refs/gitOps.ts +1 -19
  212. package/src/kernel/runtime/refs/parseRef.ts +7 -7
  213. package/src/kernel/runtime/refs/resolve.ts +141 -65
  214. package/src/kernel/runtime/resolveSources.test.ts +63 -24
  215. package/src/kernel/runtime/resolveSources.ts +36 -25
  216. package/src/kernel/runtime/storeReadiness.ts +62 -0
  217. package/src/kernel/runtime/storeless.test.ts +1 -1
  218. package/src/kernel/runtime/types.ts +1 -1
  219. package/src/kernel/runtime/wasmEmbed.test.ts +25 -20
  220. package/src/kernel/spec/emitReference.test.ts +196 -0
  221. package/src/kernel/spec/emitReference.ts +624 -0
  222. package/src/kernel/spec/emitSurface.ts +13 -7
  223. package/src/kernel/spec/index.ts +2 -0
  224. package/src/kernel/spec/surfaceConformance.test.ts +2 -2
  225. package/src/kernel/spec/surfaceConformance.ts +8 -0
  226. package/src/kernel/spec/types.ts +29 -9
  227. package/src/kernel/spec/validate.ts +2 -1
  228. package/src/kernel/vocabulary.test.ts +164 -0
  229. package/src/kernel/vocabulary.ts +146 -0
  230. package/src/testing/PARITY_GAPS.ts +9 -3
  231. package/src/testing/behavioral/README.md +3 -3
  232. package/src/testing/behavioral/autoLlm.e2e.test.ts +12 -2
  233. package/src/testing/behavioral/completion.test.ts +21 -8
  234. package/src/testing/behavioral/disclosure.test.ts +12 -0
  235. package/src/testing/behavioral/docExamples.test.ts +283 -0
  236. package/src/testing/behavioral/errorMatrix.mcp.test.ts +4 -3
  237. package/src/testing/behavioral/errorMatrix.storeless.test.ts +3 -2
  238. package/src/testing/behavioral/exitCodes.e2e.test.ts +6 -5
  239. package/src/testing/behavioral/harness.foundation.test.ts +14 -5
  240. package/src/testing/behavioral/journeys.cli.test.ts +116 -73
  241. package/src/testing/behavioral/journeys.defaultPack.test.ts +477 -0
  242. package/src/testing/behavioral/journeys.firstInstall.test.ts +167 -0
  243. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +66 -0
  244. package/src/testing/behavioral/journeys.livePack.e2e.test.ts +129 -0
  245. package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +179 -0
  246. package/src/testing/behavioral/journeys.packageStories.test.ts +188 -0
  247. package/src/testing/behavioral/liveReadSurface.ts +4 -3
  248. package/src/testing/behavioral/mcpSurface.test.ts +10 -5
  249. package/src/testing/behavioral/staleCommands.test.ts +86 -0
  250. package/src/testing/eval/__snapshots__/eval.test.ts.snap +9 -9
  251. package/src/testing/eval/cases/assembly.ts +16 -9
  252. package/src/testing/eval/cases/effectful.ts +31 -16
  253. package/src/testing/eval/cases/readNouns.ts +23 -18
  254. package/src/testing/eval/cases/stable.ts +5 -1
  255. package/src/testing/eval/eval.test.ts +7 -1
  256. package/src/testing/fixtures/fixtureCapability.ts +201 -1
  257. package/src/testing/fixtures/graph/canonical.ts +6 -3
  258. package/src/testing/fixtures/graph/defaultPack.ts +179 -0
  259. package/src/testing/fixtures/graph/owlExport.ts +97 -0
  260. package/src/testing/helpers/extractSnippets.ts +29 -0
  261. package/src/testing/helpers/fixtureGraph.ts +33 -16
  262. package/src/testing/helpers/golden.ts +1 -1
  263. package/src/testing/helpers/packRuntime.ts +2 -3
  264. package/src/testing/helpers/projectCli.ts +2 -1
  265. package/src/testing/helpers/projectMcp.ts +6 -0
  266. package/src/testing/perf/budgets.test.ts +4 -0
  267. package/src/testing/perf/budgets.ts +22 -7
  268. package/src/testing/perf/globalSetup.ts +121 -6
  269. package/src/types.ts +2 -2
  270. package/src/capabilities/block/blockList.verb.ts +0 -150
  271. package/src/capabilities/block/index.ts +0 -25
  272. package/src/capabilities/block/pack.ts +0 -155
  273. package/src/capabilities/block/parity.test.ts +0 -180
  274. package/src/capabilities/block/tierChain.ts +0 -78
  275. package/src/capabilities/colophon/pragmaColophon.ts +0 -66
  276. package/src/capabilities/config/field.test.ts +0 -188
  277. package/src/capabilities/modifier/index.ts +0 -15
  278. package/src/capabilities/modifier/pack.ts +0 -64
  279. package/src/capabilities/standard/index.ts +0 -18
  280. package/src/capabilities/standard/pack.ts +0 -128
  281. package/src/capabilities/tier/index.ts +0 -19
  282. package/src/capabilities/tier/lookup.render.ts +0 -34
  283. package/src/capabilities/tier/lookup.test.ts +0 -68
  284. package/src/capabilities/tier/lookup.verb.ts +0 -44
  285. package/src/capabilities/tier/pack.ts +0 -28
  286. package/src/capabilities/tier/runLookup.ts +0 -59
  287. package/src/capabilities/token/addConfig.render.ts +0 -27
  288. package/src/capabilities/token/addConfig.test.ts +0 -62
  289. package/src/capabilities/token/addConfig.verb.ts +0 -40
  290. package/src/capabilities/token/index.ts +0 -19
  291. package/src/capabilities/token/pack.ts +0 -58
  292. package/src/capabilities/token/runAddConfig.ts +0 -95
  293. package/src/kernel/completion/bashDrive.test.ts +0 -73
  294. package/src/kernel/runtime/graphpack/embedded/sample.ttl +0 -39
  295. package/src/kernel/runtime/lock.ts +0 -90
@@ -0,0 +1,62 @@
1
+ /**
2
+ * The STORELESS store-readiness check — the ONE source of the cold-store
3
+ * `STORE_UNAVAILABLE` error (its message AND its `pragma sources update` /
4
+ * `sources_update` recovery), shared by the lazy store boot ({@link
5
+ * loadStoreSession}) and the native MCP discovery surfaces (the `prompts/*`
6
+ * provider, the `pragma:{+uri}` resource browser).
7
+ *
8
+ * A cold store must present the SAME diagnostic on every surface: an agent that
9
+ * lists prompts over the `prompt_list` tool (store-backed, so its `needsStore`
10
+ * pre-check throws) and one that lists them over native `prompts/list` must see
11
+ * the identical `STORE_UNAVAILABLE` + `sources_update` recovery, not one error
12
+ * and one silently-empty list. Centralizing the construction here is what keeps
13
+ * those surfaces from drifting apart.
14
+ *
15
+ * It reaches only {@link resolveSources} (a pointer + config probe — no store,
16
+ * no ke), so a caller on the storeless fast path can pre-check availability
17
+ * without ever booting the store.
18
+ */
19
+
20
+ import type { ConfigLayers } from "../config/types.js";
21
+ import { PragmaError } from "../error/PragmaError.js";
22
+ import { cliRecovery } from "../error/recovery.js";
23
+ import { resolveSources } from "./resolveSources.js";
24
+
25
+ /**
26
+ * Build the canonical cold-store `STORE_UNAVAILABLE` error: the reason plus the
27
+ * single `pragma sources update` recovery that also names the `sources_update`
28
+ * tool an agent calls (then retries — PR9's C1 cold-store retry succeeds).
29
+ *
30
+ * @param reason - The boot decision's reason (e.g. "the built pack is missing
31
+ * from the cache").
32
+ * @returns The structured STORE_UNAVAILABLE error.
33
+ */
34
+ export function storeUnavailable(reason: string): PragmaError {
35
+ return PragmaError.storeUnavailable(`${reason}.`, {
36
+ recovery: cliRecovery(
37
+ "sources update",
38
+ "Build the local store from the configured packs.",
39
+ { tool: "sources_update" },
40
+ ),
41
+ });
42
+ }
43
+
44
+ /**
45
+ * The STORE_UNAVAILABLE error to surface when the store cannot boot from the
46
+ * current config and active-pack pointer, or `undefined` when a store read may
47
+ * proceed. STORELESS —
48
+ * probes the decision table only, never constructs the store.
49
+ *
50
+ * @param layers - The resolved config layers.
51
+ * @param cwd - The project directory the boot resolves against.
52
+ * @returns The error to surface cold, or `undefined` when the store is available.
53
+ */
54
+ export function checkStoreAvailable(
55
+ layers: ConfigLayers,
56
+ cwd: string,
57
+ ): PragmaError | undefined {
58
+ const decision = resolveSources(layers, cwd);
59
+ return decision.kind === "unavailable"
60
+ ? storeUnavailable(decision.reason)
61
+ : undefined;
62
+ }
@@ -58,7 +58,7 @@ describe("storeless guarantee — the store never boots for storeless verbs (PRO
58
58
  expect(runtime.store.booted).toBe(false);
59
59
  });
60
60
 
61
- it("sources status does not construct the store (reports a cold store)", async () => {
61
+ it("sources status does not construct the store", async () => {
62
62
  const runtime = bootRuntime(FLAGS, freshCwd());
63
63
  const outcome = await executeVerb(sourcesStatusVerb, {}, NO_MUT, runtime);
64
64
  expect(outcome.exitCode).toBe(0);
@@ -17,7 +17,7 @@ import type { ConfigLayers } from "../config/types.js";
17
17
  * separately so inferred mode can shape output without switching behaviour.
18
18
  */
19
19
  export interface GlobalFlags {
20
- /** Condensed Markdown output for LLM/agent consumption. */
20
+ /** Condensed Markdown output, from `--format llm` or auto-detection. */
21
21
  readonly llm: boolean;
22
22
  /** True when `llm` was inferred from a non-interactive stdout, not requested. */
23
23
  readonly autoLlm?: boolean;
@@ -1,15 +1,10 @@
1
1
  import { spawnSync } from "node:child_process";
2
- import {
3
- existsSync,
4
- mkdirSync,
5
- mkdtempSync,
6
- rmSync,
7
- writeFileSync,
8
- } from "node:fs";
2
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
9
3
  import { tmpdir } from "node:os";
10
4
  import { join } from "node:path";
11
5
  import { fileURLToPath } from "node:url";
12
6
  import { afterAll, beforeAll, describe, expect, it } from "vitest";
7
+ import { embeddedManifest } from "./graphpack/embedded.js";
13
8
 
14
9
  /**
15
10
  * The store-boot path only fully lives in the standalone binary: this is the
@@ -74,8 +69,11 @@ describe("oxigraph WASM + embedded pack embed in the compiled binary (PROTECTED)
74
69
  triples: string;
75
70
  };
76
71
  expect(out.ok).toBe(true);
77
- expect(out.entities).toBe(6);
78
- expect(Number(out.triples)).toBeGreaterThan(0);
72
+ // The compiled binary is the only place this is worth asserting: the store
73
+ // it booted from the inlined `data.nq` must hold exactly what the committed
74
+ // `manifest.json` claims was built into it.
75
+ expect(Number(out.triples)).toBe(embeddedManifest().tripleCount);
76
+ expect(out.entities).toBeGreaterThan(0);
79
77
  });
80
78
 
81
79
  it("dist binary runs storeless sources status", () => {
@@ -83,18 +81,17 @@ describe("oxigraph WASM + embedded pack embed in the compiled binary (PROTECTED)
83
81
  expect(run.status, run.stderr).toBe(0);
84
82
  const envelope = JSON.parse(run.stdout.trim()) as {
85
83
  ok: boolean;
86
- data: { lockPresent: boolean; cached: boolean };
84
+ data: { store: string };
87
85
  };
88
86
  expect(envelope.ok).toBe(true);
89
- // A fresh install: no lock, store not yet built.
90
- expect(envelope.data.lockPresent).toBe(false);
91
- expect(envelope.data.cached).toBe(false);
87
+ // A fresh install: nothing built here, so the embedded pack answers reads.
88
+ expect(envelope.data.store).toBe("embedded");
92
89
  });
93
90
 
94
91
  // Regression guard: `sources update` walks a package's TTL directories. The
95
92
  // compiled binary's node:fs globSync mishandles `**` (returns bogus paths),
96
93
  // which the in-process suite could not catch — so exercise the real binary.
97
- it("dist binary runs sources update end-to-end (build + lock + status)", () => {
94
+ it("dist binary runs sources update end-to-end (build + point + status)", () => {
98
95
  const pkg = join(workdir, "pkg");
99
96
  const proj = join(workdir, "proj");
100
97
  mkdirSync(join(pkg, "definitions"), { recursive: true });
@@ -110,7 +107,7 @@ ex:one a ex:Widget ; rdfs:label "One" .
110
107
  );
111
108
  writeFileSync(
112
109
  join(proj, "pragma.config.ts"),
113
- `export default { packages: [{ name: "pkg-a", source: "file://${pkg}" }] };\n`,
110
+ `export default { packs: [{ name: "pkg-a", source: "file://${pkg}" }] };\n`,
114
111
  );
115
112
 
116
113
  const env = {
@@ -129,14 +126,22 @@ ex:one a ex:Widget ; rdfs:label "One" .
129
126
 
130
127
  const update = inProj(["sources", "update", "--yes", "--format", "json"]);
131
128
  expect(update.status, update.stderr).toBe(0);
132
- expect(existsSync(join(proj, "pragma.lock.json"))).toBe(true);
129
+ const built = (
130
+ JSON.parse(update.stdout.trim()) as {
131
+ data: { contentHash: string };
132
+ }
133
+ ).data.contentHash;
134
+ expect(built).toMatch(/^[0-9a-f]{64}$/);
133
135
 
134
136
  const status = inProj(["sources", "status", "--format", "json"]);
135
137
  const envelope = JSON.parse(status.stdout.trim()) as {
136
- data: { lockPresent: boolean; cached: boolean; entityCount: number };
138
+ data: { store: string; contentHash: string; entityCount: number };
137
139
  };
138
- expect(envelope.data.lockPresent).toBe(true);
139
- expect(envelope.data.cached).toBe(true);
140
- expect(envelope.data.entityCount).toBe(2);
140
+ // The project now reads its OWN pack — the one the update just built.
141
+ expect(envelope.data.store).toBe("built");
142
+ expect(envelope.data.contentHash).toBe(built);
143
+ // Distinct abox subjects: the one individual (ex:one). The ex:Widget class
144
+ // is tbox schema, not an entity — the raw entity count would double this (A1).
145
+ expect(envelope.data.entityCount).toBe(1);
141
146
  });
142
147
  });
@@ -0,0 +1,196 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ fixtureModule,
4
+ fixtureReferenceModule,
5
+ } from "../../testing/fixtures/fixtureCapability.js";
6
+ import { ERROR_CODES } from "../error/constants.js";
7
+ import { emitReference } from "./emitReference.js";
8
+
9
+ /** The five pages every reference doc set carries. */
10
+ const PAGES = ["index.md", "commands.md", "tools.md", "errors.md", "config.md"];
11
+
12
+ describe("emitReference", () => {
13
+ const docs = emitReference([fixtureReferenceModule]);
14
+ const index = docs.get("index.md") ?? "";
15
+ const commands = docs.get("commands.md") ?? "";
16
+ const tools = docs.get("tools.md") ?? "";
17
+ const errors = docs.get("errors.md") ?? "";
18
+
19
+ it("emits exactly the five reference pages", () => {
20
+ expect([...docs.keys()].sort()).toEqual([...PAGES].sort());
21
+ });
22
+
23
+ it("ends every page in exactly one trailing newline", () => {
24
+ for (const content of docs.values()) {
25
+ expect(content.endsWith("\n")).toBe(true);
26
+ expect(content.endsWith("\n\n")).toBe(false);
27
+ }
28
+ });
29
+
30
+ it("is deterministic — the same catalog yields byte-identical pages", () => {
31
+ const again = emitReference([fixtureReferenceModule]);
32
+ for (const page of PAGES) {
33
+ expect(again.get(page)).toBe(docs.get(page));
34
+ }
35
+ });
36
+
37
+ describe("index.md", () => {
38
+ it("reports counts derived from the live grammar", () => {
39
+ // gizmo + ping = 2 nouns; local/scan/tidy/wipe/ping = 5 commands (hidden
40
+ // dropped); scan/tidy/wipe/ping = 4 tools (local withheld); 1 resource
41
+ // template (the module's `mcpResources` surface).
42
+ expect(index).toContain("**2** command nouns");
43
+ expect(index).toContain("**5** CLI commands");
44
+ expect(index).toContain("**4** MCP tools");
45
+ expect(index).toContain("**1** resource template(s)");
46
+ });
47
+
48
+ it("links the three sibling pages with relative paths", () => {
49
+ expect(index).toContain("(./commands.md)");
50
+ expect(index).toContain("(./tools.md)");
51
+ expect(index).toContain("(./errors.md)");
52
+ });
53
+ });
54
+
55
+ describe("commands.md", () => {
56
+ it("groups verbs under noun headings, sorted, hidden excluded", () => {
57
+ expect(commands).toContain("## gizmo");
58
+ expect(commands).toContain("## ping");
59
+ expect(commands.indexOf("## gizmo")).toBeLessThan(
60
+ commands.indexOf("## ping"),
61
+ );
62
+ expect(commands).not.toContain("hidden");
63
+ });
64
+
65
+ it("renders a read verb's usage, args, flags, attributes, and examples", () => {
66
+ expect(commands).toContain("### pragma gizmo scan");
67
+ expect(commands).toContain("pragma gizmo scan [targets...] [options]");
68
+ // Optional variadic positional token.
69
+ expect(commands).toContain("| `[targets...]` | no |");
70
+ // Enum flag: escaped pipe token, enum values, and default in the description.
71
+ expect(commands).toContain("| `--mode` | `<fast\\|slow>` |");
72
+ expect(commands).toContain("(one of: fast, slow) (default: fast)");
73
+ // Each flag kind renders its value placeholder.
74
+ expect(commands).toContain("| `--limit` | `<number>` |");
75
+ expect(commands).toContain("| `--label` | `<string>` |");
76
+ expect(commands).toContain("| `--include` | `<value...>` |");
77
+ // A bare boolean switch has no value placeholder.
78
+ expect(commands).toContain("| `--deep` | — |");
79
+ expect(commands).toContain("- Store: storeless.");
80
+ expect(commands).toContain("- MCP: exposed as the `gizmo_scan` tool.");
81
+ // A note becomes a trailing comment; a noteless example stays bare.
82
+ expect(commands).toContain("pragma gizmo scan # scan everything");
83
+ expect(commands).toContain("pragma gizmo scan alpha --mode slow");
84
+ });
85
+
86
+ it("marks a store-backed destructive mutation's CLI attributes", () => {
87
+ expect(commands).toContain("### pragma gizmo wipe");
88
+ expect(commands).toContain("pragma gizmo wipe <path>");
89
+ expect(commands).toContain(
90
+ "- Store: reads the local store (`pragma sources update` builds it).",
91
+ );
92
+ expect(commands).toContain("- Mutation: plan-first");
93
+ });
94
+
95
+ it("marks a visible verb withheld from MCP", () => {
96
+ expect(commands).toContain("### pragma gizmo local");
97
+ expect(commands).toContain("- MCP: not exposed (CLI-only).");
98
+ });
99
+
100
+ it("renders a self-verb with no sub-command in its invocation", () => {
101
+ expect(commands).toContain("### pragma ping");
102
+ expect(commands).toContain("```\npragma ping\n```");
103
+ });
104
+
105
+ it("falls back to the summary when a verb has no doc", () => {
106
+ // `ping` has no `doc`; its summary is the section body.
107
+ const pingSection = commands.slice(commands.indexOf("### pragma ping"));
108
+ expect(pingSection).toContain("Ping the gizmo host.");
109
+ });
110
+ });
111
+
112
+ describe("tools.md", () => {
113
+ it("adds the disclosure `detail` param and comma-joined enum types", () => {
114
+ expect(tools).toContain("### gizmo_scan");
115
+ expect(tools).toContain("| `mode` | enum(fast, slow) | no |");
116
+ expect(tools).toContain("| `include` | string[] | no |");
117
+ expect(tools).toContain(
118
+ "| `detail` | enum(summary, detailed) | no | Progressive-disclosure level (default summary). |",
119
+ );
120
+ });
121
+
122
+ it("adds confirm + cwd to a mutating tool and flags it destructive", () => {
123
+ const wipe = tools.slice(tools.indexOf("### gizmo_wipe"));
124
+ expect(wipe).toContain("| `confirm` | boolean | no |");
125
+ expect(wipe).toContain("| `cwd` | string | no |");
126
+ expect(tools).toContain(
127
+ "Mutation — plan-first (set `confirm: true` to apply). Marked destructive.",
128
+ );
129
+ });
130
+
131
+ it("marks a non-destructive mutating tool as such", () => {
132
+ const tidy = tools.slice(tools.indexOf("### gizmo_tidy"));
133
+ expect(tidy).toContain("| `confirm` | boolean | no |");
134
+ // The `destructive: false` branch of `formatToolAnnotations`.
135
+ expect(tools).toContain(
136
+ "Mutation — plan-first (set `confirm: true` to apply). Non-destructive.",
137
+ );
138
+ });
139
+
140
+ it("omits verbs withheld from MCP", () => {
141
+ expect(tools).not.toContain("gizmo_local");
142
+ });
143
+
144
+ it("marks a no-param tool as taking no input", () => {
145
+ const ping = tools.slice(tools.indexOf("### ping"));
146
+ expect(ping.slice(0, 200)).toContain("_No input parameters._");
147
+ });
148
+
149
+ it("renders every non-tool surface bullet the module declares", () => {
150
+ expect(tools).toContain("## Non-tool surface");
151
+ // The module declares an `mcpResources` template surface (its `surface.
152
+ // templates` id) and an `mcpPrompts` native surface, so all three bullets
153
+ // render — exercising both optional branches of `renderNonToolSurface`.
154
+ expect(tools).toContain("- **Resources**: `gizmo:{+uri}`");
155
+ expect(tools).toContain("- **Prompts**:");
156
+ expect(tools).toContain("- **Instructions**:");
157
+ });
158
+ });
159
+
160
+ describe("errors.md", () => {
161
+ it("renders the exit-code table and the full error catalog", () => {
162
+ expect(errors).toContain("| `0` | success |");
163
+ expect(errors).toContain("| `3` | store unavailable |");
164
+ expect(errors).toContain("| `ENTITY_NOT_FOUND` |");
165
+ expect(errors).toContain("| `UNSUPPORTED` |");
166
+ });
167
+
168
+ it("lists every code in the closed ERROR_CODES tuple (exhaustive)", () => {
169
+ // Non-circular exhaustiveness: iterate the source-of-truth tuple and
170
+ // assert each code's `catalog` row is present, so a code added to the
171
+ // kernel without a catalog entry fails here (not just the 2 spot-checks).
172
+ for (const code of ERROR_CODES) {
173
+ expect(errors, `errors.md is missing \`${code}\``).toContain(
174
+ `\`${code}\``,
175
+ );
176
+ }
177
+ });
178
+
179
+ it("embeds the response envelope as a JSON block", () => {
180
+ expect(errors).toContain("```json");
181
+ expect(errors).toContain('"ok": true');
182
+ expect(errors).toContain('"code": "<ErrorCode>"');
183
+ });
184
+ });
185
+ });
186
+
187
+ describe("emitReference — MCP annotation branches", () => {
188
+ it("renders a destructive fixture tool and a native-prompt-free surface", () => {
189
+ // `fixtureModule.make` is exposed, mutating, and destructive — the same
190
+ // `Marked destructive.` branch, driven from the emitSurface fixture.
191
+ const tools = emitReference([fixtureModule]).get("tools.md") ?? "";
192
+ expect(tools).toContain("### widget_make");
193
+ expect(tools).toContain("Marked destructive.");
194
+ expect(tools).not.toContain("- **Prompts**:");
195
+ });
196
+ });