@canonical/pragma-cli 0.18.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 (439) hide show
  1. package/README.md +377 -0
  2. package/package.json +78 -0
  3. package/src/bin.test.ts +52 -0
  4. package/src/bin.ts +19 -0
  5. package/src/compile-validation.runner.ts +137 -0
  6. package/src/compile-validation.ts +192 -0
  7. package/src/completions/computeSocketPath.test.ts +26 -0
  8. package/src/completions/computeSocketPath.ts +16 -0
  9. package/src/completions/constants.ts +18 -0
  10. package/src/completions/handleQuery.test.ts +93 -0
  11. package/src/completions/handleQuery.ts +30 -0
  12. package/src/completions/index.ts +14 -0
  13. package/src/completions/queryCompletions.test.ts +100 -0
  14. package/src/completions/queryCompletions.ts +61 -0
  15. package/src/completions/querySocket.test.ts +70 -0
  16. package/src/completions/querySocket.ts +44 -0
  17. package/src/completions/startCompletionsServer.test.ts +74 -0
  18. package/src/completions/startCompletionsServer.ts +75 -0
  19. package/src/completions/startCompletionsServer.unit.test.ts +131 -0
  20. package/src/completions/waitForSocket.test.ts +27 -0
  21. package/src/completions/waitForSocket.ts +27 -0
  22. package/src/config/configExists.ts +14 -0
  23. package/src/config/index.ts +6 -0
  24. package/src/config/readConfig.test.ts +152 -0
  25. package/src/config/readConfig.ts +64 -0
  26. package/src/config/resolveConfigPath.test.ts +20 -0
  27. package/src/config/resolveConfigPath.ts +11 -0
  28. package/src/config/types.ts +26 -0
  29. package/src/config/writeConfig.ts +49 -0
  30. package/src/constants.ts +78 -0
  31. package/src/domains/block/blockConfig.ts +53 -0
  32. package/src/domains/block/commands/index.ts +4 -0
  33. package/src/domains/block/commands/list.test.ts +111 -0
  34. package/src/domains/block/commands/list.ts +69 -0
  35. package/src/domains/block/commands/lookup.test.ts +187 -0
  36. package/src/domains/block/commands/lookup.ts +199 -0
  37. package/src/domains/block/formatters/index.ts +4 -0
  38. package/src/domains/block/formatters/list.test.ts +107 -0
  39. package/src/domains/block/formatters/list.ts +64 -0
  40. package/src/domains/block/formatters/lookup.test.ts +317 -0
  41. package/src/domains/block/formatters/lookup.ts +354 -0
  42. package/src/domains/block/formatters/types.ts +16 -0
  43. package/src/domains/block/helpers/index.ts +4 -0
  44. package/src/domains/block/helpers/resolveAspects.test.ts +64 -0
  45. package/src/domains/block/helpers/resolveAspects.ts +35 -0
  46. package/src/domains/block/index.ts +25 -0
  47. package/src/domains/block/mcp/index.ts +2 -0
  48. package/src/domains/block/mcp/specs.ts +199 -0
  49. package/src/domains/block/operations/index.ts +4 -0
  50. package/src/domains/block/operations/list.test.ts +80 -0
  51. package/src/domains/block/operations/list.ts +72 -0
  52. package/src/domains/block/operations/lookup.test.ts +108 -0
  53. package/src/domains/block/operations/lookup.ts +359 -0
  54. package/src/domains/block/orchestration/blockEmptyError.ts +19 -0
  55. package/src/domains/block/orchestration/buildBlockFilters.ts +12 -0
  56. package/src/domains/block/orchestration/enrichBlocks.ts +37 -0
  57. package/src/domains/block/orchestration/index.ts +5 -0
  58. package/src/domains/block/orchestration/resolveBlockList.ts +39 -0
  59. package/src/domains/block/orchestration/resolveBlockLookup.ts +21 -0
  60. package/src/domains/block/types.ts +30 -0
  61. package/src/domains/config/commands/channel.test.ts +101 -0
  62. package/src/domains/config/commands/channel.ts +80 -0
  63. package/src/domains/config/commands/index.ts +4 -0
  64. package/src/domains/config/commands/show.test.ts +61 -0
  65. package/src/domains/config/commands/show.ts +51 -0
  66. package/src/domains/config/commands/tier.test.ts +84 -0
  67. package/src/domains/config/commands/tier.ts +78 -0
  68. package/src/domains/config/formatters/channel.test.ts +56 -0
  69. package/src/domains/config/formatters/channel.ts +34 -0
  70. package/src/domains/config/formatters/index.ts +4 -0
  71. package/src/domains/config/formatters/show.test.ts +126 -0
  72. package/src/domains/config/formatters/show.ts +66 -0
  73. package/src/domains/config/formatters/tier.test.ts +70 -0
  74. package/src/domains/config/formatters/tier.ts +40 -0
  75. package/src/domains/config/index.ts +23 -0
  76. package/src/domains/config/mcp/index.ts +2 -0
  77. package/src/domains/config/mcp/specs.ts +108 -0
  78. package/src/domains/config/operations/index.ts +5 -0
  79. package/src/domains/config/operations/show.test.ts +60 -0
  80. package/src/domains/config/operations/show.ts +42 -0
  81. package/src/domains/config/operations/types.ts +13 -0
  82. package/src/domains/config/operations/validateChannel.test.ts +36 -0
  83. package/src/domains/config/operations/validateChannel.ts +24 -0
  84. package/src/domains/config/operations/validateTier.test.ts +56 -0
  85. package/src/domains/config/operations/validateTier.ts +35 -0
  86. package/src/domains/create/commands/component.test.ts +166 -0
  87. package/src/domains/create/commands/component.ts +129 -0
  88. package/src/domains/create/commands/index.ts +3 -0
  89. package/src/domains/create/commands/package.test.ts +35 -0
  90. package/src/domains/create/commands/package.ts +21 -0
  91. package/src/domains/create/index.ts +15 -0
  92. package/src/domains/create/mcp/index.ts +2 -0
  93. package/src/domains/create/mcp/specs.ts +174 -0
  94. package/src/domains/doctor/commands/doctor.test.ts +75 -0
  95. package/src/domains/doctor/commands/doctor.ts +43 -0
  96. package/src/domains/doctor/commands/index.ts +2 -0
  97. package/src/domains/doctor/formatters/doctor.test.ts +117 -0
  98. package/src/domains/doctor/formatters/doctor.ts +84 -0
  99. package/src/domains/doctor/formatters/index.ts +2 -0
  100. package/src/domains/doctor/index.ts +9 -0
  101. package/src/domains/doctor/mcp/index.ts +2 -0
  102. package/src/domains/doctor/mcp/specs.ts +88 -0
  103. package/src/domains/doctor/operations/checks/checkConfigFile.ts +28 -0
  104. package/src/domains/doctor/operations/checks/checkKeStore.ts +38 -0
  105. package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +65 -0
  106. package/src/domains/doctor/operations/checks/checkNodeVersion.ts +25 -0
  107. package/src/domains/doctor/operations/checks/checkPragmaVersion.ts +20 -0
  108. package/src/domains/doctor/operations/checks/checkShellCompletions.ts +42 -0
  109. package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +64 -0
  110. package/src/domains/doctor/operations/checks/index.ts +8 -0
  111. package/src/domains/doctor/operations/checks.test.ts +151 -0
  112. package/src/domains/doctor/operations/index.ts +3 -0
  113. package/src/domains/doctor/operations/runChecks.test.ts +89 -0
  114. package/src/domains/doctor/operations/runChecks.ts +38 -0
  115. package/src/domains/doctor/operations/types.ts +20 -0
  116. package/src/domains/graph/commands/index.ts +4 -0
  117. package/src/domains/graph/commands/inspect.test.ts +94 -0
  118. package/src/domains/graph/commands/inspect.ts +63 -0
  119. package/src/domains/graph/commands/query.test.ts +92 -0
  120. package/src/domains/graph/commands/query.ts +60 -0
  121. package/src/domains/graph/formatters/index.ts +4 -0
  122. package/src/domains/graph/formatters/inspect.ts +45 -0
  123. package/src/domains/graph/formatters/query.ts +37 -0
  124. package/src/domains/graph/helpers/index.ts +3 -0
  125. package/src/domains/graph/helpers/resolveUri.ts +70 -0
  126. package/src/domains/graph/index.ts +22 -0
  127. package/src/domains/graph/mcp/index.ts +2 -0
  128. package/src/domains/graph/mcp/specs.ts +82 -0
  129. package/src/domains/graph/operations/executeQuery.test.ts +68 -0
  130. package/src/domains/graph/operations/executeQuery.ts +32 -0
  131. package/src/domains/graph/operations/index.ts +4 -0
  132. package/src/domains/graph/operations/inspectUri.test.ts +101 -0
  133. package/src/domains/graph/operations/inspectUri.ts +61 -0
  134. package/src/domains/info/commands/index.ts +4 -0
  135. package/src/domains/info/commands/info.test.ts +88 -0
  136. package/src/domains/info/commands/info.ts +47 -0
  137. package/src/domains/info/commands/upgrade.test.ts +183 -0
  138. package/src/domains/info/commands/upgrade.ts +150 -0
  139. package/src/domains/info/constants.test.ts +22 -0
  140. package/src/domains/info/constants.ts +15 -0
  141. package/src/domains/info/formatters/index.ts +8 -0
  142. package/src/domains/info/formatters/info.test.ts +173 -0
  143. package/src/domains/info/formatters/info.ts +116 -0
  144. package/src/domains/info/formatters/upgrade.test.ts +133 -0
  145. package/src/domains/info/formatters/upgrade.ts +68 -0
  146. package/src/domains/info/index.ts +7 -0
  147. package/src/domains/info/operations/checkRegistryVersion.test.ts +124 -0
  148. package/src/domains/info/operations/checkRegistryVersion.ts +45 -0
  149. package/src/domains/info/operations/collectInfo.test.ts +111 -0
  150. package/src/domains/info/operations/collectInfo.ts +68 -0
  151. package/src/domains/info/operations/collectStoreSummary.test.ts +61 -0
  152. package/src/domains/info/operations/collectStoreSummary.ts +42 -0
  153. package/src/domains/info/operations/index.ts +5 -0
  154. package/src/domains/info/types.test-d.ts +35 -0
  155. package/src/domains/info/types.ts +46 -0
  156. package/src/domains/llm/commands/index.ts +3 -0
  157. package/src/domains/llm/commands/llm.ts +37 -0
  158. package/src/domains/llm/data/commandReference.ts +25 -0
  159. package/src/domains/llm/data/decisionTrees.ts +46 -0
  160. package/src/domains/llm/data/index.ts +4 -0
  161. package/src/domains/llm/formatters/index.ts +3 -0
  162. package/src/domains/llm/formatters/orientation.ts +53 -0
  163. package/src/domains/llm/index.ts +8 -0
  164. package/src/domains/llm/llmCommand.test.ts +93 -0
  165. package/src/domains/llm/mcp/index.ts +2 -0
  166. package/src/domains/llm/mcp/specs.ts +87 -0
  167. package/src/domains/llm/operations/collectContext.ts +47 -0
  168. package/src/domains/llm/operations/index.ts +3 -0
  169. package/src/domains/llm/types.ts +32 -0
  170. package/src/domains/modifier/commands/index.ts +4 -0
  171. package/src/domains/modifier/commands/list.test.ts +57 -0
  172. package/src/domains/modifier/commands/list.ts +33 -0
  173. package/src/domains/modifier/commands/lookup.test.ts +91 -0
  174. package/src/domains/modifier/commands/lookup.ts +105 -0
  175. package/src/domains/modifier/formatters/index.ts +4 -0
  176. package/src/domains/modifier/formatters/list.test.ts +38 -0
  177. package/src/domains/modifier/formatters/list.ts +35 -0
  178. package/src/domains/modifier/formatters/lookup.test.ts +33 -0
  179. package/src/domains/modifier/formatters/lookup.ts +38 -0
  180. package/src/domains/modifier/index.ts +22 -0
  181. package/src/domains/modifier/mcp/index.ts +2 -0
  182. package/src/domains/modifier/mcp/specs.ts +97 -0
  183. package/src/domains/modifier/operations/index.ts +4 -0
  184. package/src/domains/modifier/operations/list.test.ts +39 -0
  185. package/src/domains/modifier/operations/list.ts +41 -0
  186. package/src/domains/modifier/operations/lookup.test.ts +37 -0
  187. package/src/domains/modifier/operations/lookup.ts +57 -0
  188. package/src/domains/modifier/orchestration/index.ts +3 -0
  189. package/src/domains/modifier/orchestration/modifierEmptyError.ts +10 -0
  190. package/src/domains/modifier/orchestration/resolveModifierList.ts +16 -0
  191. package/src/domains/modifier/orchestration/resolveModifierLookup.ts +20 -0
  192. package/src/domains/modifier/types.ts +5 -0
  193. package/src/domains/ontology/commands/index.ts +4 -0
  194. package/src/domains/ontology/commands/list.test.ts +82 -0
  195. package/src/domains/ontology/commands/list.ts +46 -0
  196. package/src/domains/ontology/commands/show.test.ts +103 -0
  197. package/src/domains/ontology/commands/show.ts +66 -0
  198. package/src/domains/ontology/formatters/index.ts +4 -0
  199. package/src/domains/ontology/formatters/list.ts +37 -0
  200. package/src/domains/ontology/formatters/show.ts +74 -0
  201. package/src/domains/ontology/helpers/findNamespace.ts +23 -0
  202. package/src/domains/ontology/helpers/index.ts +7 -0
  203. package/src/domains/ontology/helpers/queryClasses.ts +50 -0
  204. package/src/domains/ontology/helpers/queryProperties.ts +57 -0
  205. package/src/domains/ontology/helpers/resolvePrefix.ts +45 -0
  206. package/src/domains/ontology/index.ts +26 -0
  207. package/src/domains/ontology/mcp/index.ts +2 -0
  208. package/src/domains/ontology/mcp/specs.ts +93 -0
  209. package/src/domains/ontology/operations/index.ts +5 -0
  210. package/src/domains/ontology/operations/listOntologies.test.ts +45 -0
  211. package/src/domains/ontology/operations/listOntologies.ts +101 -0
  212. package/src/domains/ontology/operations/showOntology.test.ts +65 -0
  213. package/src/domains/ontology/operations/showOntology.ts +41 -0
  214. package/src/domains/ontology/operations/showOntologyRaw.test.ts +39 -0
  215. package/src/domains/ontology/operations/showOntologyRaw.ts +50 -0
  216. package/src/domains/setup/commands/all.ts +58 -0
  217. package/src/domains/setup/commands/completions.ts +85 -0
  218. package/src/domains/setup/commands/entrypoints.test.ts +170 -0
  219. package/src/domains/setup/commands/index.ts +6 -0
  220. package/src/domains/setup/commands/lsp.ts +49 -0
  221. package/src/domains/setup/commands/mcp.ts +119 -0
  222. package/src/domains/setup/commands/skills.test.ts +64 -0
  223. package/src/domains/setup/commands/skills.ts +106 -0
  224. package/src/domains/setup/formatters/index.ts +2 -0
  225. package/src/domains/setup/formatters/skills.test.ts +103 -0
  226. package/src/domains/setup/formatters/skills.ts +112 -0
  227. package/src/domains/setup/formatters/types.ts +7 -0
  228. package/src/domains/setup/helpers/completionScripts.test.ts +58 -0
  229. package/src/domains/setup/helpers/completionScripts.ts +92 -0
  230. package/src/domains/setup/helpers/constants.ts +2 -0
  231. package/src/domains/setup/helpers/detectShell.test.ts +48 -0
  232. package/src/domains/setup/helpers/detectShell.ts +20 -0
  233. package/src/domains/setup/helpers/index.ts +12 -0
  234. package/src/domains/setup/helpers/runSetupTask.test.ts +279 -0
  235. package/src/domains/setup/helpers/runSetupTask.ts +229 -0
  236. package/src/domains/setup/index.ts +33 -0
  237. package/src/domains/setup/operations/index.ts +6 -0
  238. package/src/domains/setup/operations/setupAll.test.ts +48 -0
  239. package/src/domains/setup/operations/setupAll.ts +41 -0
  240. package/src/domains/setup/operations/setupCompletions.test.ts +94 -0
  241. package/src/domains/setup/operations/setupCompletions.ts +54 -0
  242. package/src/domains/setup/operations/setupLsp.test.ts +29 -0
  243. package/src/domains/setup/operations/setupLsp.ts +17 -0
  244. package/src/domains/setup/operations/setupMcp.test.ts +115 -0
  245. package/src/domains/setup/operations/setupMcp.ts +108 -0
  246. package/src/domains/setup/operations/setupSkills.test.ts +191 -0
  247. package/src/domains/setup/operations/setupSkills.ts +160 -0
  248. package/src/domains/setup/types.ts +18 -0
  249. package/src/domains/shared/ToolSpec.ts +49 -0
  250. package/src/domains/shared/bootStore.ts +77 -0
  251. package/src/domains/shared/buildQuery.ts +18 -0
  252. package/src/domains/shared/compactUri.test.ts +21 -0
  253. package/src/domains/shared/compactUri.ts +16 -0
  254. package/src/domains/shared/context.ts +15 -0
  255. package/src/domains/shared/contracts.ts +113 -0
  256. package/src/domains/shared/extractLocalName.test.ts +21 -0
  257. package/src/domains/shared/extractLocalName.ts +14 -0
  258. package/src/domains/shared/filters/buildChannelFilter.test.ts +52 -0
  259. package/src/domains/shared/filters/buildChannelFilter.ts +41 -0
  260. package/src/domains/shared/filters/buildFilterConfig.ts +16 -0
  261. package/src/domains/shared/filters/buildFilters.test.ts +33 -0
  262. package/src/domains/shared/filters/buildFilters.ts +30 -0
  263. package/src/domains/shared/filters/buildTierFilter.test.ts +78 -0
  264. package/src/domains/shared/filters/buildTierFilter.ts +69 -0
  265. package/src/domains/shared/filters/describeFilters.ts +14 -0
  266. package/src/domains/shared/filters/index.ts +10 -0
  267. package/src/domains/shared/formatters.ts +35 -0
  268. package/src/domains/shared/lookupMany.ts +45 -0
  269. package/src/domains/shared/namespaces.ts +18 -0
  270. package/src/domains/shared/packages.ts +76 -0
  271. package/src/domains/shared/prefixes.ts +37 -0
  272. package/src/domains/shared/runtime.ts +62 -0
  273. package/src/domains/shared/types.test-d.ts +127 -0
  274. package/src/domains/shared/types.ts +348 -0
  275. package/src/domains/skill/commands/index.ts +2 -0
  276. package/src/domains/skill/commands/list.test.ts +111 -0
  277. package/src/domains/skill/commands/list.ts +69 -0
  278. package/src/domains/skill/formatters/index.ts +2 -0
  279. package/src/domains/skill/formatters/list.test.ts +140 -0
  280. package/src/domains/skill/formatters/list.ts +119 -0
  281. package/src/domains/skill/formatters/types.ts +8 -0
  282. package/src/domains/skill/helpers/index.ts +6 -0
  283. package/src/domains/skill/helpers/parseFrontmatter.test.ts +122 -0
  284. package/src/domains/skill/helpers/parseFrontmatter.ts +112 -0
  285. package/src/domains/skill/helpers/resolveSkillSources.ts +34 -0
  286. package/src/domains/skill/index.ts +19 -0
  287. package/src/domains/skill/mcp/index.ts +2 -0
  288. package/src/domains/skill/mcp/specs.ts +38 -0
  289. package/src/domains/skill/operations/discover.test.ts +145 -0
  290. package/src/domains/skill/operations/discover.ts +68 -0
  291. package/src/domains/skill/operations/index.ts +4 -0
  292. package/src/domains/skill/operations/list.test.ts +68 -0
  293. package/src/domains/skill/operations/list.ts +47 -0
  294. package/src/domains/skill/types.ts +25 -0
  295. package/src/domains/standard/commands/categories.test.ts +70 -0
  296. package/src/domains/standard/commands/categories.ts +48 -0
  297. package/src/domains/standard/commands/index.ts +5 -0
  298. package/src/domains/standard/commands/list.test.ts +105 -0
  299. package/src/domains/standard/commands/list.ts +81 -0
  300. package/src/domains/standard/commands/lookup.test.ts +135 -0
  301. package/src/domains/standard/commands/lookup.ts +127 -0
  302. package/src/domains/standard/formatters/categories.test.ts +44 -0
  303. package/src/domains/standard/formatters/categories.ts +38 -0
  304. package/src/domains/standard/formatters/index.ts +6 -0
  305. package/src/domains/standard/formatters/list.test.ts +166 -0
  306. package/src/domains/standard/formatters/list.ts +156 -0
  307. package/src/domains/standard/formatters/lookup.test.ts +95 -0
  308. package/src/domains/standard/formatters/lookup.ts +86 -0
  309. package/src/domains/standard/formatters/types.ts +31 -0
  310. package/src/domains/standard/index.ts +32 -0
  311. package/src/domains/standard/mcp/index.ts +2 -0
  312. package/src/domains/standard/mcp/specs.ts +197 -0
  313. package/src/domains/standard/operations/categories.test.ts +61 -0
  314. package/src/domains/standard/operations/categories.ts +38 -0
  315. package/src/domains/standard/operations/index.ts +5 -0
  316. package/src/domains/standard/operations/list.test.ts +75 -0
  317. package/src/domains/standard/operations/list.ts +64 -0
  318. package/src/domains/standard/operations/lookup.test.ts +58 -0
  319. package/src/domains/standard/operations/lookup.ts +142 -0
  320. package/src/domains/standard/orchestration/buildStandardFilters.ts +11 -0
  321. package/src/domains/standard/orchestration/index.ts +4 -0
  322. package/src/domains/standard/orchestration/resolveStandardList.ts +42 -0
  323. package/src/domains/standard/orchestration/resolveStandardLookup.ts +20 -0
  324. package/src/domains/standard/orchestration/standardEmptyError.ts +19 -0
  325. package/src/domains/standard/types.ts +15 -0
  326. package/src/domains/tier/commands/index.ts +3 -0
  327. package/src/domains/tier/commands/list.test.ts +67 -0
  328. package/src/domains/tier/commands/list.ts +43 -0
  329. package/src/domains/tier/formatters/index.ts +3 -0
  330. package/src/domains/tier/formatters/list.test.ts +33 -0
  331. package/src/domains/tier/formatters/list.ts +40 -0
  332. package/src/domains/tier/index.ts +17 -0
  333. package/src/domains/tier/mcp/index.ts +2 -0
  334. package/src/domains/tier/mcp/specs.ts +38 -0
  335. package/src/domains/tier/operations/index.ts +3 -0
  336. package/src/domains/tier/operations/list.test.ts +32 -0
  337. package/src/domains/tier/operations/list.ts +33 -0
  338. package/src/domains/token/commands/add-config.test.ts +68 -0
  339. package/src/domains/token/commands/add-config.ts +62 -0
  340. package/src/domains/token/commands/index.ts +5 -0
  341. package/src/domains/token/commands/list.test.ts +82 -0
  342. package/src/domains/token/commands/list.ts +45 -0
  343. package/src/domains/token/commands/lookup.test.ts +125 -0
  344. package/src/domains/token/commands/lookup.ts +121 -0
  345. package/src/domains/token/formatters/index.ts +4 -0
  346. package/src/domains/token/formatters/list.test.ts +37 -0
  347. package/src/domains/token/formatters/list.ts +37 -0
  348. package/src/domains/token/formatters/lookup.test.ts +61 -0
  349. package/src/domains/token/formatters/lookup.ts +72 -0
  350. package/src/domains/token/index.ts +32 -0
  351. package/src/domains/token/mcp/index.ts +2 -0
  352. package/src/domains/token/mcp/specs.ts +145 -0
  353. package/src/domains/token/operations/add-config.test.ts +68 -0
  354. package/src/domains/token/operations/add-config.ts +61 -0
  355. package/src/domains/token/operations/index.ts +7 -0
  356. package/src/domains/token/operations/list.test.ts +50 -0
  357. package/src/domains/token/operations/list.ts +52 -0
  358. package/src/domains/token/operations/lookup.test.ts +42 -0
  359. package/src/domains/token/operations/lookup.ts +66 -0
  360. package/src/domains/token/orchestration/index.ts +3 -0
  361. package/src/domains/token/orchestration/resolveTokenList.ts +17 -0
  362. package/src/domains/token/orchestration/resolveTokenLookup.ts +20 -0
  363. package/src/domains/token/orchestration/tokenEmptyError.ts +17 -0
  364. package/src/domains/token/types.ts +6 -0
  365. package/src/error/PragmaError.test.ts +121 -0
  366. package/src/error/PragmaError.ts +164 -0
  367. package/src/error/constants.ts +12 -0
  368. package/src/error/index.ts +4 -0
  369. package/src/error/types.ts +41 -0
  370. package/src/index.ts +141 -0
  371. package/src/mcp/createMcpServer.test.ts +41 -0
  372. package/src/mcp/createMcpServer.ts +53 -0
  373. package/src/mcp/error/buildRecovery.test.ts +37 -0
  374. package/src/mcp/error/buildRecovery.ts +17 -0
  375. package/src/mcp/error/index.ts +12 -0
  376. package/src/mcp/error/serializeError.test.ts +121 -0
  377. package/src/mcp/error/serializeError.ts +31 -0
  378. package/src/mcp/error/serializeErrorPayload.test.ts +38 -0
  379. package/src/mcp/error/serializeErrorPayload.ts +27 -0
  380. package/src/mcp/error/types.ts +51 -0
  381. package/src/mcp/index.ts +15 -0
  382. package/src/mcp/registerResources.test.ts +236 -0
  383. package/src/mcp/registerResources.ts +303 -0
  384. package/src/mcp/runMcpServer.test.ts +66 -0
  385. package/src/mcp/runMcpServer.ts +24 -0
  386. package/src/mcp/tools/index.ts +55 -0
  387. package/src/mcp/tools/registerFromSpec.ts +97 -0
  388. package/src/mcp/tools/registerTools.test.ts +1124 -0
  389. package/src/mcp/types.ts +62 -0
  390. package/src/mcp/utils/estimateTokens.test.ts +14 -0
  391. package/src/mcp/utils/estimateTokens.ts +9 -0
  392. package/src/mcp/utils/index.ts +11 -0
  393. package/src/mcp/utils/wrapTool.test.ts +108 -0
  394. package/src/mcp/utils/wrapTool.ts +81 -0
  395. package/src/package-manager/constants.ts +29 -0
  396. package/src/package-manager/detectInstallSource.test.ts +23 -0
  397. package/src/package-manager/detectInstallSource.ts +111 -0
  398. package/src/package-manager/detectLocalInstall.test.ts +16 -0
  399. package/src/package-manager/detectLocalInstall.ts +43 -0
  400. package/src/package-manager/detectPackageManager.test.ts +81 -0
  401. package/src/package-manager/detectPackageManager.ts +30 -0
  402. package/src/package-manager/index.ts +6 -0
  403. package/src/package-manager/types.ts +12 -0
  404. package/src/pipeline/collectCommands.test.ts +37 -0
  405. package/src/pipeline/collectCommands.ts +47 -0
  406. package/src/pipeline/constants.ts +14 -0
  407. package/src/pipeline/createProgram.test.ts +112 -0
  408. package/src/pipeline/createProgram.ts +70 -0
  409. package/src/pipeline/formatTerminal.test.ts +43 -0
  410. package/src/pipeline/formatTerminal.ts +53 -0
  411. package/src/pipeline/index.ts +19 -0
  412. package/src/pipeline/mapExitCode.test.ts +41 -0
  413. package/src/pipeline/mapExitCode.ts +12 -0
  414. package/src/pipeline/parseGlobalFlags.ts +21 -0
  415. package/src/pipeline/renderError.test.ts +151 -0
  416. package/src/pipeline/renderError.ts +114 -0
  417. package/src/pipeline/resolveCommandKind.test.ts +68 -0
  418. package/src/pipeline/resolveCommandKind.ts +71 -0
  419. package/src/pipeline/runCli.orchestration.test.ts +418 -0
  420. package/src/pipeline/runCli.test.ts +70 -0
  421. package/src/pipeline/runCli.ts +215 -0
  422. package/src/pipeline/types.ts +17 -0
  423. package/src/testing/cli.ts +43 -0
  424. package/src/testing/createTestMcpClient.ts +64 -0
  425. package/src/testing/dsFixtures.ts +506 -0
  426. package/src/testing/fixtures/canonical-config.json +4 -0
  427. package/src/testing/fixtures/canonical.ttl +437 -0
  428. package/src/testing/fixtures/filtered-config.json +4 -0
  429. package/src/testing/fixtures.ts +34 -0
  430. package/src/testing/helpers/assertParity.ts +28 -0
  431. package/src/testing/helpers/createTestMcpClient.ts +40 -0
  432. package/src/testing/helpers/createTestRuntime.ts +67 -0
  433. package/src/testing/index.ts +8 -0
  434. package/src/testing/integration/agent-session.test.ts +148 -0
  435. package/src/testing/integration/boot.test.ts +67 -0
  436. package/src/testing/integration/mcp-surface.test.ts +574 -0
  437. package/src/testing/integration/parity.test.ts +192 -0
  438. package/src/testing/store.ts +39 -0
  439. package/src/testing/types.ts +20 -0
