@canonical/pragma-cli 0.29.0 → 0.31.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 (410) hide show
  1. package/README.md +128 -47
  2. package/dist/pragma +0 -0
  3. package/package.json +15 -13
  4. package/src/completions/constants.ts +7 -0
  5. package/src/completions/handleQuery.test.ts +32 -0
  6. package/src/completions/handleQuery.ts +20 -1
  7. package/src/completions/queryCompletions.test.ts +5 -0
  8. package/src/completions/queryCompletions.ts +17 -3
  9. package/src/completions/querySocket.test.ts +31 -0
  10. package/src/completions/querySocket.ts +36 -9
  11. package/src/config/defaultConfig.test.ts +33 -0
  12. package/src/config/defaultConfig.ts +59 -0
  13. package/src/config/defaults.json +17 -0
  14. package/src/config/findProjectConfigPath.test.ts +53 -0
  15. package/src/config/findProjectConfigPath.ts +36 -0
  16. package/src/config/index.ts +17 -2
  17. package/src/config/mergeConfigFileUpdate.ts +58 -0
  18. package/src/config/parseConfigValues.ts +217 -0
  19. package/src/config/readConfig.test.ts +104 -13
  20. package/src/config/readConfig.ts +12 -153
  21. package/src/config/readConfigLayers.test.ts +109 -0
  22. package/src/config/readConfigLayers.ts +118 -0
  23. package/src/config/resolveGlobalConfigPath.ts +13 -0
  24. package/src/config/resolveWriteConfigPath.test.ts +53 -0
  25. package/src/config/resolveWriteConfigPath.ts +31 -0
  26. package/src/config/types.ts +83 -1
  27. package/src/config/writeConfig.ts +25 -55
  28. package/src/constants.ts +3 -1
  29. package/src/domains/block/commands/list.ts +5 -90
  30. package/src/domains/block/commands/lookup.ts +8 -167
  31. package/src/domains/block/commands/sample.ts +2 -1
  32. package/src/domains/block/formatters/list.test.ts +3 -3
  33. package/src/domains/block/formatters/lookup.test.ts +5 -5
  34. package/src/domains/block/mcp/specs.ts +16 -196
  35. package/src/domains/block/orchestration/enrichBlocks.ts +6 -3
  36. package/src/domains/block/orchestration/resolveBlockLookup.ts +2 -1
  37. package/src/domains/block/stories.test.ts +28 -0
  38. package/src/domains/block/stories.ts +260 -0
  39. package/src/domains/config/commands/channel.test.ts +30 -3
  40. package/src/domains/config/commands/channel.ts +25 -8
  41. package/src/domains/config/commands/configScope.ts +46 -0
  42. package/src/domains/config/commands/framework.test.ts +32 -1
  43. package/src/domains/config/commands/framework.ts +26 -8
  44. package/src/domains/config/commands/show.ts +5 -45
  45. package/src/domains/config/commands/tier.test.ts +20 -2
  46. package/src/domains/config/commands/tier.ts +25 -8
  47. package/src/domains/config/commands/trace.test.ts +19 -2
  48. package/src/domains/config/commands/trace.ts +6 -3
  49. package/src/domains/config/formatters/channel.test.ts +20 -6
  50. package/src/domains/config/formatters/channel.ts +14 -11
  51. package/src/domains/config/formatters/framework.ts +14 -11
  52. package/src/domains/config/formatters/show.test.ts +27 -0
  53. package/src/domains/config/formatters/show.ts +27 -4
  54. package/src/domains/config/formatters/tier.test.ts +26 -10
  55. package/src/domains/config/formatters/tier.ts +19 -11
  56. package/src/domains/config/formatters/trace.ts +7 -7
  57. package/src/domains/config/mcp/specs.ts +33 -53
  58. package/src/domains/config/operations/show.test.ts +18 -0
  59. package/src/domains/config/operations/show.ts +7 -1
  60. package/src/domains/config/operations/types.ts +7 -0
  61. package/src/domains/config/operations/validateTier.test.ts +9 -0
  62. package/src/domains/config/operations/validateTier.ts +10 -2
  63. package/src/domains/config/stories.ts +42 -0
  64. package/src/domains/config/tasks/index.ts +1 -0
  65. package/src/domains/config/tasks/setChannel.ts +13 -28
  66. package/src/domains/config/tasks/setFramework.ts +11 -30
  67. package/src/domains/config/tasks/setTier.ts +10 -29
  68. package/src/domains/config/tasks/setTrace.ts +10 -28
  69. package/src/domains/config/tasks/writeConfigField.ts +41 -0
  70. package/src/domains/create/generatorPack/bundled.ts +49 -0
  71. package/src/domains/create/generatorPack/compileGeneratorPack.test.ts +159 -0
  72. package/src/domains/create/generatorPack/compileGeneratorPack.ts +312 -0
  73. package/src/domains/create/index.ts +13 -7
  74. package/src/domains/create/mcp/specs.ts +6 -161
  75. package/src/domains/create/renderGeneratorUi.test.ts +103 -0
  76. package/src/domains/create/renderGeneratorUi.ts +65 -0
  77. package/src/domains/doctor/formatters/doctor.test.ts +50 -2
  78. package/src/domains/doctor/formatters/doctor.ts +90 -38
  79. package/src/domains/doctor/operations/checks/checkConfigFile.ts +19 -5
  80. package/src/domains/doctor/operations/checks/checkMcpCommands.ts +133 -0
  81. package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +1 -1
  82. package/src/domains/doctor/operations/checks/checkPackageRefs.ts +32 -26
  83. package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +1 -1
  84. package/src/domains/doctor/operations/checks/index.ts +1 -0
  85. package/src/domains/doctor/operations/checks.test.ts +160 -7
  86. package/src/domains/doctor/operations/runChecks.test.ts +15 -6
  87. package/src/domains/doctor/operations/runChecks.ts +2 -0
  88. package/src/domains/doctor/operations/types.ts +23 -1
  89. package/src/domains/graph/commands/inspect.test.ts +2 -2
  90. package/src/domains/graph/commands/query.test.ts +5 -3
  91. package/src/domains/graph/formatters/inspect.ts +7 -7
  92. package/src/domains/graph/formatters/query.test.ts +87 -0
  93. package/src/domains/graph/formatters/query.ts +42 -5
  94. package/src/domains/graph/helpers/resolveUri.test.ts +50 -0
  95. package/src/domains/graph/helpers/resolveUri.ts +28 -21
  96. package/src/domains/graph/operations/inspectUri.test.ts +5 -5
  97. package/src/domains/graphql/commands/build.test.ts +5 -3
  98. package/src/domains/graphql/commands/build.ts +8 -16
  99. package/src/domains/graphql/commands/check.test.ts +5 -3
  100. package/src/domains/graphql/commands/check.ts +7 -13
  101. package/src/domains/graphql/commands/index.ts +1 -0
  102. package/src/domains/graphql/commands/serve.test.ts +46 -0
  103. package/src/domains/graphql/commands/serve.ts +141 -0
  104. package/src/domains/graphql/constants.ts +10 -0
  105. package/src/domains/graphql/helpers/gatherSources.test.ts +92 -0
  106. package/src/domains/graphql/helpers/gatherSources.ts +58 -0
  107. package/src/domains/graphql/helpers/index.ts +2 -0
  108. package/src/domains/graphql/helpers/parsePrefixes.test.ts +3 -3
  109. package/src/domains/graphql/helpers/parsePrefixes.ts +3 -3
  110. package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +9 -0
  111. package/src/domains/graphql/helpers/resolveSourceFiles.ts +24 -3
  112. package/src/domains/graphql/helpers/routeGraphql.test.ts +43 -0
  113. package/src/domains/graphql/helpers/routeGraphql.ts +28 -0
  114. package/src/domains/graphql/index.ts +9 -6
  115. package/src/domains/graphql/operations/compileSchema.test.ts +23 -47
  116. package/src/domains/graphql/operations/compileSchema.ts +23 -25
  117. package/src/domains/graphql/operations/createSchemaServer.test.ts +50 -0
  118. package/src/domains/graphql/operations/createSchemaServer.ts +75 -0
  119. package/src/domains/graphql/operations/ensureSchemaArtifact.test.ts +167 -0
  120. package/src/domains/graphql/operations/ensureSchemaArtifact.ts +178 -0
  121. package/src/domains/graphql/operations/index.ts +10 -0
  122. package/src/domains/info/formatters/upgrade.test.ts +7 -4
  123. package/src/domains/info/formatters/upgrade.ts +3 -1
  124. package/src/domains/info/operations/collectEntityCounts.test.ts +156 -0
  125. package/src/domains/info/operations/collectEntityCounts.ts +123 -0
  126. package/src/domains/info/operations/collectInfo.test.ts +14 -3
  127. package/src/domains/info/operations/collectInfo.ts +12 -15
  128. package/src/domains/info/operations/index.ts +1 -0
  129. package/src/domains/info/types.ts +13 -0
  130. package/src/domains/llm/capabilities.test.ts +24 -4
  131. package/src/domains/llm/commands/capabilities.ts +12 -3
  132. package/src/domains/llm/commands/llm.ts +5 -1
  133. package/src/domains/llm/data/commandReference.ts +20 -11
  134. package/src/domains/llm/data/decisionTrees.ts +10 -5
  135. package/src/domains/llm/data/toolCatalog.ts +55 -18
  136. package/src/domains/llm/formatters/orientation.ts +5 -1
  137. package/src/domains/llm/llmCommand.test.ts +11 -3
  138. package/src/domains/llm/mcp/specs.ts +3 -4
  139. package/src/domains/llm/operations/collectContext.test.ts +64 -0
  140. package/src/domains/llm/operations/collectContext.ts +7 -17
  141. package/src/domains/modifier/commands/list.ts +5 -38
  142. package/src/domains/modifier/commands/lookup.ts +8 -79
  143. package/src/domains/modifier/commands/sample.ts +2 -1
  144. package/src/domains/modifier/mcp/specs.ts +15 -94
  145. package/src/domains/modifier/operations/lookup.ts +5 -3
  146. package/src/domains/modifier/orchestration/resolveModifierLookup.ts +2 -1
  147. package/src/domains/modifier/stories.test.ts +20 -0
  148. package/src/domains/modifier/stories.ts +86 -0
  149. package/src/domains/ontology/commands/list.test.ts +5 -3
  150. package/src/domains/ontology/commands/list.ts +5 -58
  151. package/src/domains/ontology/commands/show.test.ts +85 -9
  152. package/src/domains/ontology/commands/show.ts +6 -58
  153. package/src/domains/ontology/formatters/index.ts +1 -0
  154. package/src/domains/ontology/formatters/list.ts +37 -12
  155. package/src/domains/ontology/formatters/show.ts +361 -64
  156. package/src/domains/ontology/helpers/buildClassTree.ts +89 -0
  157. package/src/domains/ontology/helpers/completeClassNames.ts +43 -0
  158. package/src/domains/ontology/helpers/expandOntologyIris.ts +79 -0
  159. package/src/domains/ontology/helpers/index.ts +14 -0
  160. package/src/domains/ontology/helpers/queryClasses.ts +32 -16
  161. package/src/domains/ontology/helpers/queryProperties.ts +39 -6
  162. package/src/domains/ontology/helpers/queryTboxFacts.ts +160 -0
  163. package/src/domains/ontology/mcp/specs.ts +7 -84
  164. package/src/domains/ontology/operations/listOntologies.test.ts +80 -3
  165. package/src/domains/ontology/operations/listOntologies.ts +126 -30
  166. package/src/domains/ontology/operations/showOntology.test.ts +131 -12
  167. package/src/domains/ontology/operations/showOntology.ts +289 -7
  168. package/src/domains/ontology/operations/showOntologyRaw.test.ts +4 -2
  169. package/src/domains/ontology/stories.test.ts +36 -0
  170. package/src/domains/ontology/stories.ts +153 -0
  171. package/src/domains/refs/operations/updateRefs.ts +2 -38
  172. package/src/domains/setup/commands/index.ts +1 -0
  173. package/src/domains/setup/commands/setup.ts +70 -0
  174. package/src/domains/setup/commands/skills.test.ts +6 -2
  175. package/src/domains/setup/commands/skills.ts +6 -2
  176. package/src/domains/setup/helpers/runSetupTask.test.ts +148 -150
  177. package/src/domains/setup/helpers/runSetupTask.ts +62 -70
  178. package/src/domains/setup/index.ts +7 -3
  179. package/src/domains/setup/operations/setupLsp.test.ts +3 -2
  180. package/src/domains/setup/operations/setupLsp.ts +7 -2
  181. package/src/domains/setup/operations/setupMcp.test.ts +6 -1
  182. package/src/domains/shared/bootStore.bareCore.test.ts +63 -0
  183. package/src/domains/shared/bootStore.test.ts +82 -0
  184. package/src/domains/shared/bootStore.ts +57 -18
  185. package/src/domains/shared/compactUri.test.ts +11 -0
  186. package/src/domains/shared/compactUri.ts +10 -5
  187. package/src/domains/shared/context.ts +2 -2
  188. package/src/domains/shared/contracts.ts +11 -0
  189. package/src/domains/shared/createInteractivePromptSession.test.ts +439 -0
  190. package/src/domains/shared/createInteractivePromptSession.ts +236 -0
  191. package/src/domains/shared/emptyErrorRecovery.test.ts +23 -26
  192. package/src/domains/shared/extractLocalName.test.ts +3 -3
  193. package/src/domains/shared/formatters.ts +23 -2
  194. package/src/domains/shared/listTiers.ts +40 -0
  195. package/src/domains/shared/loaders/bundledLoader.test.ts +248 -0
  196. package/src/domains/shared/loaders/bundledLoader.ts +158 -12
  197. package/src/domains/shared/loaders/gitLoader.ts +1 -2
  198. package/src/domains/shared/loaders/index.ts +4 -1
  199. package/src/domains/shared/loaders/localLoader.ts +2 -4
  200. package/src/domains/shared/loaders/readPackageDir.test.ts +58 -0
  201. package/src/domains/shared/loaders/readPackageDir.ts +82 -9
  202. package/src/domains/shared/loaders/storyAssetsPlugin.test.ts +84 -0
  203. package/src/domains/shared/loaders/storyAssetsPlugin.ts +46 -0
  204. package/src/domains/shared/lookupMany.test.ts +135 -0
  205. package/src/domains/shared/lookupMany.ts +50 -2
  206. package/src/domains/shared/mergeAndParseRefs.test.ts +89 -0
  207. package/src/domains/shared/mergeAndParseRefs.ts +44 -0
  208. package/src/domains/shared/namespaces.ts +13 -5
  209. package/src/domains/shared/packages.ts +10 -17
  210. package/src/domains/shared/parseSampleCount.test.ts +47 -0
  211. package/src/domains/shared/parseSampleCount.ts +45 -0
  212. package/src/domains/shared/prefixes.test.ts +211 -0
  213. package/src/domains/shared/prefixes.ts +182 -15
  214. package/src/domains/shared/renderers.ts +5 -5
  215. package/src/domains/shared/resolveConfiguredGraphs.test.ts +27 -0
  216. package/src/domains/shared/resolveConfiguredGraphs.ts +41 -0
  217. package/src/domains/shared/resolveLookupExitCode.test.ts +48 -0
  218. package/src/domains/shared/resolveLookupExitCode.ts +42 -0
  219. package/src/domains/shared/runtime.ts +4 -63
  220. package/src/domains/shared/semanticPackage.test.ts +89 -0
  221. package/src/domains/shared/semanticPackage.ts +34 -3
  222. package/src/domains/shared/stories/compileLookupCommand.test.ts +145 -0
  223. package/src/domains/shared/stories/compileLookupCommand.ts +102 -0
  224. package/src/domains/shared/stories/compileLookupTool.test.ts +105 -0
  225. package/src/domains/shared/stories/compileLookupTool.ts +96 -0
  226. package/src/domains/shared/stories/compileReadCommand.test.ts +121 -0
  227. package/src/domains/shared/stories/compileReadCommand.ts +48 -0
  228. package/src/domains/shared/stories/compileReadTool.test.ts +64 -0
  229. package/src/domains/shared/stories/compileReadTool.ts +38 -0
  230. package/src/domains/shared/stories/condense.test.ts +18 -0
  231. package/src/domains/shared/stories/condense.ts +15 -0
  232. package/src/domains/shared/stories/index.ts +20 -0
  233. package/src/domains/shared/stories/normalizeNames.test.ts +20 -0
  234. package/src/domains/shared/stories/normalizeNames.ts +22 -0
  235. package/src/domains/shared/stories/pack/applyPackFilters.test.ts +151 -0
  236. package/src/domains/shared/stories/pack/applyPackFilters.ts +111 -0
  237. package/src/domains/shared/stories/pack/applyPackSearch.test.ts +57 -0
  238. package/src/domains/shared/stories/pack/applyPackSearch.ts +41 -0
  239. package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +81 -0
  240. package/src/domains/shared/stories/pack/buildLookupQuery.ts +154 -0
  241. package/src/domains/shared/stories/pack/bundled/index.ts +23 -0
  242. package/src/domains/shared/stories/pack/bundled/standardPack.ts +164 -0
  243. package/src/domains/shared/stories/pack/bundled/tierPack.ts +50 -0
  244. package/src/domains/shared/stories/pack/collectPackStories.test.ts +406 -0
  245. package/src/domains/shared/stories/pack/collectPackStories.ts +158 -0
  246. package/src/domains/shared/stories/pack/compilePackCommands.ts +50 -0
  247. package/src/domains/shared/stories/pack/compilePackStories.test.ts +751 -0
  248. package/src/domains/shared/stories/pack/compilePackStories.ts +724 -0
  249. package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +55 -0
  250. package/src/domains/shared/stories/pack/index.ts +42 -0
  251. package/src/domains/shared/stories/pack/reservedVerbs.test.ts +213 -0
  252. package/src/domains/shared/stories/pack/reservedVerbs.ts +170 -0
  253. package/src/domains/shared/stories/pack/runSelectQuery.ts +31 -0
  254. package/src/domains/shared/stories/pack/standardParity.test.ts +381 -0
  255. package/src/domains/shared/stories/pack/types.ts +224 -0
  256. package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +742 -0
  257. package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +859 -0
  258. package/src/domains/shared/stories/projectCliParameters.test.ts +59 -0
  259. package/src/domains/shared/stories/projectCliParameters.ts +57 -0
  260. package/src/domains/shared/stories/projectToolParams.test.ts +50 -0
  261. package/src/domains/shared/stories/projectToolParams.ts +32 -0
  262. package/src/domains/shared/stories/requirePragmaContext.test.ts +23 -0
  263. package/src/domains/shared/stories/requirePragmaContext.ts +23 -0
  264. package/src/domains/shared/stories/resolveLookupDetailed.test.ts +57 -0
  265. package/src/domains/shared/stories/resolveLookupDetailed.ts +27 -0
  266. package/src/domains/shared/stories/types.ts +179 -0
  267. package/src/domains/shared/suggestions/expandGlob.ts +1 -0
  268. package/src/domains/shared/suggestions/suggestNames.ts +43 -10
  269. package/src/domains/shared/types/index.ts +5 -9
  270. package/src/domains/shared/types/ontology.ts +119 -24
  271. package/src/domains/shared/types/standard.ts +9 -52
  272. package/src/domains/skill/commands/index.ts +3 -1
  273. package/src/domains/skill/commands/list.test.ts +6 -2
  274. package/src/domains/skill/commands/list.ts +5 -63
  275. package/src/domains/skill/commands/lookup.test.ts +118 -0
  276. package/src/domains/skill/commands/lookup.ts +14 -0
  277. package/src/domains/skill/formatters/index.ts +1 -0
  278. package/src/domains/skill/formatters/lookup.test.ts +46 -0
  279. package/src/domains/skill/formatters/lookup.ts +57 -0
  280. package/src/domains/skill/helpers/resolveSkillSources.ts +0 -1
  281. package/src/domains/skill/index.ts +7 -3
  282. package/src/domains/skill/mcp/specs.ts +10 -29
  283. package/src/domains/skill/operations/discover.test.ts +61 -30
  284. package/src/domains/skill/operations/discover.ts +28 -37
  285. package/src/domains/skill/operations/index.ts +2 -1
  286. package/src/domains/skill/operations/list.test.ts +15 -7
  287. package/src/domains/skill/operations/lookup.test.ts +91 -0
  288. package/src/domains/skill/operations/lookup.ts +70 -0
  289. package/src/domains/skill/stories.test.ts +43 -0
  290. package/src/domains/skill/stories.ts +103 -0
  291. package/src/domains/skill/types.ts +8 -0
  292. package/src/domains/token/commands/lookup.test.ts +8 -0
  293. package/src/domains/token/commands/lookup.ts +12 -0
  294. package/src/domains/token/commands/sample.ts +2 -1
  295. package/src/domains/token/featureFlag.ts +17 -0
  296. package/src/domains/token/index.ts +5 -0
  297. package/src/domains/token/mcp/specs.ts +18 -2
  298. package/src/domains/token/orchestration/resolveTokenLookup.ts +2 -1
  299. package/src/domains/trace/commands/resolveTraceLimit.test.ts +31 -0
  300. package/src/domains/trace/commands/show.ts +30 -4
  301. package/src/domains/trace/tracePlugin.test.ts +1 -1
  302. package/src/index.ts +1 -13
  303. package/src/mcp/registerResources.test.ts +382 -74
  304. package/src/mcp/registerResources.ts +5 -348
  305. package/src/mcp/resources/buildGraphIndex.ts +167 -0
  306. package/src/mcp/resources/buildResourceList.test.ts +97 -0
  307. package/src/mcp/resources/buildResourceList.ts +176 -0
  308. package/src/mcp/resources/classifyEntity.test.ts +40 -0
  309. package/src/mcp/resources/classifyEntity.ts +27 -0
  310. package/src/mcp/resources/constants.ts +105 -0
  311. package/src/mcp/resources/displayPredicates.ts +62 -0
  312. package/src/mcp/resources/pickFirstValue.test.ts +29 -0
  313. package/src/mcp/resources/pickFirstValue.ts +26 -0
  314. package/src/mcp/resources/pickPrimaryType.test.ts +41 -0
  315. package/src/mcp/resources/pickPrimaryType.ts +26 -0
  316. package/src/mcp/resources/rankUriCompletions.test.ts +52 -0
  317. package/src/mcp/resources/rankUriCompletions.ts +64 -0
  318. package/src/mcp/resources/readEntity.ts +169 -0
  319. package/src/mcp/resources/registerResources.ts +126 -0
  320. package/src/mcp/resources/types.ts +128 -0
  321. package/src/mcp/tools/index.ts +22 -5
  322. package/src/mcp/tools/registerTools.test.ts +167 -34
  323. package/src/mcp/types.ts +4 -0
  324. package/src/pipeline/collectCommands.test.ts +151 -1
  325. package/src/pipeline/collectCommands.ts +35 -13
  326. package/src/pipeline/createProgram.test.ts +5 -1
  327. package/src/pipeline/createProgram.ts +2 -2
  328. package/src/pipeline/firstRun.test.ts +80 -0
  329. package/src/pipeline/firstRun.ts +99 -0
  330. package/src/pipeline/parseGlobalFlags.test.ts +102 -1
  331. package/src/pipeline/parseGlobalFlags.ts +98 -9
  332. package/src/pipeline/resolveCommandKind.test.ts +12 -0
  333. package/src/pipeline/resolveCommandKind.ts +4 -0
  334. package/src/pipeline/rootHelp.test.ts +87 -0
  335. package/src/pipeline/rootHelp.ts +265 -0
  336. package/src/pipeline/runCli.orchestration.test.ts +28 -12
  337. package/src/pipeline/runCli.test.ts +17 -4
  338. package/src/pipeline/runCli.ts +202 -25
  339. package/src/testing/cli.ts +30 -2
  340. package/src/testing/createTestMcpClient.ts +4 -1
  341. package/src/testing/dsFixtures.ts +21 -4
  342. package/src/testing/index.ts +7 -0
  343. package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +1207 -0
  344. package/src/testing/integration/cli-user-stories.test.ts +63 -0
  345. package/src/testing/integration/cross-binary-byte-equality.test.ts +129 -0
  346. package/src/testing/integration/edge-cases.test.ts +62 -50
  347. package/src/testing/integration/executor-execution.test.ts +103 -0
  348. package/src/testing/integration/executor-golden.test.ts +145 -0
  349. package/src/testing/integration/mcp-surface.test.ts +40 -15
  350. package/src/testing/integration/parity.test.ts +136 -82
  351. package/src/testing/regression/0001-skill-discovery-granularity.test.ts +71 -0
  352. package/src/testing/setupXdgIsolation.ts +26 -0
  353. package/src/testing/standardParityFixtures.ts +35 -0
  354. package/src/testing/store.ts +4 -4
  355. package/src/testing/storyFixtures.ts +63 -0
  356. package/src/domains/create/commands/component.test.ts +0 -166
  357. package/src/domains/create/commands/component.ts +0 -123
  358. package/src/domains/create/commands/index.ts +0 -3
  359. package/src/domains/create/commands/package.test.ts +0 -35
  360. package/src/domains/create/commands/package.ts +0 -21
  361. package/src/domains/create/generators.ts +0 -8
  362. package/src/domains/standard/commands/categories.test.ts +0 -70
  363. package/src/domains/standard/commands/categories.ts +0 -48
  364. package/src/domains/standard/commands/index.ts +0 -6
  365. package/src/domains/standard/commands/list.test.ts +0 -105
  366. package/src/domains/standard/commands/list.ts +0 -90
  367. package/src/domains/standard/commands/lookup.test.ts +0 -135
  368. package/src/domains/standard/commands/lookup.ts +0 -99
  369. package/src/domains/standard/commands/sample.ts +0 -57
  370. package/src/domains/standard/formatters/categories.test.ts +0 -44
  371. package/src/domains/standard/formatters/categories.ts +0 -38
  372. package/src/domains/standard/formatters/index.ts +0 -10
  373. package/src/domains/standard/formatters/list.test.ts +0 -169
  374. package/src/domains/standard/formatters/list.ts +0 -184
  375. package/src/domains/standard/formatters/lookup.test.ts +0 -95
  376. package/src/domains/standard/formatters/lookup.ts +0 -101
  377. package/src/domains/standard/formatters/sample.ts +0 -15
  378. package/src/domains/standard/formatters/types.ts +0 -31
  379. package/src/domains/standard/index.ts +0 -40
  380. package/src/domains/standard/mcp/index.ts +0 -2
  381. package/src/domains/standard/mcp/specs.ts +0 -244
  382. package/src/domains/standard/operations/categories.test.ts +0 -61
  383. package/src/domains/standard/operations/categories.ts +0 -38
  384. package/src/domains/standard/operations/index.ts +0 -6
  385. package/src/domains/standard/operations/list.test.ts +0 -75
  386. package/src/domains/standard/operations/list.ts +0 -64
  387. package/src/domains/standard/operations/lookup.test.ts +0 -58
  388. package/src/domains/standard/operations/lookup.ts +0 -151
  389. package/src/domains/standard/operations/sample.ts +0 -35
  390. package/src/domains/standard/orchestration/buildStandardFilters.ts +0 -11
  391. package/src/domains/standard/orchestration/index.ts +0 -4
  392. package/src/domains/standard/orchestration/resolveStandardList.ts +0 -45
  393. package/src/domains/standard/orchestration/resolveStandardLookup.ts +0 -32
  394. package/src/domains/standard/orchestration/standardEmptyError.test.ts +0 -33
  395. package/src/domains/standard/orchestration/standardEmptyError.ts +0 -29
  396. package/src/domains/standard/standardConfig.ts +0 -42
  397. package/src/domains/standard/types.ts +0 -15
  398. package/src/domains/tier/commands/index.ts +0 -3
  399. package/src/domains/tier/commands/list.test.ts +0 -67
  400. package/src/domains/tier/commands/list.ts +0 -59
  401. package/src/domains/tier/formatters/index.ts +0 -3
  402. package/src/domains/tier/formatters/list.test.ts +0 -33
  403. package/src/domains/tier/formatters/list.ts +0 -45
  404. package/src/domains/tier/index.ts +0 -17
  405. package/src/domains/tier/mcp/index.ts +0 -2
  406. package/src/domains/tier/mcp/specs.ts +0 -38
  407. package/src/domains/tier/operations/index.ts +0 -3
  408. package/src/domains/tier/operations/list.test.ts +0 -32
  409. package/src/domains/tier/operations/list.ts +0 -33
  410. package/src/pipeline/runInteractiveCommand.ts +0 -198
