@canonical/pragma-cli 0.34.0 → 0.35.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 (798) hide show
  1. package/README.md +153 -30
  2. package/dist/.build-ok +0 -0
  3. package/dist/package.json +83 -0
  4. package/dist/pragma.conf.js +814 -0
  5. package/dist/pragma.conf.js.map +1 -0
  6. package/dist/src/bin.js +356 -0
  7. package/dist/src/bin.js.map +1 -0
  8. package/dist/src/capabilities/capabilities/capabilities.render.js +70 -0
  9. package/dist/src/capabilities/capabilities/capabilities.render.js.map +1 -0
  10. package/dist/src/capabilities/capabilities/capabilities.verb.js +59 -0
  11. package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -0
  12. package/dist/src/capabilities/capabilities/catalog.js +130 -0
  13. package/dist/src/capabilities/capabilities/catalog.js.map +1 -0
  14. package/dist/src/capabilities/capabilities/hints.js +195 -0
  15. package/dist/src/capabilities/capabilities/hints.js.map +1 -0
  16. package/dist/src/capabilities/capabilities/index.js +11 -0
  17. package/dist/src/capabilities/capabilities/index.js.map +1 -0
  18. package/dist/src/capabilities/capabilities/types.js +11 -0
  19. package/dist/src/capabilities/capabilities/types.js.map +1 -0
  20. package/dist/src/capabilities/colophon/collectColophon.js +83 -0
  21. package/dist/src/capabilities/colophon/collectColophon.js.map +1 -0
  22. package/dist/src/capabilities/colophon/colophon.render.js +59 -0
  23. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -0
  24. package/dist/src/capabilities/colophon/colophon.verb.js +43 -0
  25. package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -0
  26. package/dist/src/capabilities/colophon/index.js +5 -0
  27. package/dist/src/capabilities/colophon/index.js.map +1 -0
  28. package/dist/src/capabilities/colophon/markdownTerminal.js +90 -0
  29. package/dist/src/capabilities/colophon/markdownTerminal.js.map +1 -0
  30. package/dist/src/capabilities/colophon/types.js +10 -0
  31. package/dist/src/capabilities/colophon/types.js.map +1 -0
  32. package/dist/src/capabilities/config/collectConfigShow.js +59 -0
  33. package/dist/src/capabilities/config/collectConfigShow.js.map +1 -0
  34. package/dist/src/capabilities/config/field.render.js +22 -0
  35. package/dist/src/capabilities/config/field.render.js.map +1 -0
  36. package/dist/src/capabilities/config/fields.js +46 -0
  37. package/dist/src/capabilities/config/fields.js.map +1 -0
  38. package/dist/src/capabilities/config/get.verb.js +61 -0
  39. package/dist/src/capabilities/config/get.verb.js.map +1 -0
  40. package/dist/src/capabilities/config/index.js +5 -0
  41. package/dist/src/capabilities/config/index.js.map +1 -0
  42. package/dist/src/capabilities/config/runField.js +59 -0
  43. package/dist/src/capabilities/config/runField.js.map +1 -0
  44. package/dist/src/capabilities/config/runGet.js +28 -0
  45. package/dist/src/capabilities/config/runGet.js.map +1 -0
  46. package/dist/src/capabilities/config/runSet.js +53 -0
  47. package/dist/src/capabilities/config/runSet.js.map +1 -0
  48. package/dist/src/capabilities/config/set.verb.js +66 -0
  49. package/dist/src/capabilities/config/set.verb.js.map +1 -0
  50. package/dist/src/capabilities/config/show.render.js +84 -0
  51. package/dist/src/capabilities/config/show.render.js.map +1 -0
  52. package/dist/src/capabilities/config/show.verb.js +44 -0
  53. package/dist/src/capabilities/config/show.verb.js.map +1 -0
  54. package/dist/src/capabilities/config/types.js +5 -0
  55. package/dist/src/capabilities/config/types.js.map +1 -0
  56. package/dist/src/capabilities/config/unset.verb.js +49 -0
  57. package/dist/src/capabilities/config/unset.verb.js.map +1 -0
  58. package/dist/src/capabilities/create/cliProjection.js +195 -0
  59. package/dist/src/capabilities/create/cliProjection.js.map +1 -0
  60. package/dist/src/capabilities/create/constants.js +47 -0
  61. package/dist/src/capabilities/create/constants.js.map +1 -0
  62. package/dist/src/capabilities/create/create.render.js +100 -0
  63. package/dist/src/capabilities/create/create.render.js.map +1 -0
  64. package/dist/src/capabilities/create/create.verb.js +438 -0
  65. package/dist/src/capabilities/create/create.verb.js.map +1 -0
  66. package/dist/src/capabilities/create/createHelp.js +47 -0
  67. package/dist/src/capabilities/create/createHelp.js.map +1 -0
  68. package/dist/src/capabilities/create/createSurface.generated.js +394 -0
  69. package/dist/src/capabilities/create/createSurface.generated.js.map +1 -0
  70. package/dist/src/capabilities/create/generatorToVerbSpec.js +106 -0
  71. package/dist/src/capabilities/create/generatorToVerbSpec.js.map +1 -0
  72. package/dist/src/capabilities/create/index.js +18 -0
  73. package/dist/src/capabilities/create/index.js.map +1 -0
  74. package/dist/src/capabilities/create/messages.js +16 -0
  75. package/dist/src/capabilities/create/messages.js.map +1 -0
  76. package/dist/src/capabilities/create/mount.js +293 -0
  77. package/dist/src/capabilities/create/mount.js.map +1 -0
  78. package/dist/src/capabilities/create/pathJail.js +65 -0
  79. package/dist/src/capabilities/create/pathJail.js.map +1 -0
  80. package/dist/src/capabilities/create/pickGenerator.js +53 -0
  81. package/dist/src/capabilities/create/pickGenerator.js.map +1 -0
  82. package/dist/src/capabilities/create/types.js +2 -0
  83. package/dist/src/capabilities/create/types.js.map +1 -0
  84. package/dist/src/capabilities/distribution.js +40 -0
  85. package/dist/src/capabilities/distribution.js.map +1 -0
  86. package/dist/src/capabilities/doctor/checks/checkKeStore.js +40 -0
  87. package/dist/src/capabilities/doctor/checks/checkKeStore.js.map +1 -0
  88. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +21 -0
  89. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -0
  90. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +92 -0
  91. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -0
  92. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js +19 -0
  93. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js.map +1 -0
  94. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +199 -0
  95. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -0
  96. package/dist/src/capabilities/doctor/checks/index.js +27 -0
  97. package/dist/src/capabilities/doctor/checks/index.js.map +1 -0
  98. package/dist/src/capabilities/doctor/checks/mcpCommand.js +57 -0
  99. package/dist/src/capabilities/doctor/checks/mcpCommand.js.map +1 -0
  100. package/dist/src/capabilities/doctor/checks/targetHealth.js +205 -0
  101. package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -0
  102. package/dist/src/capabilities/doctor/doctor.render.js +185 -0
  103. package/dist/src/capabilities/doctor/doctor.render.js.map +1 -0
  104. package/dist/src/capabilities/doctor/doctor.verb.js +45 -0
  105. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -0
  106. package/dist/src/capabilities/doctor/index.js +5 -0
  107. package/dist/src/capabilities/doctor/index.js.map +1 -0
  108. package/dist/src/capabilities/doctor/runChecks.js +83 -0
  109. package/dist/src/capabilities/doctor/runChecks.js.map +1 -0
  110. package/dist/src/capabilities/doctor/types.js +5 -0
  111. package/dist/src/capabilities/doctor/types.js.map +1 -0
  112. package/dist/src/capabilities/graph/index.js +19 -0
  113. package/dist/src/capabilities/graph/index.js.map +1 -0
  114. package/dist/src/capabilities/graph/inspect.render.js +76 -0
  115. package/dist/src/capabilities/graph/inspect.render.js.map +1 -0
  116. package/dist/src/capabilities/graph/inspect.verb.js +53 -0
  117. package/dist/src/capabilities/graph/inspect.verb.js.map +1 -0
  118. package/dist/src/capabilities/graph/query.render.js +73 -0
  119. package/dist/src/capabilities/graph/query.render.js.map +1 -0
  120. package/dist/src/capabilities/graph/query.verb.js +49 -0
  121. package/dist/src/capabilities/graph/query.verb.js.map +1 -0
  122. package/dist/src/capabilities/graph/runQuery.js +41 -0
  123. package/dist/src/capabilities/graph/runQuery.js.map +1 -0
  124. package/dist/src/capabilities/index.js +56 -0
  125. package/dist/src/capabilities/index.js.map +1 -0
  126. package/dist/src/capabilities/info/collectInfo.js +66 -0
  127. package/dist/src/capabilities/info/collectInfo.js.map +1 -0
  128. package/dist/src/capabilities/info/index.js +5 -0
  129. package/dist/src/capabilities/info/index.js.map +1 -0
  130. package/dist/src/capabilities/info/info.render.js +53 -0
  131. package/dist/src/capabilities/info/info.render.js.map +1 -0
  132. package/dist/src/capabilities/info/info.verb.js +42 -0
  133. package/dist/src/capabilities/info/info.verb.js.map +1 -0
  134. package/dist/src/capabilities/info/types.js +5 -0
  135. package/dist/src/capabilities/info/types.js.map +1 -0
  136. package/dist/src/capabilities/meta/complete.verb.js +43 -0
  137. package/dist/src/capabilities/meta/complete.verb.js.map +1 -0
  138. package/dist/src/capabilities/meta/index.js +13 -0
  139. package/dist/src/capabilities/meta/index.js.map +1 -0
  140. package/dist/src/capabilities/meta/mcp.verb.js +34 -0
  141. package/dist/src/capabilities/meta/mcp.verb.js.map +1 -0
  142. package/dist/src/capabilities/ontology/index.js +21 -0
  143. package/dist/src/capabilities/ontology/index.js.map +1 -0
  144. package/dist/src/capabilities/ontology/queries.js +123 -0
  145. package/dist/src/capabilities/ontology/queries.js.map +1 -0
  146. package/dist/src/capabilities/ontology/render.js +66 -0
  147. package/dist/src/capabilities/ontology/render.js.map +1 -0
  148. package/dist/src/capabilities/ontology/verbs.js +181 -0
  149. package/dist/src/capabilities/ontology/verbs.js.map +1 -0
  150. package/dist/src/capabilities/prompt/index.js +16 -0
  151. package/dist/src/capabilities/prompt/index.js.map +1 -0
  152. package/dist/src/capabilities/prompt/prompt.render.js +78 -0
  153. package/dist/src/capabilities/prompt/prompt.render.js.map +1 -0
  154. package/dist/src/capabilities/prompt/types.js +10 -0
  155. package/dist/src/capabilities/prompt/types.js.map +1 -0
  156. package/dist/src/capabilities/prompt/verbs.js +93 -0
  157. package/dist/src/capabilities/prompt/verbs.js.map +1 -0
  158. package/dist/src/capabilities/resources/index.js +10 -0
  159. package/dist/src/capabilities/resources/index.js.map +1 -0
  160. package/dist/src/capabilities/resources/provider.js +423 -0
  161. package/dist/src/capabilities/resources/provider.js.map +1 -0
  162. package/dist/src/capabilities/setup/buildPlan.js +168 -0
  163. package/dist/src/capabilities/setup/buildPlan.js.map +1 -0
  164. package/dist/src/capabilities/setup/index.js +5 -0
  165. package/dist/src/capabilities/setup/index.js.map +1 -0
  166. package/dist/src/capabilities/setup/mode.js +53 -0
  167. package/dist/src/capabilities/setup/mode.js.map +1 -0
  168. package/dist/src/capabilities/setup/operations/index.js +39 -0
  169. package/dist/src/capabilities/setup/operations/index.js.map +1 -0
  170. package/dist/src/capabilities/setup/operations/setupCompletions.js +160 -0
  171. package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -0
  172. package/dist/src/capabilities/setup/operations/setupConfig.js +101 -0
  173. package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -0
  174. package/dist/src/capabilities/setup/operations/setupGenerator.js +343 -0
  175. package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -0
  176. package/dist/src/capabilities/setup/operations/setupLsp.js +277 -0
  177. package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -0
  178. package/dist/src/capabilities/setup/operations/setupMcp.js +207 -0
  179. package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -0
  180. package/dist/src/capabilities/setup/operations/setupSkills.js +316 -0
  181. package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -0
  182. package/dist/src/capabilities/setup/plan.js +128 -0
  183. package/dist/src/capabilities/setup/plan.js.map +1 -0
  184. package/dist/src/capabilities/setup/plan.render.js +193 -0
  185. package/dist/src/capabilities/setup/plan.render.js.map +1 -0
  186. package/dist/src/capabilities/setup/setup.render.js +54 -0
  187. package/dist/src/capabilities/setup/setup.render.js.map +1 -0
  188. package/dist/src/capabilities/setup/setup.verb.js +334 -0
  189. package/dist/src/capabilities/setup/setup.verb.js.map +1 -0
  190. package/dist/src/capabilities/setup/shell.js +196 -0
  191. package/dist/src/capabilities/setup/shell.js.map +1 -0
  192. package/dist/src/capabilities/setup/targets.js +263 -0
  193. package/dist/src/capabilities/setup/targets.js.map +1 -0
  194. package/dist/src/capabilities/setup/types.js +5 -0
  195. package/dist/src/capabilities/setup/types.js.map +1 -0
  196. package/dist/src/capabilities/shared/assertExecOk.js +137 -0
  197. package/dist/src/capabilities/shared/assertExecOk.js.map +1 -0
  198. package/dist/src/capabilities/shared/bands.js +16 -0
  199. package/dist/src/capabilities/shared/bands.js.map +1 -0
  200. package/dist/src/capabilities/shared/index.js +26 -0
  201. package/dist/src/capabilities/shared/index.js.map +1 -0
  202. package/dist/src/capabilities/shared/packageManager.js +103 -0
  203. package/dist/src/capabilities/shared/packageManager.js.map +1 -0
  204. package/dist/src/capabilities/shared/registry.js +55 -0
  205. package/dist/src/capabilities/shared/registry.js.map +1 -0
  206. package/dist/src/capabilities/skill/discover.js +195 -0
  207. package/dist/src/capabilities/skill/discover.js.map +1 -0
  208. package/dist/src/capabilities/skill/index.js +10 -0
  209. package/dist/src/capabilities/skill/index.js.map +1 -0
  210. package/dist/src/capabilities/skill/render.js +49 -0
  211. package/dist/src/capabilities/skill/render.js.map +1 -0
  212. package/dist/src/capabilities/skill/verbs.js +83 -0
  213. package/dist/src/capabilities/skill/verbs.js.map +1 -0
  214. package/dist/src/capabilities/sources/collectStatus.js +103 -0
  215. package/dist/src/capabilities/sources/collectStatus.js.map +1 -0
  216. package/dist/src/capabilities/sources/index.js +13 -0
  217. package/dist/src/capabilities/sources/index.js.map +1 -0
  218. package/dist/src/capabilities/sources/installSkills.js +167 -0
  219. package/dist/src/capabilities/sources/installSkills.js.map +1 -0
  220. package/dist/src/capabilities/sources/runUpdate.js +394 -0
  221. package/dist/src/capabilities/sources/runUpdate.js.map +1 -0
  222. package/dist/src/capabilities/sources/status.render.js +64 -0
  223. package/dist/src/capabilities/sources/status.render.js.map +1 -0
  224. package/dist/src/capabilities/sources/status.verb.js +40 -0
  225. package/dist/src/capabilities/sources/status.verb.js.map +1 -0
  226. package/dist/src/capabilities/sources/types.js +6 -0
  227. package/dist/src/capabilities/sources/types.js.map +1 -0
  228. package/dist/src/capabilities/sources/update.render.js +34 -0
  229. package/dist/src/capabilities/sources/update.render.js.map +1 -0
  230. package/dist/src/capabilities/sources/update.verb.js +55 -0
  231. package/dist/src/capabilities/sources/update.verb.js.map +1 -0
  232. package/dist/src/capabilities/upgrade/index.js +5 -0
  233. package/dist/src/capabilities/upgrade/index.js.map +1 -0
  234. package/dist/src/capabilities/upgrade/runUpgrade.js +99 -0
  235. package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -0
  236. package/dist/src/capabilities/upgrade/types.js +5 -0
  237. package/dist/src/capabilities/upgrade/types.js.map +1 -0
  238. package/dist/src/capabilities/upgrade/upgrade.render.js +44 -0
  239. package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -0
  240. package/dist/src/capabilities/upgrade/upgrade.verb.js +52 -0
  241. package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -0
  242. package/dist/src/capabilities/version/index.js +10 -0
  243. package/dist/src/capabilities/version/index.js.map +1 -0
  244. package/dist/src/capabilities/version/version.verb.js +36 -0
  245. package/dist/src/capabilities/version/version.verb.js.map +1 -0
  246. package/dist/src/constants.js +82 -0
  247. package/dist/src/constants.js.map +1 -0
  248. package/dist/src/index.js +12 -0
  249. package/dist/src/index.js.map +1 -0
  250. package/dist/src/kernel/completion/complete.js +66 -0
  251. package/dist/src/kernel/completion/complete.js.map +1 -0
  252. package/dist/src/kernel/completion/emitScripts.js +92 -0
  253. package/dist/src/kernel/completion/emitScripts.js.map +1 -0
  254. package/dist/src/kernel/completion/entitySource.js +285 -0
  255. package/dist/src/kernel/completion/entitySource.js.map +1 -0
  256. package/dist/src/kernel/completion/index.js +14 -0
  257. package/dist/src/kernel/completion/index.js.map +1 -0
  258. package/dist/src/kernel/completion/model.js +301 -0
  259. package/dist/src/kernel/completion/model.js.map +1 -0
  260. package/dist/src/kernel/completion/parse.js +253 -0
  261. package/dist/src/kernel/completion/parse.js.map +1 -0
  262. package/dist/src/kernel/completion/rank.js +101 -0
  263. package/dist/src/kernel/completion/rank.js.map +1 -0
  264. package/dist/src/kernel/completion/resolve.js +100 -0
  265. package/dist/src/kernel/completion/resolve.js.map +1 -0
  266. package/dist/src/kernel/completion/templates/bash.js +209 -0
  267. package/dist/src/kernel/completion/templates/bash.js.map +1 -0
  268. package/dist/src/kernel/completion/templates/fish.js +214 -0
  269. package/dist/src/kernel/completion/templates/fish.js.map +1 -0
  270. package/dist/src/kernel/completion/templates/index.js +23 -0
  271. package/dist/src/kernel/completion/templates/index.js.map +1 -0
  272. package/dist/src/kernel/completion/templates/shared.js +98 -0
  273. package/dist/src/kernel/completion/templates/shared.js.map +1 -0
  274. package/dist/src/kernel/completion/templates/zsh.js +201 -0
  275. package/dist/src/kernel/completion/templates/zsh.js.map +1 -0
  276. package/dist/src/kernel/completion/types.js +13 -0
  277. package/dist/src/kernel/completion/types.js.map +1 -0
  278. package/dist/src/kernel/config/defaults.js +17 -0
  279. package/dist/src/kernel/config/defaults.js.map +1 -0
  280. package/dist/src/kernel/config/evaluateProjectConfig.js +126 -0
  281. package/dist/src/kernel/config/evaluateProjectConfig.js.map +1 -0
  282. package/dist/src/kernel/config/findProjectConfig.js +43 -0
  283. package/dist/src/kernel/config/findProjectConfig.js.map +1 -0
  284. package/dist/src/kernel/config/firstRun.js +34 -0
  285. package/dist/src/kernel/config/firstRun.js.map +1 -0
  286. package/dist/src/kernel/config/globalConfig.js +79 -0
  287. package/dist/src/kernel/config/globalConfig.js.map +1 -0
  288. package/dist/src/kernel/config/index.js +16 -0
  289. package/dist/src/kernel/config/index.js.map +1 -0
  290. package/dist/src/kernel/config/paths.js +35 -0
  291. package/dist/src/kernel/config/paths.js.map +1 -0
  292. package/dist/src/kernel/config/readConfig.js +78 -0
  293. package/dist/src/kernel/config/readConfig.js.map +1 -0
  294. package/dist/src/kernel/config/schema.js +130 -0
  295. package/dist/src/kernel/config/schema.js.map +1 -0
  296. package/dist/src/kernel/config/types.js +19 -0
  297. package/dist/src/kernel/config/types.js.map +1 -0
  298. package/dist/src/kernel/config/writeConfigField.js +59 -0
  299. package/dist/src/kernel/config/writeConfigField.js.map +1 -0
  300. package/dist/src/kernel/copy.js +43 -0
  301. package/dist/src/kernel/copy.js.map +1 -0
  302. package/dist/src/kernel/error/PragmaError.js +149 -0
  303. package/dist/src/kernel/error/PragmaError.js.map +1 -0
  304. package/dist/src/kernel/error/constants.js +40 -0
  305. package/dist/src/kernel/error/constants.js.map +1 -0
  306. package/dist/src/kernel/error/fromTaskError.js +96 -0
  307. package/dist/src/kernel/error/fromTaskError.js.map +1 -0
  308. package/dist/src/kernel/error/index.js +13 -0
  309. package/dist/src/kernel/error/index.js.map +1 -0
  310. package/dist/src/kernel/error/recovery.js +52 -0
  311. package/dist/src/kernel/error/recovery.js.map +1 -0
  312. package/dist/src/kernel/error/renderError.js +115 -0
  313. package/dist/src/kernel/error/renderError.js.map +1 -0
  314. package/dist/src/kernel/error/serialize.js +25 -0
  315. package/dist/src/kernel/error/serialize.js.map +1 -0
  316. package/dist/src/kernel/error/types.js +9 -0
  317. package/dist/src/kernel/error/types.js.map +1 -0
  318. package/dist/src/kernel/index.js +25 -0
  319. package/dist/src/kernel/index.js.map +1 -0
  320. package/dist/src/kernel/packs/collect.js +187 -0
  321. package/dist/src/kernel/packs/collect.js.map +1 -0
  322. package/dist/src/kernel/packs/compile.js +304 -0
  323. package/dist/src/kernel/packs/compile.js.map +1 -0
  324. package/dist/src/kernel/packs/disclosure.js +76 -0
  325. package/dist/src/kernel/packs/disclosure.js.map +1 -0
  326. package/dist/src/kernel/packs/glob.js +38 -0
  327. package/dist/src/kernel/packs/glob.js.map +1 -0
  328. package/dist/src/kernel/packs/graphql/buildLookupDocument.js +258 -0
  329. package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -0
  330. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +157 -0
  331. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -0
  332. package/dist/src/kernel/packs/graphql/index.js +20 -0
  333. package/dist/src/kernel/packs/graphql/index.js.map +1 -0
  334. package/dist/src/kernel/packs/graphql/nameMap.js +63 -0
  335. package/dist/src/kernel/packs/graphql/nameMap.js.map +1 -0
  336. package/dist/src/kernel/packs/index.js +34 -0
  337. package/dist/src/kernel/packs/index.js.map +1 -0
  338. package/dist/src/kernel/packs/iri.js +110 -0
  339. package/dist/src/kernel/packs/iri.js.map +1 -0
  340. package/dist/src/kernel/packs/renderPack.js +129 -0
  341. package/dist/src/kernel/packs/renderPack.js.map +1 -0
  342. package/dist/src/kernel/packs/resolveEntity.js +223 -0
  343. package/dist/src/kernel/packs/resolveEntity.js.map +1 -0
  344. package/dist/src/kernel/packs/runBodies.js +87 -0
  345. package/dist/src/kernel/packs/runBodies.js.map +1 -0
  346. package/dist/src/kernel/packs/sample.js +56 -0
  347. package/dist/src/kernel/packs/sample.js.map +1 -0
  348. package/dist/src/kernel/packs/schema.js +369 -0
  349. package/dist/src/kernel/packs/schema.js.map +1 -0
  350. package/dist/src/kernel/packs/sparql/applyFilters.js +68 -0
  351. package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -0
  352. package/dist/src/kernel/packs/sparql/applySearch.js +25 -0
  353. package/dist/src/kernel/packs/sparql/applySearch.js.map +1 -0
  354. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +217 -0
  355. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -0
  356. package/dist/src/kernel/packs/sparql/escape.js +21 -0
  357. package/dist/src/kernel/packs/sparql/escape.js.map +1 -0
  358. package/dist/src/kernel/packs/sparql/index.js +31 -0
  359. package/dist/src/kernel/packs/sparql/index.js.map +1 -0
  360. package/dist/src/kernel/packs/sparql/runSelect.js +101 -0
  361. package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -0
  362. package/dist/src/kernel/packs/types.js +30 -0
  363. package/dist/src/kernel/packs/types.js.map +1 -0
  364. package/dist/src/kernel/packs/uniqueness.js +30 -0
  365. package/dist/src/kernel/packs/uniqueness.js.map +1 -0
  366. package/dist/src/kernel/project/cli/buildProgram.js +263 -0
  367. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -0
  368. package/dist/src/kernel/project/cli/constants.js +27 -0
  369. package/dist/src/kernel/project/cli/constants.js.map +1 -0
  370. package/dist/src/kernel/project/cli/dispatch.js +420 -0
  371. package/dist/src/kernel/project/cli/dispatch.js.map +1 -0
  372. package/dist/src/kernel/project/cli/exitCodes.js +66 -0
  373. package/dist/src/kernel/project/cli/exitCodes.js.map +1 -0
  374. package/dist/src/kernel/project/cli/globalFlags.js +216 -0
  375. package/dist/src/kernel/project/cli/globalFlags.js.map +1 -0
  376. package/dist/src/kernel/project/cli/helpFormat.js +59 -0
  377. package/dist/src/kernel/project/cli/helpFormat.js.map +1 -0
  378. package/dist/src/kernel/project/cli/index.js +14 -0
  379. package/dist/src/kernel/project/cli/index.js.map +1 -0
  380. package/dist/src/kernel/project/cli/rootHelp.js +197 -0
  381. package/dist/src/kernel/project/cli/rootHelp.js.map +1 -0
  382. package/dist/src/kernel/project/cli/suggest.js +75 -0
  383. package/dist/src/kernel/project/cli/suggest.js.map +1 -0
  384. package/dist/src/kernel/project/cli/suggestNames.js +96 -0
  385. package/dist/src/kernel/project/cli/suggestNames.js.map +1 -0
  386. package/dist/src/kernel/project/cli/verbHelp.js +131 -0
  387. package/dist/src/kernel/project/cli/verbHelp.js.map +1 -0
  388. package/dist/src/kernel/project/mcp/buildServer.js +67 -0
  389. package/dist/src/kernel/project/mcp/buildServer.js.map +1 -0
  390. package/dist/src/kernel/project/mcp/envelope.js +37 -0
  391. package/dist/src/kernel/project/mcp/envelope.js.map +1 -0
  392. package/dist/src/kernel/project/mcp/index.js +8 -0
  393. package/dist/src/kernel/project/mcp/index.js.map +1 -0
  394. package/dist/src/kernel/project/mcp/instructions.js +44 -0
  395. package/dist/src/kernel/project/mcp/instructions.js.map +1 -0
  396. package/dist/src/kernel/project/mcp/mcpError.js +42 -0
  397. package/dist/src/kernel/project/mcp/mcpError.js.map +1 -0
  398. package/dist/src/kernel/project/mcp/prompts/index.js +36 -0
  399. package/dist/src/kernel/project/mcp/prompts/index.js.map +1 -0
  400. package/dist/src/kernel/project/mcp/prompts/provider.js +98 -0
  401. package/dist/src/kernel/project/mcp/prompts/provider.js.map +1 -0
  402. package/dist/src/kernel/project/mcp/prompts/source.js +154 -0
  403. package/dist/src/kernel/project/mcp/prompts/source.js.map +1 -0
  404. package/dist/src/kernel/project/mcp/registerVerb.js +300 -0
  405. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -0
  406. package/dist/src/kernel/project/mcp/serve.js +35 -0
  407. package/dist/src/kernel/project/mcp/serve.js.map +1 -0
  408. package/dist/src/kernel/render/compactUri.js +24 -0
  409. package/dist/src/kernel/render/compactUri.js.map +1 -0
  410. package/dist/src/kernel/render/contracts.js +10 -0
  411. package/dist/src/kernel/render/contracts.js.map +1 -0
  412. package/dist/src/kernel/render/disclosure.js +34 -0
  413. package/dist/src/kernel/render/disclosure.js.map +1 -0
  414. package/dist/src/kernel/render/envelope.js +30 -0
  415. package/dist/src/kernel/render/envelope.js.map +1 -0
  416. package/dist/src/kernel/render/formatters.js +27 -0
  417. package/dist/src/kernel/render/formatters.js.map +1 -0
  418. package/dist/src/kernel/render/index.js +15 -0
  419. package/dist/src/kernel/render/index.js.map +1 -0
  420. package/dist/src/kernel/render/prefixes.js +46 -0
  421. package/dist/src/kernel/render/prefixes.js.map +1 -0
  422. package/dist/src/kernel/render/renderers.js +468 -0
  423. package/dist/src/kernel/render/renderers.js.map +1 -0
  424. package/dist/src/kernel/render/style.js +85 -0
  425. package/dist/src/kernel/render/style.js.map +1 -0
  426. package/dist/src/kernel/render/turtle.js +194 -0
  427. package/dist/src/kernel/render/turtle.js.map +1 -0
  428. package/dist/src/kernel/render/writeStdout.js +43 -0
  429. package/dist/src/kernel/render/writeStdout.js.map +1 -0
  430. package/dist/src/kernel/runtime/boot.js +49 -0
  431. package/dist/src/kernel/runtime/boot.js.map +1 -0
  432. package/dist/src/kernel/runtime/facade.js +39 -0
  433. package/dist/src/kernel/runtime/facade.js.map +1 -0
  434. package/dist/src/kernel/runtime/graphpack/build.js +122 -0
  435. package/dist/src/kernel/runtime/graphpack/build.js.map +1 -0
  436. package/dist/src/kernel/runtime/graphpack/buildIndex.js +303 -0
  437. package/dist/src/kernel/runtime/graphpack/buildIndex.js.map +1 -0
  438. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +6 -0
  439. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -0
  440. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +4 -0
  441. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -0
  442. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js +4 -0
  443. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js.map +1 -0
  444. package/dist/src/kernel/runtime/graphpack/embedded.js +82 -0
  445. package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -0
  446. package/dist/src/kernel/runtime/graphpack/hash.js +38 -0
  447. package/dist/src/kernel/runtime/graphpack/hash.js.map +1 -0
  448. package/dist/src/kernel/runtime/graphpack/index.js +11 -0
  449. package/dist/src/kernel/runtime/graphpack/index.js.map +1 -0
  450. package/dist/src/kernel/runtime/graphpack/manifest.js +145 -0
  451. package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -0
  452. package/dist/src/kernel/runtime/graphpack/read.js +92 -0
  453. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -0
  454. package/dist/src/kernel/runtime/graphpack/schemas.js +70 -0
  455. package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -0
  456. package/dist/src/kernel/runtime/graphpack/stories.js +68 -0
  457. package/dist/src/kernel/runtime/graphpack/stories.js.map +1 -0
  458. package/dist/src/kernel/runtime/graphpack/types.js +55 -0
  459. package/dist/src/kernel/runtime/graphpack/types.js.map +1 -0
  460. package/dist/src/kernel/runtime/index.js +8 -0
  461. package/dist/src/kernel/runtime/index.js.map +1 -0
  462. package/dist/src/kernel/runtime/loadSession.js +34 -0
  463. package/dist/src/kernel/runtime/loadSession.js.map +1 -0
  464. package/dist/src/kernel/runtime/paths.js +78 -0
  465. package/dist/src/kernel/runtime/paths.js.map +1 -0
  466. package/dist/src/kernel/runtime/probe.js +37 -0
  467. package/dist/src/kernel/runtime/probe.js.map +1 -0
  468. package/dist/src/kernel/runtime/readEntity.js +363 -0
  469. package/dist/src/kernel/runtime/readEntity.js.map +1 -0
  470. package/dist/src/kernel/runtime/refs/gitOps.js +65 -0
  471. package/dist/src/kernel/runtime/refs/gitOps.js.map +1 -0
  472. package/dist/src/kernel/runtime/refs/index.js +29 -0
  473. package/dist/src/kernel/runtime/refs/index.js.map +1 -0
  474. package/dist/src/kernel/runtime/refs/parseRef.js +70 -0
  475. package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -0
  476. package/dist/src/kernel/runtime/refs/resolve.js +332 -0
  477. package/dist/src/kernel/runtime/refs/resolve.js.map +1 -0
  478. package/dist/src/kernel/runtime/resolveSources.js +62 -0
  479. package/dist/src/kernel/runtime/resolveSources.js.map +1 -0
  480. package/dist/src/kernel/runtime/store.js +75 -0
  481. package/dist/src/kernel/runtime/store.js.map +1 -0
  482. package/dist/src/kernel/runtime/storeReadiness.js +51 -0
  483. package/dist/src/kernel/runtime/storeReadiness.js.map +1 -0
  484. package/dist/src/kernel/runtime/types.js +11 -0
  485. package/dist/src/kernel/runtime/types.js.map +1 -0
  486. package/dist/src/kernel/spec/asVerb.js +21 -0
  487. package/dist/src/kernel/spec/asVerb.js.map +1 -0
  488. package/dist/src/kernel/spec/emitReference.js +578 -0
  489. package/dist/src/kernel/spec/emitReference.js.map +1 -0
  490. package/dist/src/kernel/spec/emitSurface.js +202 -0
  491. package/dist/src/kernel/spec/emitSurface.js.map +1 -0
  492. package/dist/src/kernel/spec/index.js +11 -0
  493. package/dist/src/kernel/spec/index.js.map +1 -0
  494. package/dist/src/kernel/spec/surfaceConformance.js +103 -0
  495. package/dist/src/kernel/spec/surfaceConformance.js.map +1 -0
  496. package/dist/src/kernel/spec/types.js +14 -0
  497. package/dist/src/kernel/spec/types.js.map +1 -0
  498. package/dist/src/kernel/spec/validate.js +110 -0
  499. package/dist/src/kernel/spec/validate.js.map +1 -0
  500. package/dist/src/kernel/vocabulary.js +97 -0
  501. package/dist/src/kernel/vocabulary.js.map +1 -0
  502. package/dist/src/types.js +11 -0
  503. package/dist/src/types.js.map +1 -0
  504. package/package.json +20 -22
  505. package/pragma.conf.ts +249 -60
  506. package/src/bin.ts +267 -82
  507. package/src/capabilities/block.parity.test.ts +6 -3
  508. package/src/capabilities/capabilities/capabilities.render.ts +1 -1
  509. package/src/capabilities/capabilities/capabilities.verb.ts +1 -1
  510. package/src/capabilities/capabilities/catalog.ts +3 -3
  511. package/src/capabilities/capabilities/hints.ts +32 -7
  512. package/src/capabilities/capabilities/index.ts +1 -1
  513. package/src/capabilities/colophon/collectColophon.ts +35 -24
  514. package/src/capabilities/colophon/colophon.render.ts +25 -1
  515. package/src/capabilities/colophon/colophon.test.ts +42 -21
  516. package/src/capabilities/colophon/colophon.verb.ts +4 -4
  517. package/src/capabilities/config/collectConfigShow.test.ts +1 -0
  518. package/src/capabilities/config/collectConfigShow.ts +3 -3
  519. package/src/capabilities/config/field.render.ts +4 -5
  520. package/src/capabilities/config/fields.ts +17 -10
  521. package/src/capabilities/config/get.verb.ts +70 -0
  522. package/src/capabilities/config/getUnset.test.ts +264 -0
  523. package/src/capabilities/config/index.ts +5 -1
  524. package/src/capabilities/config/runField.ts +40 -22
  525. package/src/capabilities/config/runGet.ts +34 -0
  526. package/src/capabilities/config/runSet.ts +35 -9
  527. package/src/capabilities/config/set.test.ts +48 -14
  528. package/src/capabilities/config/set.verb.ts +8 -7
  529. package/src/capabilities/config/show.render.ts +1 -1
  530. package/src/capabilities/config/show.verb.ts +9 -6
  531. package/src/capabilities/config/types.ts +18 -4
  532. package/src/capabilities/config/unset.verb.ts +58 -0
  533. package/src/capabilities/create/byteEquality.subprocess.test.ts +2 -3
  534. package/src/capabilities/create/byteEquality.test.ts +25 -11
  535. package/src/capabilities/create/cliProjection.ts +227 -0
  536. package/src/capabilities/create/constants.ts +36 -61
  537. package/src/capabilities/create/create.mcp.test.ts +89 -5
  538. package/src/capabilities/create/create.render.ts +71 -7
  539. package/src/capabilities/create/create.test.ts +433 -219
  540. package/src/capabilities/create/create.verb.ts +297 -328
  541. package/src/capabilities/create/createGrammar.test.ts +865 -0
  542. package/src/capabilities/create/createHelp.ts +71 -0
  543. package/src/capabilities/create/createSurface.generated.ts +400 -0
  544. package/src/capabilities/create/crossCli.subprocess.test.ts +745 -0
  545. package/src/capabilities/create/cwdJail.test.ts +24 -5
  546. package/src/capabilities/create/generatorToVerbSpec.test.ts +186 -0
  547. package/src/capabilities/create/generatorToVerbSpec.ts +13 -11
  548. package/src/capabilities/create/index.ts +7 -4
  549. package/src/capabilities/create/messages.ts +18 -0
  550. package/src/capabilities/create/mount.ts +391 -0
  551. package/src/capabilities/create/pathJail.test.ts +90 -0
  552. package/src/capabilities/create/pathJail.ts +8 -5
  553. package/src/capabilities/create/pickGenerator.ts +23 -35
  554. package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
  555. package/src/capabilities/create/types.ts +20 -0
  556. package/src/capabilities/distribution.test.ts +3 -1
  557. package/src/capabilities/distribution.ts +10 -15
  558. package/src/capabilities/doctor/checks/checkKeStore.ts +7 -5
  559. package/src/capabilities/doctor/checks/checkPackageRefs.ts +6 -4
  560. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +2 -2
  561. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +72 -27
  562. package/src/capabilities/doctor/checks/checkShellCompletions.ts +59 -13
  563. package/src/capabilities/doctor/checks/index.ts +27 -0
  564. package/src/capabilities/doctor/checks/mcpCommand.test.ts +100 -0
  565. package/src/capabilities/doctor/checks/mcpCommand.ts +69 -0
  566. package/src/capabilities/doctor/checks/targetHealth.ts +274 -0
  567. package/src/capabilities/doctor/doctor.render.test.ts +18 -7
  568. package/src/capabilities/doctor/doctor.render.ts +43 -19
  569. package/src/capabilities/doctor/doctor.test.ts +123 -34
  570. package/src/capabilities/doctor/doctor.verb.ts +3 -3
  571. package/src/capabilities/doctor/runChecks.ts +62 -63
  572. package/src/capabilities/doctor/types.ts +20 -4
  573. package/src/capabilities/emptyRecovery.test.ts +13 -8
  574. package/src/capabilities/graph/examples.exec.test.ts +107 -0
  575. package/src/capabilities/graph/index.ts +1 -1
  576. package/src/capabilities/graph/inspect.render.ts +70 -22
  577. package/src/capabilities/graph/inspect.test.ts +260 -5
  578. package/src/capabilities/graph/inspect.verb.ts +18 -6
  579. package/src/capabilities/graph/query.render.ts +15 -3
  580. package/src/capabilities/graph/query.verb.ts +3 -3
  581. package/src/capabilities/graph/runQuery.ts +2 -3
  582. package/src/capabilities/index.ts +3 -1
  583. package/src/capabilities/info/collectInfo.ts +5 -4
  584. package/src/capabilities/info/info.render.ts +1 -1
  585. package/src/capabilities/info/info.verb.ts +1 -1
  586. package/src/capabilities/lazy.test.ts +32 -0
  587. package/src/capabilities/meta/complete.verb.ts +1 -1
  588. package/src/capabilities/meta/index.ts +1 -1
  589. package/src/capabilities/meta/mcp.verb.ts +10 -8
  590. package/src/capabilities/ontology/index.ts +15 -11
  591. package/src/capabilities/ontology/ontology.test.ts +6 -55
  592. package/src/capabilities/ontology/queries.ts +2 -2
  593. package/src/capabilities/ontology/render.ts +3 -4
  594. package/src/capabilities/ontology/verbs.ts +27 -68
  595. package/src/capabilities/prompt/index.ts +2 -2
  596. package/src/capabilities/prompt/prompt.render.ts +6 -2
  597. package/src/capabilities/prompt/types.ts +1 -1
  598. package/src/capabilities/prompt/verbs.ts +4 -5
  599. package/src/capabilities/reference.test.ts +63 -0
  600. package/src/capabilities/resources/provider.ts +342 -85
  601. package/src/capabilities/resources/resources.test.ts +355 -59
  602. package/src/capabilities/setup/buildPlan.ts +236 -0
  603. package/src/capabilities/setup/index.ts +7 -7
  604. package/src/capabilities/setup/mode.ts +74 -0
  605. package/src/capabilities/setup/operations/index.ts +74 -0
  606. package/src/capabilities/setup/operations/setupCompletions.ts +97 -24
  607. package/src/capabilities/setup/operations/setupConfig.ts +124 -0
  608. package/src/capabilities/setup/operations/setupGenerator.ts +396 -326
  609. package/src/capabilities/setup/operations/setupLsp.ts +329 -68
  610. package/src/capabilities/setup/operations/setupMcp.ts +137 -97
  611. package/src/capabilities/setup/operations/setupSkills.ts +336 -108
  612. package/src/capabilities/setup/plan.render.ts +241 -0
  613. package/src/capabilities/setup/plan.ts +236 -0
  614. package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
  615. package/src/capabilities/setup/setup.render.test.ts +281 -73
  616. package/src/capabilities/setup/setup.render.ts +45 -77
  617. package/src/capabilities/setup/setup.test.ts +972 -209
  618. package/src/capabilities/setup/setup.verb.ts +223 -71
  619. package/src/capabilities/setup/shell.test.ts +86 -0
  620. package/src/capabilities/setup/shell.ts +137 -11
  621. package/src/capabilities/setup/targets.ts +367 -0
  622. package/src/capabilities/setup/types.ts +18 -57
  623. package/src/capabilities/shared/assertExecOk.ts +68 -10
  624. package/src/capabilities/shared/index.ts +32 -0
  625. package/src/capabilities/shared/packageManager.test.ts +55 -0
  626. package/src/capabilities/shared/packageManager.ts +62 -6
  627. package/src/capabilities/skill/discover.ts +37 -5
  628. package/src/capabilities/skill/index.ts +1 -1
  629. package/src/capabilities/skill/render.ts +10 -9
  630. package/src/capabilities/skill/skill.test.ts +7 -5
  631. package/src/capabilities/skill/verbs.ts +3 -4
  632. package/src/capabilities/sources/collectStatus.ts +7 -2
  633. package/src/capabilities/sources/index.ts +1 -1
  634. package/src/capabilities/sources/installSkills.ts +84 -7
  635. package/src/capabilities/sources/runUpdate.ts +53 -21
  636. package/src/capabilities/sources/sources.test.ts +154 -2
  637. package/src/capabilities/sources/status.render.ts +1 -1
  638. package/src/capabilities/sources/status.verb.ts +1 -1
  639. package/src/capabilities/sources/update.render.ts +1 -1
  640. package/src/capabilities/sources/update.verb.ts +1 -1
  641. package/src/capabilities/surface.test.ts +134 -17
  642. package/src/capabilities/upgrade/runUpgrade.ts +8 -8
  643. package/src/capabilities/upgrade/upgrade.render.ts +4 -5
  644. package/src/capabilities/upgrade/upgrade.test.ts +3 -3
  645. package/src/capabilities/upgrade/upgrade.verb.ts +1 -1
  646. package/src/capabilities/version/index.ts +12 -0
  647. package/src/capabilities/version/version.test.ts +66 -0
  648. package/src/capabilities/version/version.verb.ts +39 -0
  649. package/src/constants.ts +31 -1
  650. package/src/identity.test.ts +40 -25
  651. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +15 -13
  652. package/src/kernel/completion/complete.test.ts +12 -2
  653. package/src/kernel/completion/complete.ts +1 -1
  654. package/src/kernel/completion/emitScripts.ts +1 -1
  655. package/src/kernel/completion/entitySource.test.ts +1 -1
  656. package/src/kernel/completion/entitySource.ts +21 -8
  657. package/src/kernel/completion/model.test.ts +164 -12
  658. package/src/kernel/completion/model.ts +94 -14
  659. package/src/kernel/completion/parse.test.ts +4 -7
  660. package/src/kernel/completion/parse.ts +15 -0
  661. package/src/kernel/completion/resolve.test.ts +0 -1
  662. package/src/kernel/completion/safety.test.ts +34 -26
  663. package/src/kernel/completion/shellDrive.test.ts +28 -9
  664. package/src/kernel/completion/templates/bash.ts +7 -2
  665. package/src/kernel/completion/templates/index.ts +23 -0
  666. package/src/kernel/completion/types.ts +7 -0
  667. package/src/kernel/config/defaults.test.ts +25 -2
  668. package/src/kernel/config/defaults.ts +4 -3
  669. package/src/kernel/config/evaluateProjectConfig.ts +31 -8
  670. package/src/kernel/config/firstRun.test.ts +44 -38
  671. package/src/kernel/config/firstRun.ts +24 -88
  672. package/src/kernel/config/index.ts +1 -1
  673. package/src/kernel/config/readConfig.test.ts +6 -3
  674. package/src/kernel/config/readConfig.ts +1 -1
  675. package/src/kernel/config/schema.ts +3 -1
  676. package/src/kernel/config/types.ts +3 -1
  677. package/src/kernel/copy.test.ts +34 -4
  678. package/src/kernel/copy.ts +54 -0
  679. package/src/kernel/error/PragmaError.test.ts +5 -2
  680. package/src/kernel/error/PragmaError.ts +4 -2
  681. package/src/kernel/error/constants.ts +7 -5
  682. package/src/kernel/error/fromTaskError.ts +28 -6
  683. package/src/kernel/error/recovery.ts +14 -0
  684. package/src/kernel/error/renderError.ts +42 -1
  685. package/src/kernel/error/types.ts +21 -1
  686. package/src/kernel/index.ts +26 -0
  687. package/src/kernel/packs/collect.ts +12 -16
  688. package/src/kernel/packs/compile.test.ts +130 -1
  689. package/src/kernel/packs/compile.ts +93 -3
  690. package/src/kernel/packs/disclosure.ts +2 -2
  691. package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
  692. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +3 -4
  693. package/src/kernel/packs/graphql/index.ts +20 -0
  694. package/src/kernel/packs/index.ts +40 -0
  695. package/src/kernel/packs/iri.test.ts +73 -0
  696. package/src/kernel/packs/iri.ts +66 -14
  697. package/src/kernel/packs/renderPack.ts +24 -5
  698. package/src/kernel/packs/resolveEntity.test.ts +213 -0
  699. package/src/kernel/packs/resolveEntity.ts +112 -18
  700. package/src/kernel/packs/runBodies.ts +2 -3
  701. package/src/kernel/packs/sample.ts +1 -1
  702. package/src/kernel/packs/schema.ts +18 -1
  703. package/src/kernel/packs/sparql/applyFilters.ts +16 -17
  704. package/src/kernel/packs/sparql/buildLookupQuery.ts +75 -3
  705. package/src/kernel/packs/sparql/index.ts +37 -0
  706. package/src/kernel/packs/sparql/runSelect.test.ts +1 -1
  707. package/src/kernel/packs/sparql/runSelect.ts +3 -4
  708. package/src/kernel/packs/toolDescription.test.ts +42 -3
  709. package/src/kernel/packs/types.ts +13 -0
  710. package/src/kernel/packs/uniqueness.ts +1 -1
  711. package/src/kernel/project/cli/buildProgram.test.ts +147 -12
  712. package/src/kernel/project/cli/buildProgram.ts +77 -18
  713. package/src/kernel/project/cli/constants.ts +34 -0
  714. package/src/kernel/project/cli/dispatch.test.ts +160 -3
  715. package/src/kernel/project/cli/dispatch.ts +222 -42
  716. package/src/kernel/project/cli/exitCodes.ts +1 -1
  717. package/src/kernel/project/cli/globalFlags.test.ts +117 -1
  718. package/src/kernel/project/cli/globalFlags.ts +130 -30
  719. package/src/kernel/project/cli/helpFormat.ts +13 -0
  720. package/src/kernel/project/cli/rootHelp.ts +41 -12
  721. package/src/kernel/project/cli/suggest.test.ts +33 -1
  722. package/src/kernel/project/cli/suggest.ts +25 -1
  723. package/src/kernel/project/cli/verbHelp.test.ts +30 -0
  724. package/src/kernel/project/cli/verbHelp.ts +23 -7
  725. package/src/kernel/project/mcp/buildServer.ts +7 -4
  726. package/src/kernel/project/mcp/envelope.ts +2 -2
  727. package/src/kernel/project/mcp/instructions.ts +2 -2
  728. package/src/kernel/project/mcp/mcpError.ts +1 -1
  729. package/src/kernel/project/mcp/parity.test.ts +5 -2
  730. package/src/kernel/project/mcp/prompts/index.ts +37 -0
  731. package/src/kernel/project/mcp/prompts/source.ts +2 -2
  732. package/src/kernel/project/mcp/registerVerb.ts +35 -9
  733. package/src/kernel/project/mcp/serve.ts +2 -2
  734. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
  735. package/src/kernel/render/contracts.ts +21 -0
  736. package/src/kernel/render/envelope.ts +2 -3
  737. package/src/kernel/render/formatters.ts +1 -1
  738. package/src/kernel/render/renderers.test.ts +243 -6
  739. package/src/kernel/render/renderers.ts +222 -20
  740. package/src/kernel/render/style.test.ts +75 -24
  741. package/src/kernel/render/style.ts +31 -1
  742. package/src/kernel/render/turtle.ts +222 -0
  743. package/src/kernel/runtime/graphpack/buildIndex.ts +1 -1
  744. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +3 -3
  745. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
  746. package/src/kernel/runtime/graphpack/embedded.ts +3 -3
  747. package/src/kernel/runtime/graphpack/manifest.ts +1 -1
  748. package/src/kernel/runtime/graphpack/read.ts +1 -2
  749. package/src/kernel/runtime/loadSession.ts +1 -1
  750. package/src/kernel/runtime/probe.ts +6 -6
  751. package/src/kernel/runtime/readEntity.ts +472 -28
  752. package/src/kernel/runtime/refs/index.ts +39 -0
  753. package/src/kernel/runtime/refs/parseRef.ts +2 -2
  754. package/src/kernel/runtime/refs/resolve.ts +4 -4
  755. package/src/kernel/runtime/storeReadiness.ts +1 -2
  756. package/src/kernel/runtime/types.ts +15 -1
  757. package/src/kernel/runtime/wasmEmbed.test.ts +37 -39
  758. package/src/kernel/spec/emitReference.ts +105 -30
  759. package/src/kernel/spec/emitSurface.ts +48 -6
  760. package/src/kernel/spec/surfaceConformance.test.ts +4 -2
  761. package/src/kernel/spec/types.ts +248 -4
  762. package/src/testing/behavioral/docExamples.test.ts +14 -0
  763. package/src/testing/behavioral/errorMatrix.mcp.test.ts +2 -2
  764. package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
  765. package/src/testing/behavioral/journeys.cli.test.ts +1 -1
  766. package/src/testing/behavioral/journeys.defaultPack.test.ts +7 -7
  767. package/src/testing/behavioral/journeys.implementation.test.ts +206 -0
  768. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +2 -2
  769. package/src/testing/behavioral/journeys.packageStories.test.ts +4 -4
  770. package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
  771. package/src/testing/behavioral/mcpSurface.test.ts +1 -1
  772. package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
  773. package/src/testing/eval/cases/effectful.ts +3 -2
  774. package/src/testing/fixtures/blockGraph.ts +79 -0
  775. package/src/testing/fixtures/graph/canonical.ts +88 -2
  776. package/src/testing/fixtures/graph/defaultPack.ts +1 -1
  777. package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
  778. package/src/testing/helpers/projectMcp.ts +32 -6
  779. package/src/testing/helpers/runCli.ts +35 -18
  780. package/src/testing/perf/budgets.test.ts +20 -9
  781. package/src/testing/perf/budgets.ts +58 -9
  782. package/src/testing/perf/codegen.test.ts +126 -0
  783. package/src/testing/perf/globalSetup.test.ts +286 -0
  784. package/src/testing/perf/globalSetup.ts +505 -23
  785. package/src/testing/perf/measure.test.ts +38 -0
  786. package/src/testing/perf/measure.ts +23 -4
  787. package/src/testing/setupXdgIsolation.ts +81 -21
  788. package/src/testing/tempRoot.globalSetup.ts +122 -0
  789. package/dist/pragma +0 -0
  790. package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -189
  791. package/src/capabilities/create/templates.embedded.generated.ts +0 -28
  792. package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -42
  793. package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
  794. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -68
  795. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -61
  796. package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
  797. package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
  798. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Vitest global setup: build the compiled `dist/pragma` once, before the suite,
