@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
@@ -1,166 +0,0 @@
1
- import type { CommandContext, CommandDefinition } from "@canonical/cli-core";
2
- import { describe, expect, it } from "vitest";
3
- import { PragmaError } from "#error";
4
- import buildComponentCommand from "./component.js";
5
-
6
- const ctx: CommandContext = {
7
- cwd: "/tmp",
8
- globalFlags: { llm: false, format: "text" as const, verbose: false },
9
- };
10
-
11
- const llmCtx: CommandContext = {
12
- cwd: "/tmp",
13
- globalFlags: { llm: true, format: "text" as const, verbose: false },
14
- };
15
-
16
- const jsonCtx: CommandContext = {
17
- cwd: "/tmp",
18
- globalFlags: { llm: false, format: "json" as const, verbose: false },
19
- };
20
-
21
- async function executeOutput(
22
- cmd: CommandDefinition,
23
- params: Record<string, unknown>,
24
- context: CommandContext,
25
- ): Promise<{ value: unknown; text: string }> {
26
- const result = await cmd.execute(params, context);
27
- expect(result.tag).toBe("output");
28
- if (result.tag !== "output") throw new Error("Expected output result");
29
- const text = result.render.plain(result.value);
30
- return { value: result.value, text };
31
- }
32
-
33
- describe("buildComponentCommand", () => {
34
- it("has correct path", () => {
35
- const cmd = buildComponentCommand();
36
- expect(cmd.path).toEqual(["create", "component"]);
37
- });
38
-
39
- it("includes framework as positional required select parameter", () => {
40
- const cmd = buildComponentCommand();
41
- const framework = cmd.parameters.find((p) => p.name === "framework");
42
- expect(framework).toBeDefined();
43
- expect(framework?.positional).toBe(true);
44
- expect(framework?.required).toBe(true);
45
- expect(framework?.type).toBe("select");
46
- expect(framework?.choices?.map((c) => c.value)).toEqual([
47
- "react",
48
- "svelte",
49
- "lit",
50
- ]);
51
- });
52
-
53
- it("includes prompt-derived parameters", () => {
54
- const cmd = buildComponentCommand();
55
- const names = cmd.parameters.map((p) => p.name);
56
- expect(names).toContain("componentPath");
57
- expect(names).toContain("withStyles");
58
- expect(names).toContain("withStories");
59
- expect(names).toContain("withSsrTests");
60
- });
61
-
62
- it("includes execution-mode parameters", () => {
63
- const cmd = buildComponentCommand();
64
- const names = cmd.parameters.map((p) => p.name);
65
- expect(names).toContain("dryRun");
66
- expect(names).toContain("yes");
67
- expect(names).toContain("showFiles");
68
- expect(names).toContain("preview");
69
- expect(names).toContain("generatedStamp");
70
- });
71
-
72
- it("dry-run with react returns output with file paths", async () => {
73
- const cmd = buildComponentCommand();
74
- const { text } = await executeOutput(
75
- cmd,
76
- {
77
- framework: "react",
78
- componentPath: "src/components/Button",
79
- dryRun: true,
80
- yes: true,
81
- },
82
- ctx,
83
- );
84
- expect(text).toContain("Button");
85
- expect(text).toContain("src/components/Button");
86
- });
87
-
88
- it("dry-run with svelte returns output with svelte files", async () => {
89
- const cmd = buildComponentCommand();
90
- const { text } = await executeOutput(
91
- cmd,
92
- {
93
- framework: "svelte",
94
- componentPath: "src/lib/components/Toggle",
95
- dryRun: true,
96
- yes: true,
97
- },
98
- ctx,
99
- );
100
- expect(text).toContain("Toggle");
101
- expect(text).toContain("src/lib/components/Toggle");
102
- });
103
-
104
- it("LLM mode returns markdown", async () => {
105
- const cmd = buildComponentCommand();
106
- const { text } = await executeOutput(
107
- cmd,
108
- {
109
- framework: "react",
110
- componentPath: "src/components/Card",
111
- },
112
- llmCtx,
113
- );
114
- // LLM markdown output includes generator name header
115
- expect(text).toContain("component/react");
116
- });
117
-
118
- it("JSON mode returns parseable JSON", async () => {
119
- const cmd = buildComponentCommand();
120
- const { text } = await executeOutput(
121
- cmd,
122
- {
123
- framework: "react",
124
- componentPath: "src/components/Card",
125
- },
126
- jsonCtx,
127
- );
128
- const data = JSON.parse(text);
129
- expect(data.generator.name).toBe("component/react");
130
- expect(Array.isArray(data.plan)).toBe(true);
131
- });
132
-
133
- it("throws PragmaError for invalid framework", async () => {
134
- const cmd = buildComponentCommand();
135
- await expect(cmd.execute({ framework: "angular" }, ctx)).rejects.toThrow(
136
- PragmaError,
137
- );
138
- });
139
-
140
- it("throws PragmaError when framework is missing", async () => {
141
- const cmd = buildComponentCommand();
142
- await expect(cmd.execute({}, ctx)).rejects.toThrow(PragmaError);
143
- });
144
-
145
- it("returns interactive result when required answers are missing", async () => {
146
- const cmd = buildComponentCommand();
147
- // framework provided but componentPath has a default, so it should NOT
148
- // trigger interactive mode — all prompts have defaults
149
- const result = await cmd.execute({ framework: "lit", dryRun: true }, ctx);
150
- // componentPath has a default, so executeGenerator applies it and proceeds
151
- expect(result.tag).toBe("output");
152
- });
153
-
154
- it("has parameter groups", () => {
155
- const cmd = buildComponentCommand();
156
- expect(cmd.parameterGroups).toEqual({
157
- Component: ["componentPath"],
158
- Options: ["withStyles", "withStories", "withSsrTests"],
159
- });
160
- });
161
-
162
- it("has examples in meta", () => {
163
- const cmd = buildComponentCommand();
164
- expect(cmd.meta?.examples?.length).toBeGreaterThan(0);
165
- });
166
- });
@@ -1,123 +0,0 @@
1
- import {
2
- type CommandDefinition,
3
- executeGenerator,
4
- type ParameterDefinition,
5
- promptToParameter,
6
- } from "@canonical/cli-core";
7
- import { generators } from "@canonical/summon-component";
8
- import { PragmaError } from "#error";
9
- import { COMPONENT_GENERATORS } from "../generators.js";
10
-
11
- const FRAMEWORK_CHOICES = [
12
- { label: "react", value: "react" },
13
- { label: "svelte", value: "svelte" },
14
- { label: "lit", value: "lit" },
15
- ] as const;
16
-
17
- /** Reference generator used to derive shared prompt parameters. */
18
- const referenceGenerator = generators["component/react"];
19
-
20
- /**
21
- * Build the `pragma create component` command definition.
22
- *
23
- * Uses a dispatch pattern: `framework` is a required positional select
24
- * parameter. The execute function looks up the matching generator and
25
- * delegates to `executeGenerator` from cli-core.
26
- *
27
- * @returns The command definition for `pragma create component`.
28
- * @note Impure
29
- */
30
- export default function buildComponentCommand(): CommandDefinition {
31
- const frameworkParam: ParameterDefinition = {
32
- name: "framework",
33
- description: "Component framework (react, svelte, lit)",
34
- type: "select",
35
- choices: [...FRAMEWORK_CHOICES],
36
- positional: true,
37
- required: true,
38
- };
39
-
40
- // Derive prompt parameters from the reference generator
41
- const promptParams = referenceGenerator.prompts.map(promptToParameter);
42
-
43
- // Execution-mode parameters (same as generatorToCommand appends)
44
- const execParams: ParameterDefinition[] = [
45
- {
46
- name: "dryRun",
47
- description: "Preview without writing files",
48
- type: "boolean",
49
- },
50
- {
51
- name: "undo",
52
- description: "Reverse a previously generated component",
53
- type: "boolean",
54
- },
55
- {
56
- name: "yes",
57
- description: "Skip confirmation prompts",
58
- type: "boolean",
59
- },
60
- {
61
- name: "showFiles",
62
- description: "Show file contents in dry-run",
63
- type: "boolean",
64
- },
65
- {
66
- name: "preview",
67
- description: "Show file preview before writing",
68
- type: "boolean",
69
- default: true,
70
- },
71
- {
72
- name: "generatedStamp",
73
- description: "Add generated file stamps",
74
- type: "boolean",
75
- default: true,
76
- },
77
- ];
78
-
79
- const parameters = [frameworkParam, ...promptParams, ...execParams];
80
-
81
- return {
82
- path: ["create", "component"],
83
- description:
84
- "Generate a component with TypeScript, tests, stories, and styles",
85
- parameters,
86
- execute: async (params, ctx) => {
87
- const framework = params.framework as string | undefined;
88
- if (!framework) {
89
- throw PragmaError.invalidInput("framework", "(missing)", {
90
- validOptions: ["react", "svelte", "lit"],
91
- recovery: {
92
- message: "Provide a framework for component generation.",
93
- cli: "pragma create component react --component-path src/components/Button",
94
- },
95
- });
96
- }
97
-
98
- const gen = COMPONENT_GENERATORS[framework];
99
- if (!gen) {
100
- throw PragmaError.invalidInput("framework", framework, {
101
- validOptions: Object.keys(COMPONENT_GENERATORS),
102
- recovery: {
103
- message: `Valid frameworks: ${Object.keys(COMPONENT_GENERATORS).join(", ")}`,
104
- },
105
- });
106
- }
107
-
108
- return executeGenerator(gen, params, ctx);
109
- },
110
- meta: {
111
- examples: [
112
- "pragma create component react --component-path src/components/Button",
113
- "pragma create component svelte --component-path src/lib/components/Toggle",
114
- "pragma create component lit --component-path src/lib/Accordion",
115
- "pragma create component react --component-path src/components/Button --dry-run",
116
- ],
117
- },
118
- parameterGroups: {
119
- Component: ["componentPath"],
120
- Options: ["withStyles", "withStories", "withSsrTests"],
121
- },
122
- };
123
- }
@@ -1,3 +0,0 @@
1
- /** @module Create command definitions for `pragma create`. */
2
- export { default as componentCommand } from "./component.js";
3
- export { default as packageCommand } from "./package.js";
@@ -1,35 +0,0 @@
1
- import type { CommandContext } from "@canonical/cli-core";
2
- import { describe, expect, it } from "vitest";
3
- import buildPackageCommand from "./package.js";
4
-
5
- const ctx: CommandContext = {
6
- cwd: "/tmp",
7
- globalFlags: { llm: false, format: "text" as const, verbose: false },
8
- };
9
-
10
- describe("buildPackageCommand", () => {
11
- it("has correct path", () => {
12
- const cmd = buildPackageCommand();
13
- expect(cmd.path).toEqual(["create", "package"]);
14
- });
15
-
16
- it("dry-run with all params returns output", async () => {
17
- const cmd = buildPackageCommand();
18
- const result = await cmd.execute(
19
- {
20
- name: "@canonical/test-pkg",
21
- type: "tool-ts",
22
- dryRun: true,
23
- yes: true,
24
- },
25
- ctx,
26
- );
27
- expect(result.tag).toBe("output");
28
- });
29
-
30
- it("with missing required params returns batch output outside a TTY", async () => {
31
- const cmd = buildPackageCommand();
32
- const result = await cmd.execute({}, ctx);
33
- expect(result.tag).toBe("output");
34
- });
35
- });
@@ -1,21 +0,0 @@
1
- import {
2
- type CommandDefinition,
3
- generatorToCommand,
4
- } from "@canonical/cli-core";
5
- import { generators as packageGenerators } from "@canonical/summon-package";
6
-
7
- /**
8
- * Build the `pragma create package` command definition by bridging
9
- * the package generator via `generatorToCommand`.
10
- *
11
- * @returns The command definition for `pragma create package`.
12
- * @throws Error if the package generator is not found.
13
- * @note Impure
14
- */
15
- export default function buildPackageCommand(): CommandDefinition {
16
- const gen = packageGenerators.package;
17
- if (!gen) {
18
- throw new Error("Package generator not found in @canonical/summon-package");
19
- }
20
- return generatorToCommand(["create", "package"], gen);
21
- }
@@ -1,8 +0,0 @@
1
- import { generators } from "@canonical/summon-component";
2
- import type { AnyGenerator } from "@canonical/summon-core";
3
-
4
- export const COMPONENT_GENERATORS: Record<string, AnyGenerator> = {
5
- react: generators["component/react"],
6
- svelte: generators["component/svelte"],
7
- lit: generators["component/lit"],
8
- };
@@ -1,70 +0,0 @@
1
- import type { CommandDefinition } from "@canonical/cli-core";
2
- import type { Store } from "@canonical/ke";
3
- import { afterAll, beforeAll, describe, expect, it } from "vitest";
4
- import { createTestStore, DS_ALL_TTL } from "#testing";
5
- import type { PragmaContext } from "../../shared/context.js";
6
- import buildCategoriesCommand from "./categories.js";
7
-
8
- let store: Store;
9
- let cleanup: () => void;
10
-
11
- beforeAll(async () => {
12
- const result = await createTestStore({ ttl: DS_ALL_TTL });
13
- store = result.store;
14
- cleanup = result.cleanup;
15
- });
16
-
17
- afterAll(() => cleanup());
18
-
19
- function makeCtx(overrides: Partial<PragmaContext> = {}): PragmaContext {
20
- return {
21
- cwd: "/tmp",
22
- globalFlags: { llm: false, format: "text" as const, verbose: false },
23
- store,
24
- config: { tier: undefined, channel: "prerelease" },
25
- ...overrides,
26
- };
27
- }
28
-
29
- async function executeOutput(
30
- cmd: CommandDefinition,
31
- params: Record<string, unknown>,
32
- ctx: PragmaContext,
33
- ): Promise<{ value: unknown; text: string }> {
34
- const result = await cmd.execute(params, ctx);
35
- expect(result.tag).toBe("output");
36
- if (result.tag !== "output") throw new Error("Expected output result");
37
- const text = result.render.plain(result.value);
38
- return { value: result.value, text };
39
- }
40
-
41
- describe("buildCategoriesCommand", () => {
42
- it("returns categories with counts", async () => {
43
- const ctx = makeCtx();
44
- const cmd = buildCategoriesCommand(ctx);
45
- const { text } = await executeOutput(cmd, {}, ctx);
46
- expect(text).toContain("react (2 standards)");
47
- expect(text).toContain("code (1 standard)");
48
- });
49
-
50
- it("renders LLM format with --llm", async () => {
51
- const ctx = makeCtx({
52
- globalFlags: { llm: true, format: "text" as const, verbose: false },
53
- });
54
- const cmd = buildCategoriesCommand(ctx);
55
- const { text } = await executeOutput(cmd, {}, ctx);
56
- expect(text).toContain("## Standard Categories");
57
- expect(text).toContain("**react**");
58
- });
59
-
60
- it("renders JSON output", async () => {
61
- const ctx = makeCtx({
62
- globalFlags: { llm: false, format: "json" as const, verbose: false },
63
- });
64
- const cmd = buildCategoriesCommand(ctx);
65
- const { text } = await executeOutput(cmd, {}, ctx);
66
- const parsed = JSON.parse(text);
67
- expect(Array.isArray(parsed)).toBe(true);
68
- expect(parsed.some((c: { name: string }) => c.name === "react")).toBe(true);
69
- });
70
- });
@@ -1,48 +0,0 @@
1
- /**
2
- * Wires the `pragma standard categories` CLI command.
3
- *
4
- * Lists all standard categories with their standard counts. Throws a
5
- * structured recovery error when no categories are found.
6
- */
7
-
8
- import {
9
- type CommandDefinition,
10
- type CommandResult,
11
- createOutputResult,
12
- } from "@canonical/cli-core";
13
- import { PragmaError } from "#error";
14
- import type { PragmaContext } from "../../shared/context.js";
15
- import { selectFormatter } from "../../shared/formatters.js";
16
- import { categoriesFormatters } from "../formatters/index.js";
17
- import { listCategories } from "../operations/index.js";
18
-
19
- export default function buildCategoriesCommand(
20
- ctx: PragmaContext,
21
- ): CommandDefinition {
22
- return {
23
- path: ["standard", "categories"],
24
- description: "List all standard categories with counts",
25
- parameters: [],
26
- meta: {
27
- examples: ["pragma standard categories"],
28
- },
29
- execute: async (
30
- _params: Record<string, unknown>,
31
- ): Promise<CommandResult> => {
32
- const categories = await listCategories(ctx.store);
33
-
34
- if (categories.length === 0) {
35
- throw PragmaError.emptyResults("categories", {
36
- recovery: {
37
- message:
38
- "Ensure code standards packages are installed: bun add -D @canonical/code-standards",
39
- },
40
- });
41
- }
42
-
43
- return createOutputResult(categories, {
44
- plain: selectFormatter(ctx, categoriesFormatters),
45
- });
46
- },
47
- };
48
- }
@@ -1,6 +0,0 @@
1
- /** @module Re-exports standard command builders (`categories`, `list`, `lookup`, `sample`). */
2
-
3
- export { default as categoriesCommand } from "./categories.js";
4
- export { default as listCommand } from "./list.js";
5
- export { default as lookupCommand } from "./lookup.js";
6
- export { default as sampleCommand } from "./sample.js";
@@ -1,105 +0,0 @@
1
- import type { CommandDefinition } from "@canonical/cli-core";
2
- import type { Store } from "@canonical/ke";
3
- import { afterAll, beforeAll, describe, expect, it } from "vitest";
4
- import { PragmaError } from "#error";
5
- import { createTestStore, DS_ALL_TTL } from "#testing";
6
- import type { PragmaContext } from "../../shared/context.js";
7
- import buildListCommand from "./list.js";
8
-
9
- let store: Store;
10
- let cleanup: () => void;
11
-
12
- beforeAll(async () => {
13
- const result = await createTestStore({ ttl: DS_ALL_TTL });
14
- store = result.store;
15
- cleanup = result.cleanup;
16
- });
17
-
18
- afterAll(() => cleanup());
19
-
20
- function makeCtx(overrides: Partial<PragmaContext> = {}): PragmaContext {
21
- return {
22
- cwd: "/tmp",
23
- globalFlags: { llm: false, format: "text" as const, verbose: false },
24
- store,
25
- config: { tier: undefined, channel: "prerelease" },
26
- ...overrides,
27
- };
28
- }
29
-
30
- async function executeOutput(
31
- cmd: CommandDefinition,
32
- params: Record<string, unknown>,
33
- ctx: PragmaContext,
34
- ): Promise<{ value: unknown; text: string }> {
35
- const result = await cmd.execute(params, ctx);
36
- expect(result.tag).toBe("output");
37
- if (result.tag !== "output") throw new Error("Expected output result");
38
- const text = result.render.plain(result.value);
39
- return { value: result.value, text };
40
- }
41
-
42
- describe("buildListCommand", () => {
43
- it("returns output result with all standards", async () => {
44
- const ctx = makeCtx();
45
- const cmd = buildListCommand(ctx);
46
- const { text } = await executeOutput(cmd, {}, ctx);
47
- expect(text).toContain("react/component/folder-structure");
48
- expect(text).toContain("react/component/props");
49
- expect(text).toContain("code/function/purity");
50
- });
51
-
52
- it("filters by --category", async () => {
53
- const ctx = makeCtx();
54
- const cmd = buildListCommand(ctx);
55
- const { text } = await executeOutput(cmd, { category: "react" }, ctx);
56
- expect(text).toContain("react/component/folder-structure");
57
- expect(text).toContain("react/component/props");
58
- expect(text).not.toContain("code/function/purity");
59
- });
60
-
61
- it("filters by --search", async () => {
62
- const ctx = makeCtx();
63
- const cmd = buildListCommand(ctx);
64
- const { text } = await executeOutput(cmd, { search: "folder" }, ctx);
65
- expect(text).toContain("react/component/folder-structure");
66
- expect(text).not.toContain("code/function/purity");
67
- });
68
-
69
- it("throws EMPTY_RESULTS for non-matching filter", async () => {
70
- const ctx = makeCtx();
71
- const cmd = buildListCommand(ctx);
72
- try {
73
- await cmd.execute({ category: "nonexistent" }, ctx);
74
- expect.fail("Should have thrown");
75
- } catch (e) {
76
- expect(e).toBeInstanceOf(PragmaError);
77
- expect((e as PragmaError).code).toBe("EMPTY_RESULTS");
78
- }
79
- });
80
-
81
- it("renders LLM format with --llm", async () => {
82
- const ctx = makeCtx({
83
- globalFlags: { llm: true, format: "text" as const, verbose: false },
84
- });
85
- const cmd = buildListCommand(ctx);
86
- const { text } = await executeOutput(cmd, {}, ctx);
87
- expect(text).toContain("## Standards");
88
- expect(text).toContain("**react/component/folder-structure**");
89
- });
90
-
91
- it("renders JSON output", async () => {
92
- const ctx = makeCtx({
93
- globalFlags: { llm: false, format: "json" as const, verbose: false },
94
- });
95
- const cmd = buildListCommand(ctx);
96
- const { text } = await executeOutput(cmd, {}, ctx);
97
- const parsed = JSON.parse(text);
98
- expect(Array.isArray(parsed)).toBe(true);
99
- expect(
100
- parsed.some(
101
- (s: { name: string }) => s.name === "react/component/folder-structure",
102
- ),
103
- ).toBe(true);
104
- });
105
- });
@@ -1,90 +0,0 @@
1
- /**
2
- * Wires the `pragma standard list` CLI command.
3
- *
4
- * Lists all code standards with optional category and search filters.
5
- * Supports progressive disclosure via `--digest` (summary + first example)
6
- * and `--detailed` (full dos/donts) flags.
7
- */
8
-
9
- import {
10
- type CommandDefinition,
11
- type CommandResult,
12
- createOutputResult,
13
- } from "@canonical/cli-core";
14
- import { createListView } from "#tui";
15
- import type { PragmaContext } from "../../shared/context.js";
16
- import { selectFormatter } from "../../shared/formatters.js";
17
- import { listFormatters } from "../formatters/index.js";
18
- import type { StandardListOutput } from "../formatters/types.js";
19
- import { resolveStandardList } from "../orchestration/index.js";
20
- import { standardConfig } from "../standardConfig.js";
21
-
22
- export default function buildListCommand(
23
- ctx: PragmaContext,
24
- ): CommandDefinition {
25
- return {
26
- path: ["standard", "list"],
27
- description: "List all code standards",
28
- parameters: [
29
- {
30
- name: "category",
31
- description: "Filter by category",
32
- type: "string",
33
- },
34
- {
35
- name: "search",
36
- description: "Search in name and description",
37
- type: "string",
38
- },
39
- {
40
- name: "digest",
41
- description: "Show description and first example for each standard",
42
- type: "boolean",
43
- default: false,
44
- },
45
- {
46
- name: "detailed",
47
- description: "Show full dos/donts for each standard",
48
- type: "boolean",
49
- default: false,
50
- },
51
- ],
52
- meta: {
53
- examples: [
54
- "pragma standard list",
55
- "pragma standard list --category react",
56
- 'pragma standard list --search "folder"',
57
- "pragma standard list --digest",
58
- "pragma standard list --detailed",
59
- "pragma standard list --llm",
60
- ],
61
- },
62
- execute: async (
63
- params: Record<string, unknown>,
64
- ): Promise<CommandResult> => {
65
- const contract = await resolveStandardList(ctx, {
66
- category: params.category as string | undefined,
67
- search: params.search as string | undefined,
68
- digest: params.digest === true,
69
- detailed: params.detailed === true,
70
- });
71
-
72
- const output: StandardListOutput = {
73
- items: contract.items,
74
- details: contract.details,
75
- disclosure: contract.disclosure,
76
- };
77
-
78
- return createOutputResult(output, {
79
- plain: selectFormatter(ctx, listFormatters),
80
- ink: (data) =>
81
- createListView({
82
- heading: "Standards",
83
- domain: "standard",
84
- items: data.items,
85
- columns: standardConfig.listColumns,
86
- }),
87
- });
88
- },
89
- };
90
- }