@@ -4,17 +4,51 @@ import { P } from "../../shared/prefixes.js";
4
4
  import type { OntologySummary } from "../../shared/types/index.js";
5
5
  import findNamespace from "../helpers/findNamespace.js";
6
6
 
7
+ const SH = "http://www.w3.org/ns/shacl#";
8
+
7
9
  /** Check whether a URI belongs to the anatomy namespace. */
8
10
  function isAnatomyTerm(uri: string): boolean {
9
11
  return uri.toLowerCase().includes("anatomy");
10
12
  }
11
13
 
14
+ /** Per-namespace URI accumulator. */
15
+ function add(
16
+ map: Map<string, Set<string>>,
17
+ namespace: string,
18
+ uri: string,
19
+ ): void {
20
+ const set = map.get(namespace) ?? new Set();
21
+ set.add(uri);
22
+ map.set(namespace, set);
23
+ }
24
+
25
+ /**
26
+ * Derive a namespace from a URI when no registered prefix matches: cut
27
+ * after the last `#`, else after the last `/`. Keeps ontologies loaded
28
+ * without a declared prefix (e.g. a package that has not yet published
29
+ * its `pragma.prefixes`) visible in the listing instead of silently
30
+ * dropping their whole TBox.
31
+ */
32
+ function deriveNamespace(uri: string): string | undefined {
33
+ const hash = uri.lastIndexOf("#");
34
+ if (hash > 0) return uri.slice(0, hash + 1);
35
+ // Scheme-agnostic: any slash after the `scheme://` authority separator
36
+ // marks a path segment; a URI with no path (http://host) has none.
37
+ const authority = uri.indexOf("://");
38
+ if (authority < 0) return undefined;
39
+ const slash = uri.lastIndexOf("/");
40
+ return slash > authority + 2 ? uri.slice(0, slash + 1) : undefined;
41
+ }
42
+
12
43
  /**
13
- * List all loaded ontology namespaces with their class, property, and anatomy counts.
44
+ * List all loaded ontology namespaces with their header metadata (title,
45
+ * version) and counts: classes, relations (object properties), attributes
46
+ * (datatype properties), SHACL shapes, and anatomy terms.
14
47
  *
15
48
  * Discovers namespaces by querying for `owl:Class` and
16
49
  * `owl:ObjectProperty`/`owl:DatatypeProperty` definitions, then maps
17
- * namespace URIs back to prefixes via `store.prefixes`.
50
+ * namespace URIs back to prefixes via `store.prefixes`. Four whole-store
51
+ * queries regardless of how many namespaces are loaded.
18
52
  *
19
53
  * @param store - The ke store to query.
20
54
  * @returns An array of {@link OntologySummary} sorted alphabetically by prefix.
@@ -41,25 +75,47 @@ export default async function listOntologies(
41
75
  `),
42
76
  );
43
77
 
78
+ const shapeResult = await store.query(
79
+ buildQuery(`
80
+ SELECT ?shape ?target
81
+ WHERE {
82
+ ?shape a <${SH}NodeShape> .
83
+ OPTIONAL { ?shape <${SH}targetClass> ?target }
84
+ }
85
+ `),
86
+ );
87
+
88
+ const metaResult = await store.query(
89
+ buildQuery(`
90
+ SELECT ?ont ?title ?version
91
+ WHERE {
92
+ ?ont a ${P.owl}Ontology .
93
+ OPTIONAL { ?ont ${P.rdfs}label ?title }
94
+ OPTIONAL { ?ont ${P.owl}versionInfo ?version }
95
+ }
96
+ ORDER BY ?ont
97
+ `),
98
+ );
99
+
44
100
  const prefixEntries = Object.entries(store.prefixes);
101
+ // Everything below is keyed by namespace URI so ontologies without a
102
+ // registered prefix still surface in the listing.
103
+ const nsOf = (uri: string): string | undefined =>
104
+ findNamespace(uri, prefixEntries)?.namespace ?? deriveNamespace(uri);
45
105
  const classCounts = new Map<string, Set<string>>();
46
- const propCounts = new Map<string, Set<string>>();
106
+ const relationCounts = new Map<string, Set<string>>();
107
+ const attributeCounts = new Map<string, Set<string>>();
108
+ const shapeCounts = new Map<string, Set<string>>();
47
109
  const anatomyCounts = new Map<string, Set<string>>();
110
+ const meta = new Map<string, { title?: string; version?: string }>();
48
111
 
49
112
  if (classResult.type === "select") {
50
113
  for (const b of classResult.bindings) {
51
114
  const uri = b.class ?? "";
52
- const ns = findNamespace(uri, prefixEntries);
115
+ const ns = nsOf(uri);
53
116
  if (ns) {
54
- const set = classCounts.get(ns.prefix) ?? new Set();
55
- set.add(uri);
56
- classCounts.set(ns.prefix, set);
57
-
58
- if (isAnatomyTerm(uri)) {
59
- const anatomySet = anatomyCounts.get(ns.prefix) ?? new Set();
60
- anatomySet.add(uri);
61
- anatomyCounts.set(ns.prefix, anatomySet);
62
- }
117
+ add(classCounts, ns, uri);
118
+ if (isAnatomyTerm(uri)) add(anatomyCounts, ns, uri);
63
119
  }
64
120
  }
65
121
  }
@@ -67,35 +123,75 @@ export default async function listOntologies(
67
123
  if (propResult.type === "select") {
68
124
  for (const b of propResult.bindings) {
69
125
  const uri = b.prop ?? "";
70
- const ns = findNamespace(uri, prefixEntries);
126
+ const ns = nsOf(uri);
71
127
  if (ns) {
72
- const set = propCounts.get(ns.prefix) ?? new Set();
73
- set.add(uri);
74
- propCounts.set(ns.prefix, set);
75
-
76
- if (isAnatomyTerm(uri)) {
77
- const anatomySet = anatomyCounts.get(ns.prefix) ?? new Set();
78
- anatomySet.add(uri);
79
- anatomyCounts.set(ns.prefix, anatomySet);
80
- }
128
+ const kind = b.propType?.includes("ObjectProperty")
129
+ ? relationCounts
130
+ : attributeCounts;
131
+ add(kind, ns, uri);
132
+ if (isAnatomyTerm(uri)) add(anatomyCounts, ns, uri);
133
+ }
134
+ }
135
+ }
136
+
137
+ if (shapeResult.type === "select") {
138
+ for (const b of shapeResult.bindings) {
139
+ // Same attribution as `ontology show`: a shape counts for the
140
+ // namespace of the shape itself or of its target class.
141
+ const ns = b.shape ? nsOf(b.shape) : undefined;
142
+ const targetNs = b.target ? nsOf(b.target) : undefined;
143
+ const owner = ns ?? targetNs;
144
+ if (owner && b.shape) add(shapeCounts, owner, b.shape);
145
+ }
146
+ }
147
+
148
+ if (metaResult.type === "select") {
149
+ for (const b of metaResult.bindings) {
150
+ const ns = b.ont ? nsOf(b.ont) : undefined;
151
+ if (ns && !meta.has(ns)) {
152
+ meta.set(ns, {
153
+ ...(b.title ? { title: b.title } : {}),
154
+ ...(b.version ? { version: b.version } : {}),
155
+ });
81
156
  }
82
157
  }
83
158
  }
84
159
 
85
- const allPrefixes = new Set([
160
+ // A namespace that only contributes SHACL shapes still surfaces; one
161
+ // that only declares an owl:Ontology header (no terms at all) does not —
162
+ // an empty TBox is not a listable ontology.
163
+ const allNamespaces = new Set([
86
164
  ...classCounts.keys(),
87
- ...propCounts.keys(),
165
+ ...relationCounts.keys(),
166
+ ...attributeCounts.keys(),
88
167
  ...anatomyCounts.keys(),
168
+ ...shapeCounts.keys(),
89
169
  ]);
90
170
 
91
- return [...allPrefixes].sort().map((prefix) => {
92
- const namespace = prefixEntries.find(([p]) => p === prefix)?.[1] ?? "";
171
+ const summaries = [...allNamespaces].map((namespace) => {
172
+ const prefix = prefixEntries.find(([, ns]) => ns === namespace)?.[0] ?? "";
173
+ const header = meta.get(namespace);
93
174
  return {
94
175
  prefix,
95
176
  namespace,
96
- classCount: classCounts.get(prefix)?.size ?? 0,
97
- propertyCount: propCounts.get(prefix)?.size ?? 0,
98
- anatomyCount: anatomyCounts.get(prefix)?.size ?? 0,
177
+ ...(header?.title ? { title: header.title } : {}),
178
+ ...(header?.version ? { version: header.version } : {}),
179
+ classCount: classCounts.get(namespace)?.size ?? 0,
180
+ relationCount: relationCounts.get(namespace)?.size ?? 0,
181
+ attributeCount: attributeCounts.get(namespace)?.size ?? 0,
182
+ shapeCount: shapeCounts.get(namespace)?.size ?? 0,
183
+ anatomyCount: anatomyCounts.get(namespace)?.size ?? 0,
99
184
  };
100
185
  });
186
+
187
+ // Prefixed namespaces first (alphabetical), unprefixed after by URI.
188
+ return summaries.sort((a, b) =>
189
+ a.prefix && b.prefix
190
+ ? a.prefix.localeCompare(b.prefix)
191
+ : a.prefix
192
+ ? -1
193
+ : b.prefix
194
+ ? 1
195
+ : a.namespace.localeCompare(b.namespace),
196
+ );
101
197
  }
@@ -2,7 +2,7 @@ import type { Store } from "@canonical/ke";
2
2
  import { afterAll, beforeAll, describe, expect, it } from "vitest";
3
3
  import { PragmaError } from "#error";
4
4
  import { createTestStore, DS_ALL_TTL } from "#testing";
5
- import { PREFIX_MAP } from "../../shared/prefixes.js";
5
+ import { DEFAULT_PREFIX_MAP } from "../../shared/prefixes.js";
6
6
  import showOntology from "./showOntology.js";
7
7
 
8
8
  let store: Store;
@@ -17,31 +17,85 @@ beforeAll(async () => {
17
17
  afterAll(() => cleanup());
18
18
 
19
19
  describe("showOntology", () => {
20
- it("returns classes and properties for a prefix", async () => {
20
+ it("returns classes with attached properties for a prefix", async () => {
21
21
  const result = await showOntology(store, "ds");
22
22
  expect(result.prefix).toBe("ds");
23
- expect(result.namespace).toBe(PREFIX_MAP.ds);
23
+ expect(result.namespace).toBe(DEFAULT_PREFIX_MAP.ds);
24
24
  expect(result.classes.length).toBeGreaterThan(0);
25
- expect(result.properties.length).toBeGreaterThan(0);
25
+
26
+ const uiBlock = result.classes.find((c) => c.iri === "ds:UIBlock");
27
+ expect(uiBlock).toBeDefined();
28
+ expect(uiBlock?.properties.map((p) => p.label)).toContain("name");
26
29
  });
27
30
 
28
- it("includes class labels and superclass relationships", async () => {
31
+ it("preserves all subClassOf edges as compact IRIs", async () => {
29
32
  const result = await showOntology(store, "ds");
30
33
  const component = result.classes.find((c) => c.label === "Component");
31
34
  expect(component).toBeDefined();
32
- expect(component?.superclass).toContain("UIBlock");
35
+ expect(component?.subClassOf).toContain("ds:UIBlock");
36
+ });
37
+
38
+ it("orders classes topologically (parents before children)", async () => {
39
+ const result = await showOntology(store, "ds");
40
+ const order = result.classes.map((c) => c.iri);
41
+ expect(order.indexOf("ds:UIBlock")).toBeLessThan(
42
+ order.indexOf("ds:Component"),
43
+ );
44
+ });
45
+
46
+ it("includes rdfs:comment when declared", async () => {
47
+ const result = await showOntology(store, "ds");
48
+ const component = result.classes.find((c) => c.iri === "ds:Component");
49
+ expect(component?.comment).toBe("A reusable UI building block.");
50
+ });
51
+
52
+ it("counts instances per class", async () => {
53
+ const result = await showOntology(store, "ds");
54
+ const component = result.classes.find((c) => c.iri === "ds:Component");
55
+ expect(component?.instances).toBeGreaterThan(0);
56
+ });
57
+
58
+ it("marks functional properties", async () => {
59
+ const result = await showOntology(store, "ds");
60
+ const uiBlock = result.classes.find((c) => c.iri === "ds:UIBlock");
61
+ const tier = uiBlock?.properties.find((p) => p.iri === "ds:tier");
62
+ expect(tier?.functional).toBe(true);
33
63
  });
34
64
 
35
- it("includes property domain and range", async () => {
65
+ it("attaches property domain and range as compact IRIs", async () => {
36
66
  const result = await showOntology(store, "ds");
37
- const nameProp = result.properties.find((p) => p.uri.endsWith("name"));
67
+ const uiBlock = result.classes.find((c) => c.iri === "ds:UIBlock");
68
+ const nameProp = uiBlock?.properties.find((p) => p.iri === "ds:name");
38
69
  expect(nameProp).toBeDefined();
39
- expect(nameProp?.domain).toContain("UIBlock");
40
- expect(nameProp?.type).toBe("datatype");
70
+ expect(nameProp?.domain).toBe("ds:UIBlock");
71
+ expect(nameProp?.kind).toBe("datatype");
72
+ expect(nameProp?.range).toBe("xsd:string");
73
+ });
74
+
75
+ it("emits a prefixes map covering the compact IRIs used", async () => {
76
+ const result = await showOntology(store, "ds");
77
+ expect(result.prefixes.ds).toBe(DEFAULT_PREFIX_MAP.ds);
78
+ expect(result.prefixes.xsd).toBeDefined();
79
+ });
80
+
81
+ it("surfaces the owl:Ontology header", async () => {
82
+ const result = await showOntology(store, "ds");
83
+ expect(result.meta?.title).toBe("Design System Ontology");
84
+ expect(result.meta?.version).toBe("0.1.0-test");
85
+ });
86
+
87
+ it("summarizes SHACL node shapes", async () => {
88
+ const result = await showOntology(store, "ds");
89
+ const shape = result.constraints?.find(
90
+ (c) => c.shape === "ds:ComponentShape",
91
+ );
92
+ expect(shape).toBeDefined();
93
+ expect(shape?.targetClass).toBe("ds:Component");
94
+ expect(shape?.propertyCount).toBe(2);
41
95
  });
42
96
 
43
97
  it("resolves full namespace URI", async () => {
44
- const result = await showOntology(store, PREFIX_MAP.ds);
98
+ const result = await showOntology(store, DEFAULT_PREFIX_MAP.ds);
45
99
  expect(result.prefix).toBe("ds");
46
100
  expect(result.classes.length).toBeGreaterThan(0);
47
101
  });
@@ -59,7 +113,72 @@ describe("showOntology", () => {
59
113
  it("returns cs ontology with standard classes", async () => {
60
114
  const result = await showOntology(store, "cs");
61
115
  expect(result.prefix).toBe("cs");
62
- const standard = result.classes.find((c) => c.uri.includes("CodeStandard"));
116
+ const standard = result.classes.find((c) => c.iri.includes("CodeStandard"));
63
117
  expect(standard).toBeDefined();
64
118
  });
65
119
  });
120
+
121
+ describe("showOntology — class focus", () => {
122
+ it("deep-dives into a class by label", async () => {
123
+ const result = await showOntology(store, "ds", { class: "Component" });
124
+ const focus = result.focus;
125
+ expect(focus).toBeDefined();
126
+ expect(focus?.iri).toBe("ds:Component");
127
+ expect(focus?.superChain).toEqual(["ds:UIBlock"]);
128
+ expect(focus?.instances).toBeGreaterThan(0);
129
+ });
130
+
131
+ it("separates direct and inherited properties", async () => {
132
+ const result = await showOntology(store, "ds", { class: "Component" });
133
+ const inherited = result.focus?.inheritedProperties.map((p) => p.iri);
134
+ expect(inherited).toContain("ds:name");
135
+ });
136
+
137
+ it("finds reverse references (properties ranging over the class)", async () => {
138
+ const result = await showOntology(store, "ds", { class: "UIBlock" });
139
+ const refs = result.focus?.referencedBy.map((p) => p.iri);
140
+ expect(refs).toContain("ds:implementsBlock");
141
+ });
142
+
143
+ it("returns sample instance IRIs", async () => {
144
+ const result = await showOntology(store, "ds", { class: "Component" });
145
+ expect(result.focus?.sampleInstances.length).toBeGreaterThan(0);
146
+ });
147
+
148
+ it("emits runnable follow-up queries with compact IRIs", async () => {
149
+ const result = await showOntology(store, "ds", { class: "Component" });
150
+ const queries = result.focus?.queries ?? [];
151
+ expect(queries.length).toBeGreaterThan(0);
152
+ expect(queries[0]?.sparql).toBe(
153
+ "SELECT ?instance WHERE { ?instance a ds:Component } LIMIT 20",
154
+ );
155
+ // A sample-instance inspection query is included when instances exist.
156
+ expect(queries.some((q) => q.sparql.includes("?predicate ?object"))).toBe(
157
+ true,
158
+ );
159
+ });
160
+
161
+ it("accepts a compact IRI and a local name", async () => {
162
+ const byIri = await showOntology(store, "ds", { class: "ds:Component" });
163
+ expect(byIri.focus?.iri).toBe("ds:Component");
164
+
165
+ const byLocal = await showOntology(store, "ds", { class: "component" });
166
+ expect(byLocal.focus?.iri).toBe("ds:Component");
167
+ });
168
+
169
+ it("throws not-found with suggestions for an unknown class", async () => {
170
+ try {
171
+ await showOntology(store, "ds", { class: "Comp" });
172
+ expect.unreachable("should have thrown");
173
+ } catch (e) {
174
+ expect((e as PragmaError).code).toBe("ENTITY_NOT_FOUND");
175
+ expect((e as PragmaError).suggestions).toContain("Component");
176
+ }
177
+ });
178
+
179
+ it("still returns the full namespace structure alongside the focus", async () => {
180
+ const result = await showOntology(store, "ds", { class: "Component" });
181
+ expect(result.classes.length).toBeGreaterThan(0);
182
+ expect(result.focus).toBeDefined();
183
+ });
184
+ });