2
+ * Vitest global setup: emit `dist/` once, before the suite,
3
3
  * if it is missing OR older than the sources it was built from.
4
4
  *
5
- * Shared by both configs, because two suites spawn the binary: the perf budgets
5
+ * Shared by both configs, because two suites spawn the shipped entry: the perf budgets
6
6
  * (src/testing/perf/**, `test:perf`) and the storeless-guarantee guards in
7
7
  * src/kernel/completion/safety.test.ts (the main `test:vitest` pass). Wiring it
8
- * into both means `bun run test` on a clean checkout provisions the binary with
8
+ * into both means `bun run test` on a clean checkout provisions the emit with
9
9
  * no manual build step — neither suite may assume it is pre-built.
10
10
  *
11
11
  * STALENESS, not mere existence. `existsSync` alone meant every spawned-binary
@@ -19,7 +19,7 @@
19
19
  * STALENESS INCLUDES THE EMBEDDED WORKSPACE DEPS. The binary bundles every
20
20
  * `@canonical/*` workspace package it (transitively) imports — task, summon-*,
21
21
  * ke, … — so an edit to `packages/runtime/task` is a change to what
22
- * `dist/pragma` runs, yet this package's own `src` never moves. The gate
22
+ * the shipped entry runs, yet this package's own `src` never moves. The gate
23
23
  * therefore also watches each workspace-linked dependency (found by following
24
24
  * the `node_modules/<name>` symlinks, transitively) — its `src` (the authored
25
25
  * source), `dist` (what the bundler actually embeds, per the dep's export map)
@@ -32,18 +32,177 @@
32
32
  * hashing every input on every suite start costs more than the rebuild it
33
33
  * avoids. CI is fresh-checkout either way; this gate exists for developer
34
34
  * boxes that have built before.
35
+ *
36
+ * THE DEP DISTS THEMSELVES ARE GATED HERE TOO, FIRST. The suites do not only
37
+ * embed the workspace deps — they IMPORT and SPAWN their dists live
38
+ * (byteEquality runs against summon-core's `dist/esm`, crossCli's
39
+ * `--generators` fixture re-exports the summon generator dists, the offline
40
+ * cells spawn cli/summon's built bin, and every static
41
+ * `@canonical/summon-*`/`@canonical/task` import resolves through the deps'
42
+ * `exports` maps into `dist/…`). Rebuilding those dists from inside a test
43
+ * worker's `beforeAll` raced the sibling workers importing the same files in
44
+ * the same parallel pass (tsc/copy-templates overwrite in place, no clean),
45
+ * so the staleness gate lives HERE: this hook runs ONCE, in the main
46
+ * process, BEFORE any worker starts — for full runs and single-file
47
+ * `vitest run <file>` invocations alike, under both configs. Order matters:
48
+ * stale dep dists rebuild first (dependencies before dependents — a cycle
49
+ * throws loudly, naming its members, instead of hanging the topo loop), and
50
+ * only then is the emit judged — a refreshed dep dist moves the mtimes
51
+ * the emit check watches, so the entry that loads them is rebuilt in
52
+ * the same setup pass and every worker sees one consistent generation.
53
+ *
54
+ * THAT PLACEMENT SERIALIZES ONE PROCESS, NOT THE WORKSPACE. cli/summon's
55
+ * sibling gate (src/testing/globalSetup.ts) rebuilds four of the same dep
56
+ * dists from ITS process, nothing orders the two suites, and two
57
+ * invocations of this package's own suites can overlap too — so every
58
+ * root here (each per-root dep dist AND the emit) ALWAYS enters
59
+ * {@link buildUnderLock}, which takes an O_EXCL lockfile at the root's
60
+ * top level — OUTSIDE every tree the freshness rules stat — and judges
61
+ * freshness only UNDER it: a second process finding the lock waits for
62
+ * release and RE-STATS instead of double-building (two in-place `tsc`
63
+ * rewrites truncating one dist under a live importer). A pre-lock
64
+ * freshness skip existed once and let a contender bless another
65
+ * process's mid-flight emit (the entry lands before `tsc` can fail —
66
+ * measured live), proceeding with no lock against an artifact about to
67
+ * be destroyed; deleting it is what makes "one consistent generation for
68
+ * every worker" true. A lock that never clears fails loudly after a
69
+ * timeout instead of forever.
35
70
  */
36
71
 
37
72
  import { spawnSync } from "node:child_process";
38
- import { lstatSync, readdirSync, realpathSync, statSync } from "node:fs";
73
+ import {
74
+ closeSync,
75
+ existsSync,
76
+ lstatSync,
77
+ openSync,
78
+ readdirSync,
79
+ readFileSync,
80
+ realpathSync,
81
+ rmSync,
82
+ statSync,
83
+ writeSync,
84
+ } from "node:fs";
39
85
  import { join, sep } from "node:path";
40
86
  import { fileURLToPath } from "node:url";
41
87
 
42
- /** Everything the compiled binary is built FROM, relative to the package root. */
43
- const INPUTS = ["src", "scripts", "pragma.conf.ts", "package.json"];
88
+ /**
89
+ * Everything the emit is built FROM, relative to the package root. Both
90
+ * tsconfigs are inputs: `tsconfig.build.json` IS the emit configuration and
91
+ * `tsconfig.json` is what it extends, so an option edit changes `dist` while
92
+ * `src` never moves.
93
+ */
94
+ const INPUTS = [
95
+ "src",
96
+ "scripts",
97
+ "pragma.conf.ts",
98
+ "package.json",
99
+ "tsconfig.json",
100
+ "tsconfig.build.json",
101
+ ];
102
+
103
+ /** How long a contender waits on another process's build lock (ms). */
104
+ const LOCK_TIMEOUT_MS = 120_000;
105
+
106
+ /** Contention poll interval (ms). */
107
+ const LOCK_POLL_MS = 200;
108
+
109
+ /** Synchronous sleep — the gate is sync, in the main process, pre-worker. */
110
+ function sleepSync(ms: number): void {
111
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
112
+ }
44
113
 
45
114
  /**
46
- * What feeds the binary inside one workspace dependency: its authored source,
115
+ * Serialize one root's rebuild across PROCESSES with an `O_EXCL` lockfile
116
+ * at `<root>/.dist-build.lock` — the root's top level, deliberately
117
+ * OUTSIDE every tree the freshness rules stat. The lock's own
118
+ * create/unlink is a directory mutation, and a lock kept beside the
119
+ * served artifact inside `dist/**` bumped a directory {@link DEP_INPUTS}
120
+ * watches on EVERY entry, so a fully fresh tree re-judged the emit
121
+ * stale and rebuilt it on every vitest invocation (measured);
122
+ * the root's own mtime, by contrast, is watched by nothing — only its
123
+ * named children are. The file must also stay UNTRACKED: the root-level
124
+ * home sits outside the ignored `dist/`, so `.dist-build.lock` has its
125
+ * own root `.gitignore` rule — a committed lock (crash residue swept
126
+ * into a `git add -A`) would block every clone's every run for the full
127
+ * timeout, with a "delete the file" remedy git keeps undoing. The next
128
+ * relocation must keep BOTH properties: outside every watched tree, and
129
+ * inside an ignore rule. One root serves ONE dist artifact, so
130
+ * root-scoped is artifact-scoped, and both sibling gates compute the
131
+ * same path for the same root — contention still meets contention. Freshness is
132
+ * decided ONLY under the lock: callers enter unconditionally, with no
133
+ * pre-lock fast path — a stat taken outside the lock can land inside
134
+ * another process's emit-to-exit window (`tsc` emits the entry before it
135
+ * can fail) and bless a mid-flight artifact without waiting on anything.
136
+ * The holder stats after acquiring and builds only if stale, so an
137
+ * uncontended fresh root pays one open/unlink and nothing else; a
138
+ * contender waits for release and then loops back to ACQUIRE the lock
139
+ * itself and re-stat UNDER it — a lock-free existence-then-freshness
140
+ * probe is two unsynchronised observations, and between them a new
141
+ * holder can take the lock and begin an in-place rebuild whose
142
+ * mid-flight mtimes the probe blesses — building only when the re-stat
143
+ * still reads stale, which a FAILED holder guarantees: a `build`
144
+ * callback whose build RAN and failed destroys the served artifact
145
+ * before rethrowing, because a failed build
146
+ * can still EMIT it (nothing sets `noEmitOnError`, so `tsc` writes output
147
+ * and exits nonzero, and the two-step builds' first step writes the entry
148
+ * before the second can fail) — mtime alone cannot tell a failed build
149
+ * from a clean one — while a spawn failure with NO child (`error` set
150
+ * and `signal == null`) leaves the artifact alone: no builder ever ran,
151
+ * nothing was emitted, and the dist on disk is still the previous good
152
+ * generation, stale by the same stats that sent the holder in. A lockfile that never clears (a killed
153
+ * builder) fails loudly after {@link LOCK_TIMEOUT_MS} naming the file,
154
+ * rather than double-building or waiting forever. RESIDUAL, accepted:
155
+ * since every entry takes the lock, crash residue blocks EVERY later run
156
+ * for the full timeout until the file is removed (pre-existing wait
157
+ * semantics — no stale-lock reclaim is attempted).
158
+ *
159
+ * TWIN: cli/summon's globalSetup (src/testing/globalSetup.ts) carries the
160
+ * same helper — the two gates are deliberate SIBLINGS with no import edge
161
+ * (importing from `@canonical/pragma-cli` there would close a dependency
162
+ * cycle); keep the copies in step.
163
+ *
164
+ * @param root - The package root the lock scopes (one served dist each).
165
+ * @param isFresh - Re-stats the artifact against its inputs.
166
+ * @param build - Rebuilds the artifact (throws loudly on failure).
167
+ * @note Impure — creates and removes `<root>/.dist-build.lock`; blocks
168
+ * while waiting.
169
+ */
170
+ function buildUnderLock(
171
+ root: string,
172
+ isFresh: () => boolean,
173
+ build: () => void,
174
+ ): void {
175
+ const lockPath = join(root, ".dist-build.lock");
176
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
177
+ for (;;) {
178
+ let fd: number;
179
+ try {
180
+ fd = openSync(lockPath, "wx");
181
+ } catch (cause) {
182
+ if ((cause as NodeJS.ErrnoException).code !== "EEXIST") throw cause;
183
+ if (Date.now() >= deadline) {
184
+ throw new Error(
185
+ `perf globalSetup: build lock ${lockPath} still held after ` +
186
+ `${LOCK_TIMEOUT_MS}ms — a killed build may have left it behind; ` +
187
+ "delete the file and re-run",
188
+ );
189
+ }
190
+ sleepSync(LOCK_POLL_MS);
191
+ continue;
192
+ }
193
+ try {
194
+ writeSync(fd, `${process.pid}\n`);
195
+ if (!isFresh()) build();
196
+ return;
197
+ } finally {
198
+ closeSync(fd);
199
+ rmSync(lockPath, { force: true });
200
+ }
201
+ }
202
+ }
203
+
204
+ /**
205
+ * What feeds the entry inside one workspace dependency: its authored source,
47
206
  * the compiled output the bundler embeds, and its manifest. Deliberately NOT
48
207
  * the whole package dir — that would watch `coverage/` and `node_modules/`,
49
208
  * whose mtimes move on every test run and would force a rebuild loop.
@@ -76,7 +235,7 @@ function newestMtime(path: string): number {
76
235
  }
77
236
 
78
237
  /**
79
- * Every workspace package the binary can embed, transitively: follow each
238
+ * Every workspace package the entry can load, transitively: follow each
80
239
  * `node_modules/<name>` symlink whose target lives OUTSIDE any `node_modules`
81
240
  * store (that is what distinguishes a workspace link from a registry install),
82
241
  * then repeat from the target's own `node_modules`. Cycles are cut by the
@@ -124,22 +283,345 @@ function workspaceDepRoots(pkgRoot: string): string[] {
124
283
  return [...visited].filter((dir) => dir !== root);
125
284
  }
126
285
 
127
- export default function setup(): void {
128
- const root = fileURLToPath(new URL("../../../", import.meta.url));
129
- const built = newestMtime(join(root, "dist", "pragma"));
130
- const fresh =
131
- built > 0 &&
132
- INPUTS.every((input) => newestMtime(join(root, input)) < built) &&
133
- workspaceDepRoots(root).every((dep) =>
134
- DEP_INPUTS.every((input) => newestMtime(join(dep, input)) < built),
135
- );
136
- if (fresh) return;
286
+ /**
287
+ * What one dep's dist is built from (a missing entry stats 0). Every
288
+ * `tsconfig.build.json` here is a thin override extending the package's own
289
+ * `tsconfig.json`, which supplies the compiler options that shape the emit —
290
+ * so both are watched. The repo-root template copier is a build input too —
291
+ * see {@link TEMPLATE_COPIER}, statted separately because no
292
+ * `join(root, input)` path can reach it. RESIDUAL, accepted: the shared
293
+ * `@canonical/typescript-config` base those extend is NOT watched — the
294
+ * packages reach it inconsistently (most via their own `node_modules` link,
295
+ * summon-application by relative path), so no one entry covers it; an edit
296
+ * there without a per-package tsconfig change can leave a dist judged fresh.
297
+ */
298
+ const DIST_INPUTS = [
299
+ "src",
300
+ "generators",
301
+ "package.json",
302
+ "tsconfig.build.json",
303
+ "tsconfig.json",
304
+ ];
137
305
 
138
- const result = spawnSync("bun", ["run", "scripts/build.ts"], {
306
+ /**
307
+ * The repo-root template copier — the SECOND build step of four gated dists
308
+ * (`bun ../../../scripts/copy-templates.ts` in summon-component/-package/
309
+ * -application and cli/summon): a ROOT-OWNED build input (the r12-F4 class,
310
+ * one directory up) that {@link DIST_INPUTS}' root-relative paths can never
311
+ * reach, so an edit to the copier's glob or filter left every dist judged
312
+ * FRESH and the suites green against copies the OLD copier produced. It is
313
+ * statted as one absolute constant, UNCONDITIONALLY for every dep root (a
314
+ * cheap single stat; roots whose build never runs it just carry a harmless
315
+ * extra input). The compiled BINARY's own rule deliberately omits it:
316
+ * `scripts/build.ts` embeds each package's `src` templates directly and
317
+ * never runs the copier.
318
+ *
319
+ * WATCHED-CONSTANT RULE: for one absolute constant a stat of 0 is ALWAYS a
320
+ * bug — the copier moved (the filed PRA-138 relocation is the standing
321
+ * trigger) and the constant dangles — never a legitimate absence like
322
+ * {@link DIST_INPUTS}' root-relative entries. `newestMtime`'s 0 would make
323
+ * `0 < built` vacuously true, silently deleting the clause from every
324
+ * gate, so the module THROWS at load while the path is missing. EXPORTED
325
+ * for the existsSync pin in globalSetup.test.ts.
326
+ * TWIN: cli/summon's globalSetup carries the same constant and rule.
327
+ */
328
+ export const TEMPLATE_COPIER = fileURLToPath(
329
+ new URL("../../../../../../scripts/copy-templates.ts", import.meta.url),
330
+ );
331
+ if (!existsSync(TEMPLATE_COPIER)) {
332
+ throw new Error(
333
+ `perf globalSetup: the watched template copier is MISSING at ${TEMPLATE_COPIER} — ` +
334
+ "the TEMPLATE_COPIER constant dangles (copier moved?); fix the path, " +
335
+ "or its freshness clause silently stops watching",
336
+ );
337
+ }
338
+
339
+ /**
340
+ * The gate build's ONE env delta — the flag that flips `scripts/build.ts`
341
+ * into CHECK mode (read by `checkModeFromEnv` in scripts/codegen.ts).
342
+ * EXPORTED so the flag's VALUE is pinned: this constant IS the object the
343
+ * gate spawn below spreads into its env, and a codegen.test.ts cell
344
+ * asserts that value actually enters check mode, so the value and its
345
+ * reader cannot drift apart unnoticed. The SPREAD at the spawn is a
346
+ * different matter: it is pinned by CONSTRUCTION, not by an assertion —
347
+ * an env-object refactor that drops `...GATE_BUILD_ENV` leaves every cell
348
+ * green while the gate silently reverts to write mode, restoring the
349
+ * silent-repair MAJORs.
350
+ */
351
+ export const GATE_BUILD_ENV = { PRAGMA_BUILD_SKIP_DOCS: "1" } as const;
352
+
353
+ /** Every string leaf of a package.json `exports` value (conditions walked). */
354
+ function exportTargets(exportsField: unknown): string[] {
355
+ if (typeof exportsField === "string") return [exportsField];
356
+ if (exportsField && typeof exportsField === "object") {
357
+ return Object.values(exportsField).flatMap(exportTargets);
358
+ }
359
+ return [];
360
+ }
361
+
362
+ /**
363
+ * EVERY dist artifact one workspace package serves, absolute, entry first —
364
+ * or `[]` for a package that serves no compiled dist (no `build` script, or
365
+ * an entry outside `dist/`, e.g. webarchitect's source-served
366
+ * `src/index.ts`), which the dep-dist gate skips.
367
+ *
368
+ * The entry (`module` ?? `main`) alone was the whole freshness subject once,
369
+ * and that was too narrow: the suites also consume `types` (summon-
370
+ * application's tsc reads summon-core's `dist/types`), the export-map
371
+ * subpaths (`@canonical/summon-core/projection` resolves into `dist/esm/
372
+ * projection/`), and the template copier's destination (cli/summon's
373
+ * `dist/generators`) — so a TORN build could leave the entry newer than
374
+ * every input while another served output was missing or stale, and the
375
+ * gate blessed it. Freshness is judged against the OLDEST of these (a
376
+ * missing one stats 0 and reads stale). RESIDUAL, accepted: a torn emit
377
+ * that wrote a SUBSET of one directory's files carries fresh mtimes on
378
+ * what it did write — mtimes cannot prove set-completeness.
379
+ */
380
+ function servedDistOutputs(root: string): string[] {
381
+ let manifest: {
382
+ module?: string;
383
+ main?: string;
384
+ types?: string;
385
+ exports?: unknown;
386
+ scripts?: Record<string, string>;
387
+ };
388
+ try {
389
+ manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf-8"));
390
+ } catch {
391
+ return [];
392
+ }
393
+ const entry = manifest.module ?? manifest.main;
394
+ if (!entry?.startsWith("dist") || !manifest.scripts?.build) {
395
+ return [];
396
+ }
397
+ const outputs = new Set<string>([entry]);
398
+ if (manifest.types?.startsWith("dist")) outputs.add(manifest.types);
399
+ for (const target of exportTargets(manifest.exports)) {
400
+ const relative = target.replace(/^\.\//, "");
401
+ if (relative.startsWith("dist")) outputs.add(relative);
402
+ }
403
+ // The template copier's destination, when this package's build runs it
404
+ // (`bun ../../../scripts/copy-templates.ts <src> <dest>`).
405
+ const copyDest = /copy-templates\.ts\s+\S+\s+(\S+)/.exec(
406
+ manifest.scripts.build,
407
+ )?.[1];
408
+ if (copyDest?.startsWith("dist")) outputs.add(copyDest);
409
+ return [...outputs].map((output) => join(root, output));
410
+ }
411
+
412
+ /** The slice of `spawnSync`'s result the build wrapper judges. */
413
+ interface BuildResult {
414
+ status: number | null | undefined;
415
+ /**
416
+ * The never-started/ran-then-killed discriminator: spawnSync's
417
+ * `NodeJS.Signals | null` — `null` when no child ever ran, a signal
418
+ * (e.g. `SIGTERM`) when spawnSync KILLED a running child itself
419
+ * (maxBuffer/timeout — `error` is set in BOTH cases). Bun may leave it
420
+ * `undefined` on a spawn failure; judged `== null` either way.
421
+ */
422
+ signal: NodeJS.Signals | null | undefined;
423
+ stdout: string | null;
424
+ stderr: string | null;
425
+ error?: Error | undefined;
426
+ }
427
+
428
+ /** Runs one root's build and reports the spawn result. */
429
+ type BuildRunner = (root: string) => BuildResult;
430
+
431
+ /** The real runner: the package's own `bun run build`, streams captured. */
432
+ function runBuild(root: string): BuildResult {
433
+ return spawnSync("bun", ["run", "build"], {
139
434
  cwd: root,
140
- stdio: "inherit",
435
+ stdio: "pipe",
436
+ encoding: "utf-8",
437
+ // Uncapped: at the 1 MiB default a diagnostic FLOOD had spawnSync
438
+ // kill a child that had already emitted (ENOBUFS), instead of the
439
+ // flood reaching the nonzero arm intact.
440
+ maxBuffer: Number.POSITIVE_INFINITY,
441
+ });
442
+ }
443
+
444
+ /**
445
+ * Build one root's served dist under the cross-process lock, destroying the
446
+ * artifact only when the build RAN and failed.
447
+ *
448
+ * The per-root build-or-destroy rule, extracted and EXPORTED so a unit cell
449
+ * can drive it with an injected runner (globalSetup.test.ts, beside this
450
+ * file): this wrapper is the loop's one confirmed false-green producer
451
+ * (round 12), and unexported it was pinned by nothing — a dropped rmSync or
452
+ * a restored destroy-on-spawn-error stayed green until a real CI build
453
+ * failed. Three shapes:
454
+ * - spawn failure with NO child (`result.error` with `signal == null` —
455
+ * ENOENT/EACCES): throw naming the error, artifact PRESERVED (no child
456
+ * ever ran, so nothing was emitted; the dist on disk is the previous
457
+ * good generation). `error` ALONE does not mean this — spawnSync also
458
+ * sets it when it KILLS a build that ran (maxBuffer/timeout), and
459
+ * there `signal` carries the evidence.
460
+ * - nonzero exit / signal kill — spawnSync's own mid-run kills included
461
+ * (`error` set WITH a signal: the child RAN and can have emitted
462
+ * before dying): destroy the artifact (a failed build can still have
463
+ * EMITTED it — see {@link buildUnderLock}), then throw naming the
464
+ * root, the kill when there was one, and both captured streams.
465
+ * - success: the artifact is left as built, the lock released.
466
+ *
467
+ * TWIN: cli/summon's globalSetup carries the same function; keep in step.
468
+ *
469
+ * @param root - The workspace package being built (the lock lives at its
470
+ * top level, outside the watched trees).
471
+ * @param artifact - Its served dist entry.
472
+ * @param isFresh - Re-stats the artifact against its inputs (under the lock).
473
+ * @param runner - The build runner ({@link runBuild}; injectable for tests).
474
+ * @note Impure — takes the lock, builds, and may remove the artifact.
475
+ */
476
+ export function buildDistOrDestroy(
477
+ root: string,
478
+ artifact: string,
479
+ isFresh: () => boolean,
480
+ runner: BuildRunner = runBuild,
481
+ ): void {
482
+ buildUnderLock(root, isFresh, () => {
483
+ const result = runner(root);
484
+ if (result.error && result.signal == null) {
485
+ // A spawn failure with NO child (ENOENT/EACCES — no signal, and
486
+ // `status` unset): nothing can have been emitted, so the artifact
487
+ // on disk is still the previous good generation — preserve it,
488
+ // and name the failure's only carrier. `error` with a SIGNAL is
489
+ // the opposite case: spawnSync killed a build that RAN
490
+ // (maxBuffer/timeout) — that shape falls through to the destroy
491
+ // arm below.
492
+ throw new Error(
493
+ `perf globalSetup: failed to RUN the build for ${root}: ${result.error.message}`,
494
+ );
495
+ }
496
+ if (result.status !== 0) {
497
+ // The build RAN and failed — a nonzero exit, or a kill after the
498
+ // child started — and it can still have EMITTED the artifact (see
499
+ // buildUnderLock's docblock): destroy the evidence so the
500
+ // contender's re-stat and every later run see STALE instead of a
501
+ // fresh-looking dist compiled from erroring sources.
502
+ rmSync(artifact, { force: true });
503
+ const killed = result.error
504
+ ? ` (killed mid-run: ${result.error.message})`
505
+ : "";
506
+ throw new Error(
507
+ `perf globalSetup: failed to build ${root}'s dist:${killed}\n${result.stdout}${result.stderr}`,
508
+ );
509
+ }
141
510
  });
142
- if (result.status !== 0) {
143
- throw new Error("perf globalSetup: failed to build dist/pragma");
511
+ }
512
+
513
+ /**
514
+ * Rebuild every STALE workspace dep dist, dependencies before dependents
515
+ * (summon-application's tsc reads summon-core's `dist/types`). Runs in the
516
+ * main process before any worker exists, so an in-place `tsc`/copy-templates
517
+ * rewrite can never race a worker importing or spawning the same files.
518
+ * Staleness is the emit gate's own honest mtime rule, per package: its
519
+ * served entry artifact must be newer than every {@link DIST_INPUTS} entry.
520
+ *
521
+ * @param pkgRoot - This package's root directory (the closure's seed).
522
+ * @note Impure — stats and rebuilds workspace dists.
523
+ */
524
+ function buildStaleDepDists(pkgRoot: string): void {
525
+ const deps = workspaceDepRoots(pkgRoot);
526
+ // Dependencies before dependents: a root is ready once none of ITS deps
527
+ // are still pending. `workspaceDepRoots` follows devDependency links too,
528
+ // so a future dev-edge cycle is an ordinary event — it must throw with its
529
+ // members named, never spin the synchronous loop forever.
530
+ const depsOf = new Map(
531
+ deps.map((root) => [root, new Set(workspaceDepRoots(root))] as const),
532
+ );
533
+ const remaining = new Set(deps);
534
+ const ordered: string[] = [];
535
+ while (remaining.size > 0) {
536
+ const next = [...remaining].find((root) =>
537
+ [...(depsOf.get(root) ?? [])].every((dep) => !remaining.has(dep)),
538
+ );
539
+ if (next === undefined) {
540
+ throw new Error(
541
+ `perf globalSetup: dependency cycle among ${[...remaining].join(", ")}`,
542
+ );
543
+ }
544
+ ordered.push(next);
545
+ remaining.delete(next);
546
+ }
547
+ for (const root of ordered) {
548
+ const outputs = servedDistOutputs(root);
549
+ const artifact = outputs[0];
550
+ if (!artifact) continue;
551
+ const isFresh = (): boolean => {
552
+ // The OLDEST served output is the build's honest age: a missing one
553
+ // stats 0 (stale), and every input must predate ALL of them — the
554
+ // entry alone let a torn build pass on its freshest file.
555
+ const built = Math.min(...outputs.map(newestMtime));
556
+ return (
557
+ built > 0 &&
558
+ newestMtime(TEMPLATE_COPIER) < built &&
559
+ DIST_INPUTS.every((input) => newestMtime(join(root, input)) < built)
560
+ );
561
+ };
562
+ // No pre-lock isFresh() skip: freshness is decided UNDER the lock —
563
+ // a fresh-looking artifact out here can be another process's
564
+ // mid-flight emit (see buildUnderLock's docblock).
565
+ buildDistOrDestroy(root, artifact, isFresh);
144
566
  }
145
567
  }
568
+
569
+ export default function setup(): void {
570
+ const root = fileURLToPath(new URL("../../../", import.meta.url));
571
+ // Stale dep dists rebuild FIRST: their fresh mtimes then mark dist/pragma
572
+ // (which bundles them) stale below, so one setup pass yields one
573
+ // consistent generation for every worker.
574
+ buildStaleDepDists(root);
575
+ // The SUCCESS SENTINEL, not an output file. `tsc` writes its outputs even
576
+ // when it exits non-zero, so an emitted file carries a fresh mtime from a
577
+ // build that FAILED — keying on one would mark that wreckage fresh and run
578
+ // every spawning PROTECTED suite against it. `scripts/build.ts` writes
579
+ // `dist/.build-ok` last and only on a clean emit.
580
+ const binary = join(root, "dist", ".build-ok");
581
+ const isFresh = (): boolean => {
582
+ const built = newestMtime(binary);
583
+ return (
584
+ built > 0 &&
585
+ INPUTS.every((input) => newestMtime(join(root, input)) < built) &&
586
+ workspaceDepRoots(root).every((dep) =>
587
+ DEP_INPUTS.every((input) => newestMtime(join(dep, input)) < built),
588
+ )
589
+ );
590
+ };
591
+ // The binary rebuild is the same cross-process hazard as a dep dist (two
592
+ // overlapping invocations of this package's suites), so it takes the
593
+ // same kind of lock — this package's own root-level
594
+ // `.dist-build.lock`, the uniform scheme every gated root uses — and,
595
+ // like every root, enters it unconditionally: freshness is decided
596
+ // only UNDER it.
597
+ buildUnderLock(root, isFresh, () => {
598
+ const result = spawnSync("bun", ["run", "scripts/build.ts"], {
599
+ cwd: root,
600
+ stdio: "inherit",
601
+ // The GATE's build rewrites NONE of the committed artifacts its
602
+ // drift guards read: the generated surface runs in CHECK mode (a stale
603
+ // committed module FAILS this build, naming itself) and no reference
604
+ // docs are written —
605
+ // otherwise this same vitest run would silently repair what its
606
+ // drift guards (create.test.ts's PROTECTED cells; reference.test.ts)
607
+ // exist to catch. Every guard compares the bytes git actually holds.
608
+ // This one spawn serves both gate configs (vitest.config.ts and
609
+ // vitest.perf.config.ts register this globalSetup).
610
+ env: { ...process.env, ...GATE_BUILD_ENV },
611
+ });
612
+ if (result.error) {
613
+ // The builder never STARTED: nothing was written, so the binary on
614
+ // disk is still the previous good generation — preserve it.
615
+ throw new Error(
616
+ `perf globalSetup: failed to RUN the build for dist/pragma: ${result.error.message}`,
617
+ );
618
+ }
619
+ if (result.status !== 0) {
620
+ // The build RAN and failed — same failure-destroys-the-evidence
621
+ // rule as the dep dists: a partially written binary must read
622
+ // STALE, never fresh.
623
+ rmSync(binary, { force: true });
624
+ throw new Error("perf globalSetup: failed to build dist/pragma");
625
+ }
626
+ });
627
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The measurement helper's runnability guard — the perf pass's one defense
3
+ * against timing a binary that cannot run. The PROTECTED budgets assert only
4
+ * ceilings; pre-fix a 0-byte `dist/pragma` (an interrupted build the
5
+ * staleness gate stats as FRESH — mtime, not runnability) failed every spawn
6
+ * in ~0.3ms and sailed under all four budgets. measureCommand now throws on
7
+ * the FIRST sample whose status is nonzero or whose spawn errored, naming
8
+ * the argv — these cells pin both failure shapes. Budgets.test.ts itself is
9
+ * unchanged: its argvs all exit 0 by contract.
10
+ */
11
+
12
+ import { mkdtempSync } from "node:fs";
13
+ import { tmpdir } from "node:os";
14
+ import { join } from "node:path";
15
+ import { describe, expect, it } from "vitest";
16
+ import { measureCommand } from "./measure.js";
17
+
18
+ describe("measureCommand — a failing argv fails the measurement", () => {
19
+ it("a sample that exits nonzero throws loudly, naming the argv and status", () => {
20
+ // `bun -e "process.exit(3)"` is a real spawn that runs and fails — the
21
+ // shape a broken binary produces on every budget argv.
22
+ expect(() =>
23
+ measureCommand(process.execPath, ["-e", "process.exit(3)"], {
24
+ runs: 2,
25
+ warmups: 0,
26
+ }),
27
+ ).toThrowError(
28
+ /measureCommand: `.+ -e process\.exit\(3\)` failed on sample 1\/2 — status 3/,
29
+ );
30
+ });
31
+
32
+ it("a binary that cannot spawn at all throws loudly, naming the error", () => {
33
+ const absent = join(mkdtempSync(join(tmpdir(), "measure-absent-")), "nope");
34
+ expect(() =>
35
+ measureCommand(absent, ["--help"], { runs: 1, warmups: 0 }),
36
+ ).toThrowError(/failed on sample 1\/1 — .*error: /);
37
+ });
38
+ });
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Perf measurement helper for the compiled `pragma` binary.
3
3
  *
4
- * Spawns the standalone binary N times, discards warmups, and reports the
4
+ * Spawns the shipped entry N times, discards warmups, and reports the
5
5
  * median and p95 of the wall-clock durations. Kept dependency-free (only
6
6
  * `node:child_process`) so it can run inside vitest without touching the
7
7
  * kernel's import graph. Wired up by the perf-spike commit; the skeleton
@@ -62,11 +62,20 @@ export function trimmedMean(sorted: readonly number[], trim = 0.1): number {
62
62
  /**
63
63
  * Measure the wall-clock cost of running `binary args…` repeatedly.
64
64
  *
65
- * @param binary - Absolute path to the compiled binary.
65
+ * Every budget argv exits 0 by contract, so a sample that FAILS —
66
+ * nonzero/killed `status` or a spawn `error` — throws on the spot, naming
67
+ * the argv and the failure. Without this the timing loop certified
68
+ * non-runnable artifacts: the staleness gate guarantees the emit's
69
+ * FRESHNESS, not its runnability, and a truncated artifact (an interrupted
70
+ * build) failed every spawn in ~0.3ms — sailing under every ceiling and
71
+ * turning the PROTECTED budgets into a vacuous pass.
72
+ *
73
+ * @param binary - Absolute path to the executable to spawn (the runtime, when
74
+ * the entry is passed as its first argument).
66
75
  * @param args - Arguments passed on each spawn.
67
76
  * @param options - Run/warmup counts and env overlay.
68
77
  * @returns Median, p95, and the kept samples.
69
- * @note Impure — spawns child processes.
78
+ * @note Impure — spawns child processes; throws on the first failing sample.
70
79
  */
71
80
  export function measureCommand(
72
81
  binary: string,
@@ -79,11 +88,21 @@ export function measureCommand(
79
88
 
80
89
  for (let i = 0; i < runs; i++) {
81
90
  const start = performance.now();
82
- spawnSync(binary, [...args], {
91
+ const result = spawnSync(binary, [...args], {
83
92
  env: { ...process.env, ...options.env },
84
93
  stdio: "ignore",
85
94
  });
86
95
  const elapsed = performance.now() - start;
96
+ if (result.error || result.status !== 0) {
97
+ throw new Error(
98
+ `measureCommand: \`${[binary, ...args].join(" ")}\` failed on ` +
99
+ `sample ${i + 1}/${runs} — status ${String(result.status)}, ` +
100
+ `signal ${String(result.signal)}` +
101
+ (result.error ? `, error: ${result.error.message}` : "") +
102
+ ". Every budget argv must exit 0: a binary that cannot run must " +
103
+ "fail the measurement, not be timed failing.",
104
+ );
105
+ }
87
106
  if (i >= warmups) samples.push(elapsed);
88
107
  }
89
108