@@ -0,0 +1,437 @@
1
+
2
+ @prefix ds: <https://ds.canonical.com/> .
3
+ @prefix cs: <http://pragma.canonical.com/codestandards#> .
4
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
5
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
6
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
7
+
8
+ # ---- Classes ----
9
+
10
+ ds:UIBlock a owl:Class ;
11
+ rdfs:label "UI Block" .
12
+
13
+ ds:Component a owl:Class ;
14
+ rdfs:subClassOf ds:UIBlock ;
15
+ rdfs:label "Component" .
16
+
17
+ ds:Pattern a owl:Class ;
18
+ rdfs:subClassOf ds:UIBlock ;
19
+ rdfs:label "Pattern" .
20
+
21
+ ds:Tier a owl:Class ;
22
+ rdfs:label "Tier" .
23
+
24
+ ds:ModifierFamily a owl:Class ;
25
+ rdfs:label "Modifier Family" .
26
+
27
+ ds:Modifier a owl:Class ;
28
+ rdfs:label "Modifier" .
29
+
30
+ ds:Token a owl:Class ;
31
+ rdfs:label "Design Token" .
32
+
33
+ ds:TokenType a owl:Class ;
34
+ rdfs:label "Token Type" .
35
+
36
+ ds:ImplementationLibrary a owl:Class ;
37
+ rdfs:label "Implementation Library" .
38
+
39
+ ds:ImplementationObject a owl:Class ;
40
+ rdfs:label "Implementation Object" .
41
+
42
+ ds:BlockProperty a owl:Class ;
43
+ rdfs:label "Block Property" .
44
+
45
+ ds:Subcomponent a owl:Class ;
46
+ rdfs:subClassOf ds:UIBlock ;
47
+ rdfs:label "Subcomponent" .
48
+
49
+ cs:CodeStandard a owl:Class ;
50
+ rdfs:label "Code Standard" .
51
+
52
+ cs:Category a owl:Class ;
53
+ rdfs:label "Standard Category" .
54
+
55
+ # ---- Properties ----
56
+
57
+ ds:name a owl:DatatypeProperty ;
58
+ rdfs:domain ds:UIBlock ;
59
+ rdfs:range xsd:string .
60
+
61
+ ds:tier a owl:ObjectProperty ;
62
+ rdfs:domain ds:UIBlock .
63
+
64
+ ds:release a owl:ObjectProperty ;
65
+ rdfs:domain ds:UIBlock .
66
+
67
+ ds:hasModifierFamily a owl:ObjectProperty ;
68
+ rdfs:domain ds:UIBlock ;
69
+ rdfs:range ds:ModifierFamily .
70
+
71
+ ds:modifierFamily a owl:ObjectProperty ;
72
+ rdfs:domain ds:Modifier ;
73
+ rdfs:range ds:ModifierFamily .
74
+
75
+ ds:tokenId a owl:DatatypeProperty ;
76
+ rdfs:domain ds:Token ;
77
+ rdfs:range xsd:string .
78
+
79
+ ds:tokenType a owl:ObjectProperty ;
80
+ rdfs:domain ds:Token ;
81
+ rdfs:range ds:TokenType .
82
+
83
+ ds:tokenTier a owl:ObjectProperty ;
84
+ rdfs:domain ds:Token .
85
+
86
+ ds:valueLight a owl:DatatypeProperty ;
87
+ rdfs:domain ds:Token ;
88
+ rdfs:range xsd:string .
89
+
90
+ ds:valueDark a owl:DatatypeProperty ;
91
+ rdfs:domain ds:Token ;
92
+ rdfs:range xsd:string .
93
+
94
+ ds:platform a owl:DatatypeProperty ;
95
+ rdfs:domain ds:ImplementationLibrary ;
96
+ rdfs:range xsd:string .
97
+
98
+ ds:libraryName a owl:DatatypeProperty ;
99
+ rdfs:domain ds:ImplementationLibrary ;
100
+ rdfs:range xsd:string .
101
+
102
+ ds:hasImplementation a owl:ObjectProperty ;
103
+ rdfs:domain ds:ImplementationLibrary ;
104
+ rdfs:range ds:ImplementationObject .
105
+
106
+ ds:implementsBlock a owl:ObjectProperty ;
107
+ rdfs:domain ds:ImplementationObject ;
108
+ rdfs:range ds:UIBlock .
109
+
110
+ ds:headLink a owl:DatatypeProperty ;
111
+ rdfs:domain ds:ImplementationObject ;
112
+ rdfs:range xsd:string .
113
+
114
+ ds:usesToken a owl:ObjectProperty ;
115
+ rdfs:domain ds:UIBlock ;
116
+ rdfs:range ds:Token .
117
+
118
+ ds:anatomyNode a owl:ObjectProperty ;
119
+ rdfs:domain ds:UIBlock .
120
+
121
+ ds:summary a owl:DatatypeProperty ;
122
+ rdfs:domain ds:UIBlock ;
123
+ rdfs:range xsd:string .
124
+
125
+ ds:whenToUse a owl:DatatypeProperty ;
126
+ rdfs:domain ds:UIBlock ;
127
+ rdfs:range xsd:string .
128
+
129
+ ds:whenNotToUse a owl:DatatypeProperty ;
130
+ rdfs:domain ds:UIBlock ;
131
+ rdfs:range xsd:string .
132
+
133
+ ds:guidelines a owl:DatatypeProperty ;
134
+ rdfs:domain ds:UIBlock ;
135
+ rdfs:range xsd:string .
136
+
137
+ ds:anatomyDsl a owl:DatatypeProperty ;
138
+ rdfs:domain ds:UIBlock ;
139
+ rdfs:range xsd:string .
140
+
141
+ ds:anatomyClassic a owl:DatatypeProperty ;
142
+ rdfs:domain ds:UIBlock ;
143
+ rdfs:range xsd:string .
144
+
145
+ ds:figmaLink a owl:DatatypeProperty ;
146
+ rdfs:domain ds:UIBlock ;
147
+ rdfs:range xsd:string .
148
+
149
+ ds:hasProperty a owl:ObjectProperty ;
150
+ rdfs:domain ds:UIBlock ;
151
+ rdfs:range ds:BlockProperty .
152
+
153
+ ds:propertyType a owl:DatatypeProperty ;
154
+ rdfs:domain ds:BlockProperty ;
155
+ rdfs:range xsd:string .
156
+
157
+ ds:optional a owl:DatatypeProperty ;
158
+ rdfs:domain ds:BlockProperty ;
159
+ rdfs:range xsd:boolean .
160
+
161
+ ds:defaultValue a owl:DatatypeProperty ;
162
+ rdfs:domain ds:BlockProperty ;
163
+ rdfs:range xsd:string .
164
+
165
+ ds:constraints a owl:DatatypeProperty ;
166
+ rdfs:domain ds:BlockProperty ;
167
+ rdfs:range xsd:string .
168
+
169
+ ds:hasSubcomponent a owl:ObjectProperty ;
170
+ rdfs:domain ds:UIBlock ;
171
+ rdfs:range ds:Subcomponent .
172
+
173
+ cs:name a owl:DatatypeProperty ;
174
+ rdfs:domain cs:CodeStandard ;
175
+ rdfs:range xsd:string .
176
+
177
+ cs:hasCategory a owl:ObjectProperty ;
178
+ rdfs:domain cs:CodeStandard ;
179
+ rdfs:range cs:Category .
180
+
181
+ cs:slug a owl:DatatypeProperty ;
182
+ rdfs:domain cs:Category ;
183
+ rdfs:range xsd:string .
184
+
185
+ cs:description a owl:DatatypeProperty ;
186
+ rdfs:domain cs:CodeStandard ;
187
+ rdfs:range xsd:string .
188
+
189
+ cs:Example a owl:Class .
190
+
191
+ cs:do a owl:ObjectProperty ;
192
+ rdfs:domain cs:CodeStandard ;
193
+ rdfs:range cs:Example .
194
+
195
+ cs:dont a owl:ObjectProperty ;
196
+ rdfs:domain cs:CodeStandard ;
197
+ rdfs:range cs:Example .
198
+
199
+ cs:language a owl:DatatypeProperty ;
200
+ rdfs:domain cs:Example ;
201
+ rdfs:range xsd:string .
202
+
203
+ cs:code a owl:DatatypeProperty ;
204
+ rdfs:domain cs:Example ;
205
+ rdfs:range xsd:string .
206
+
207
+ cs:extends a owl:ObjectProperty ;
208
+ rdfs:domain cs:CodeStandard ;
209
+ rdfs:range cs:CodeStandard .
210
+
211
+
212
+ @prefix ds: <https://ds.canonical.com/> .
213
+
214
+ ds:global a ds:Tier ;
215
+ ds:name "global" .
216
+
217
+ ds:apps a ds:Tier ;
218
+ ds:name "apps" .
219
+
220
+ ds:apps_lxd a ds:Tier ;
221
+ ds:name "apps/lxd" .
222
+
223
+
224
+ @prefix ds: <https://ds.canonical.com/> .
225
+
226
+ ds:stable a ds:ReleaseChannel .
227
+ ds:experimental a ds:ReleaseChannel .
228
+ ds:alpha a ds:ReleaseChannel .
229
+ ds:beta a ds:ReleaseChannel .
230
+
231
+
232
+ @prefix ds: <https://ds.canonical.com/> .
233
+
234
+ ds:global.component.button a ds:Component ;
235
+ ds:name "Button" ;
236
+ ds:tier ds:global ;
237
+ ds:release ds:stable ;
238
+ ds:summary "Primary action trigger with optional icon and label." ;
239
+ ds:whenToUse "Use for high-priority actions in forms and flows." ;
240
+ ds:whenNotToUse "Avoid for low-emphasis tertiary actions." ;
241
+ ds:guidelines "Keep labels concise and pair icons with text when possible." ;
242
+ ds:anatomyDsl "root: button; children: label, icon" ;
243
+ ds:anatomyClassic "button > label + icon" ;
244
+ ds:figmaLink "https://figma.com/design/example/Button" ;
245
+ ds:hasModifierFamily ds:modifier_family.importance ;
246
+ ds:hasModifierFamily ds:modifier_family.density ;
247
+ ds:usesToken ds:token.color.primary ;
248
+ ds:anatomyNode ds:global.component.button.node.root ;
249
+ ds:anatomyNode ds:global.component.button.node.label ;
250
+ ds:anatomyNode ds:global.component.button.node.icon ;
251
+ ds:hasProperty [
252
+ a ds:BlockProperty ;
253
+ ds:name "disabled" ;
254
+ ds:propertyType "boolean" ;
255
+ ds:optional true ;
256
+ ds:defaultValue "false" ;
257
+ ds:constraints "Disables click and keyboard activation."
258
+ ] , [
259
+ a ds:BlockProperty ;
260
+ ds:name "loading" ;
261
+ ds:propertyType "boolean" ;
262
+ ds:optional true ;
263
+ ds:defaultValue "false" ;
264
+ ds:constraints "Shows busy state and suppresses duplicate actions."
265
+ ] ;
266
+ ds:hasSubcomponent ds:global.subcomponent.button.icon .
267
+
268
+ ds:global.component.button.node.root a ds:AnatomyNode ;
269
+ ds:name "button" .
270
+
271
+ ds:global.component.button.node.label a ds:AnatomyNode ;
272
+ ds:name "label" .
273
+
274
+ ds:global.component.button.node.icon a ds:AnatomyNode ;
275
+ ds:name "icon" .
276
+
277
+ ds:global.subcomponent.button.icon a ds:Subcomponent ;
278
+ ds:name "Button Icon" ;
279
+ ds:tier ds:global ;
280
+ ds:release ds:stable .
281
+
282
+ ds:global.component.card a ds:Component ;
283
+ ds:name "Card" ;
284
+ ds:tier ds:global ;
285
+ ds:release ds:stable ;
286
+ ds:summary "Contained surface for related content and actions." ;
287
+ ds:anatomyDsl "root: card; children: header, body" ;
288
+ ds:hasProperty [
289
+ a ds:BlockProperty ;
290
+ ds:name "padding" ;
291
+ ds:propertyType "dimension" ;
292
+ ds:optional true ;
293
+ ds:defaultValue "spacing.md" ;
294
+ ds:constraints "Use design token references for spacing values."
295
+ ] .
296
+
297
+ ds:apps.lxd.component.panel a ds:Component ;
298
+ ds:name "LXD Panel" ;
299
+ ds:tier ds:apps_lxd ;
300
+ ds:release ds:stable .
301
+
302
+ ds:global.component.beta-widget a ds:Component ;
303
+ ds:name "Beta Widget" ;
304
+ ds:tier ds:global ;
305
+ ds:release ds:beta .
306
+
307
+
308
+ @prefix ds: <https://ds.canonical.com/> .
309
+
310
+ ds:impl.react a ds:ImplementationLibrary ;
311
+ ds:libraryName "@canonical/react-ds-global" ;
312
+ ds:platform "react" ;
313
+ ds:hasImplementation [
314
+ a ds:ImplementationObject ;
315
+ ds:implementsBlock ds:global.component.button ;
316
+ ds:headLink "src/lib/Button/Button.tsx"
317
+ ] , [
318
+ a ds:ImplementationObject ;
319
+ ds:implementsBlock ds:global.component.card ;
320
+ ds:headLink "src/lib/Card/Card.tsx"
321
+ ] .
322
+
323
+ ds:impl.svelte a ds:ImplementationLibrary ;
324
+ ds:libraryName "@canonical/svelte-ds-global" ;
325
+ ds:platform "svelte" .
326
+
327
+
328
+ @prefix cs: <http://pragma.canonical.com/codestandards#> .
329
+
330
+ cs:react_category a cs:Category ;
331
+ cs:slug "react" .
332
+
333
+ cs:code_category a cs:Category ;
334
+ cs:slug "code" .
335
+
336
+ cs:react_folder a cs:CodeStandard ;
337
+ cs:name "react/component/folder-structure" ;
338
+ cs:hasCategory cs:react_category ;
339
+ cs:description "Components must follow the standard folder layout" ;
340
+ cs:do [
341
+ cs:description "Place component files in src/lib/ComponentName/" ;
342
+ cs:language "typescript" ;
343
+ cs:code "src/lib/Button/Button.tsx"
344
+ ] ;
345
+ cs:do [
346
+ cs:description "Include index.ts barrel export" ;
347
+ cs:language "typescript" ;
348
+ cs:code "export { default } from './Button.js';"
349
+ ] ;
350
+ cs:dont [
351
+ cs:description "Use flat directory with all components at same level" ;
352
+ cs:language "typescript" ;
353
+ cs:code "src/lib/Button.tsx"
354
+ ] .
355
+
356
+ cs:react_props a cs:CodeStandard ;
357
+ cs:name "react/component/props" ;
358
+ cs:hasCategory cs:react_category ;
359
+ cs:extends cs:react_folder ;
360
+ cs:description "Props must extend the base HTML element type" ;
361
+ cs:do [
362
+ cs:description "Extend HTMLAttributes<HTMLElement>" ;
363
+ cs:language "typescript" ;
364
+ cs:code "interface ButtonProps extends HTMLAttributes<HTMLButtonElement> {}"
365
+ ] ;
366
+ cs:dont [
367
+ cs:description "Define props without extending HTML attributes" ;
368
+ cs:language "typescript" ;
369
+ cs:code "interface ButtonProps { onClick: () => void }"
370
+ ] .
371
+
372
+ cs:code_purity a cs:CodeStandard ;
373
+ cs:name "code/function/purity" ;
374
+ cs:hasCategory cs:code_category ;
375
+ cs:description "Functions should be pure where possible" ;
376
+ cs:do [
377
+ cs:description "Return same output for same input" ;
378
+ cs:language "typescript" ;
379
+ cs:code "function add(a: number, b: number) { return a + b; }"
380
+ ] ;
381
+ cs:dont [
382
+ cs:description "Modify external state without annotation" ;
383
+ cs:language "typescript" ;
384
+ cs:code "let count = 0; function increment() { count++; }"
385
+ ] .
386
+
387
+
388
+ @prefix ds: <https://ds.canonical.com/> .
389
+
390
+ ds:modifier_family.importance a ds:ModifierFamily ;
391
+ ds:name "importance" .
392
+
393
+ ds:mod_importance_default a ds:Modifier ;
394
+ ds:name "default" ;
395
+ ds:modifierFamily ds:modifier_family.importance .
396
+
397
+ ds:mod_importance_primary a ds:Modifier ;
398
+ ds:name "primary" ;
399
+ ds:modifierFamily ds:modifier_family.importance .
400
+
401
+ ds:mod_importance_secondary a ds:Modifier ;
402
+ ds:name "secondary" ;
403
+ ds:modifierFamily ds:modifier_family.importance .
404
+
405
+ ds:modifier_family.density a ds:ModifierFamily ;
406
+ ds:name "density" .
407
+
408
+ ds:mod_density_default a ds:Modifier ;
409
+ ds:name "default" ;
410
+ ds:modifierFamily ds:modifier_family.density .
411
+
412
+ ds:mod_density_compact a ds:Modifier ;
413
+ ds:name "compact" ;
414
+ ds:modifierFamily ds:modifier_family.density .
415
+
416
+
417
+ @prefix ds: <https://ds.canonical.com/> .
418
+
419
+ ds:token_type.color a ds:TokenType ;
420
+ rdfs:label "Color" .
421
+
422
+ ds:token_type.dimension a ds:TokenType ;
423
+ rdfs:label "Dimension" .
424
+
425
+ ds:token.color.primary a ds:Token ;
426
+ ds:tokenId "color.primary" ;
427
+ ds:tokenType ds:token_type.color ;
428
+ ds:tokenTier ds:token_tier.semantic ;
429
+ ds:valueLight "#0066cc" ;
430
+ ds:valueDark "#4d9aff" .
431
+
432
+ ds:token.spacing.sm a ds:Token ;
433
+ ds:tokenId "spacing.sm" ;
434
+ ds:tokenType ds:token_type.dimension ;
435
+ ds:tokenTier ds:token_tier.primitive ;
436
+ ds:valueLight "8px" ;
437
+ ds:valueDark "8px" .
@@ -0,0 +1,4 @@
1
+ {
2
+ "tier": "apps/lxd",
3
+ "channel": "normal"
4
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Test fixtures for configuration parsing and package-manager detection.
3
+ *
4
+ * Groups sample config strings and mock binary paths used by
5
+ * unit tests across the config and package-manager domains.
6
+ */
7
+
8
+ /** Full config with both tier and channel set. */
9
+ const SAMPLE_CONFIG_FULL = `tier = "apps/lxd"
10
+ channel = "experimental"
11
+ `;
12
+
13
+ /** Config with only the tier field set. */
14
+ const SAMPLE_CONFIG_TIER_ONLY = `tier = "global"
15
+ `;
16
+
17
+ /** Empty config — no tier, no channel override. */
18
+ const SAMPLE_CONFIG_EMPTY = "";
19
+
20
+ /** Mock pragma binary paths keyed by package manager name. */
21
+ const MOCK_BIN_PATHS: Record<string, string> = {
22
+ bun: "/home/user/.bun/install/global/node_modules/.bin/pragma",
23
+ pnpm: "/home/user/.local/share/pnpm/global/5/node_modules/.bin/pragma",
24
+ yarn: "/home/user/.yarn/bin/pragma",
25
+ npm: "/home/user/.config/nvm/versions/node/v24/bin/pragma",
26
+ local: "/project/node_modules/.bin/pragma",
27
+ };
28
+
29
+ export {
30
+ SAMPLE_CONFIG_FULL,
31
+ SAMPLE_CONFIG_TIER_ONLY,
32
+ SAMPLE_CONFIG_EMPTY,
33
+ MOCK_BIN_PATHS,
34
+ };
@@ -0,0 +1,28 @@
1
+ import { expect } from "vitest";
2
+
3
+ /**
4
+ * Assert that an MCP tool response's `data` field is deeply equal
5
+ * to the operation result that CLI would produce.
6
+ *
7
+ * Unwraps the MCP response envelope and deep-compares `data` against
8
+ * the raw operation result. Fails with a clear diff on mismatch.
9
+ *
10
+ * @param operationResult - The raw result from calling the shared operation.
11
+ * @param mcpResponse - The raw MCP `CallToolResult` from `client.callTool()`.
12
+ * @throws When the envelope is not `ok: true` or `data` does not match.
13
+ */
14
+ export default function assertParity(
15
+ operationResult: unknown,
16
+ mcpResponse: Record<string, unknown>,
17
+ ): void {
18
+ const content = mcpResponse.content as unknown[];
19
+ const first = content[0] as { type: string; text: string };
20
+ expect(first.type).toBe("text");
21
+
22
+ const envelope = JSON.parse(first.text) as {
23
+ ok: boolean;
24
+ data?: unknown;
25
+ };
26
+ expect(envelope.ok).toBe(true);
27
+ expect(envelope.data).toEqual(operationResult);
28
+ }
@@ -0,0 +1,40 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { InMemoryTransport } from "@modelcontextprotocol/sdk/inMemory.js";
3
+ import type { PragmaRuntime } from "../../domains/shared/runtime.js";
4
+ import { createMcpServerFromRuntime } from "../../mcp/createMcpServer.js";
5
+ import type { TestMcpClientResult } from "../types.js";
6
+
7
+ /**
8
+ * Create an in-process MCP client connected to a server backed by
9
+ * the given runtime.
10
+ *
11
+ * Uses `createMcpServerFromRuntime` and the MCP SDK's in-memory
12
+ * transport. No network, no stdio. The caller owns the runtime
13
+ * lifecycle and must call `cleanup` when done.
14
+ *
15
+ * @param runtime - An already-booted pragma runtime.
16
+ * @returns The connected client and a cleanup function.
17
+ *
18
+ * @note Impure
19
+ */
20
+ export default async function createTestMcpClient(
21
+ runtime: PragmaRuntime,
22
+ ): Promise<TestMcpClientResult> {
23
+ const { server } = createMcpServerFromRuntime(runtime);
24
+
25
+ const [serverTransport, clientTransport] =
26
+ InMemoryTransport.createLinkedPair();
27
+
28
+ const client = new Client({ name: "pragma-test-client", version: "0.0.0" });
29
+
30
+ await server.connect(serverTransport);
31
+ await client.connect(clientTransport);
32
+
33
+ return {
34
+ client,
35
+ cleanup: async () => {
36
+ await client.close();
37
+ await server.close();
38
+ },
39
+ };
40
+ }
@@ -0,0 +1,67 @@
1
+ import { copyFileSync, mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import type { PragmaRuntime } from "../../domains/shared/runtime.js";
5
+ import { bootPragma } from "../../domains/shared/runtime.js";
6
+
7
+ const FIXTURES_DIR = new URL("../fixtures/", import.meta.url).pathname;
8
+ const CANONICAL_TTL = join(FIXTURES_DIR, "canonical.ttl");
9
+
10
+ type ConfigName = "canonical-config.json" | "filtered-config.json";
11
+
12
+ /**
13
+ * Create a PragmaRuntime backed by the canonical test fixture.
14
+ *
15
+ * Stages the selected config as `pragma.config.json` in a temp directory
16
+ * and calls the real `bootPragma()` with a sources override pointing at
17
+ * `testing/fixtures/canonical.ttl`. No mocks. Each call creates an
18
+ * independent runtime. The caller owns disposal.
19
+ *
20
+ * @param options - Optional configuration overrides.
21
+ * @param options.config - Config file name within the fixtures directory.
22
+ * Defaults to `"canonical-config.json"` (tier=global, channel=normal).
23
+ * Use `"filtered-config.json"` for tier-filtering tests (apps/lxd).
24
+ * @returns A fully booted PragmaRuntime whose `dispose` also cleans up
25
+ * the temporary directory.
26
+ *
27
+ * @example
28
+ * const rt = await createTestRuntime();
29
+ * const blocks = await listBlocks(rt.store, rt.config);
30
+ * expect(blocks.some((c) => c.name === "Button")).toBe(true);
31
+ * rt.dispose();
32
+ *
33
+ * @example
34
+ * const rt = await createTestRuntime({ config: "filtered-config.json" });
35
+ * expect(rt.config.tier).toBe("apps/lxd");
36
+ * rt.dispose();
37
+ *
38
+ * @note Impure
39
+ */
40
+ export default async function createTestRuntime(options?: {
41
+ config?: ConfigName;
42
+ }): Promise<PragmaRuntime> {
43
+ const configFile = options?.config ?? "canonical-config.json";
44
+
45
+ // Stage a temp directory with pragma.config.json so bootPragma's
46
+ // readConfig() finds it via the real config lookup path.
47
+ const tmpDir = mkdtempSync(join(tmpdir(), "pragma-test-"));
48
+ copyFileSync(
49
+ join(FIXTURES_DIR, configFile),
50
+ join(tmpDir, "pragma.config.json"),
51
+ );
52
+
53
+ const runtime = await bootPragma({
54
+ cwd: tmpDir,
55
+ sources: [CANONICAL_TTL],
56
+ });
57
+
58
+ // Wrap dispose to also clean up the temp directory.
59
+ const originalDispose = runtime.dispose.bind(runtime);
60
+ return {
61
+ ...runtime,
62
+ dispose: () => {
63
+ originalDispose();
64
+ rmSync(tmpDir, { recursive: true, force: true });
65
+ },
66
+ };
67
+ }
@@ -0,0 +1,8 @@
1
+ /** @module Test infrastructure: CLI subprocess runner, MCP test client, fixtures, and test store factory. */
2
+ export type { CommandResult } from "./cli.js";
3
+ export { runCommand } from "./cli.js";
4
+ export { default as createTestMcpClient } from "./createTestMcpClient.js";
5
+ export { DS_ALL_TTL, DS_ONTOLOGY_TTL, DS_TIERS_TTL } from "./dsFixtures.js";
6
+ export type { PragmaTestStoreOptions } from "./store.js";
7
+ export { createTestStore } from "./store.js";
8
+ export type { TestMcpClientResult } from "./types.js";