@canonical/pragma-cli 0.33.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 (892) 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 +25 -24
  505. package/pragma.conf.ts +853 -0
  506. package/src/bin.ts +276 -82
  507. package/src/capabilities/block.parity.test.ts +253 -0
  508. package/src/capabilities/capabilities/capabilities.render.ts +4 -3
  509. package/src/capabilities/capabilities/capabilities.verb.ts +32 -14
  510. package/src/capabilities/capabilities/catalog.ts +20 -12
  511. package/src/capabilities/capabilities/hints.ts +43 -24
  512. package/src/capabilities/capabilities/index.ts +1 -1
  513. package/src/capabilities/colophon/collectColophon.ts +50 -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 +9 -5
  517. package/src/capabilities/colophon/types.ts +16 -7
  518. package/src/capabilities/config/collectConfigShow.test.ts +58 -0
  519. package/src/capabilities/config/collectConfigShow.ts +43 -6
  520. package/src/capabilities/config/field.render.ts +4 -5
  521. package/src/capabilities/config/fields.ts +17 -37
  522. package/src/capabilities/config/get.verb.ts +70 -0
  523. package/src/capabilities/config/getUnset.test.ts +264 -0
  524. package/src/capabilities/config/index.ts +5 -1
  525. package/src/capabilities/config/runField.ts +40 -22
  526. package/src/capabilities/config/runGet.ts +34 -0
  527. package/src/capabilities/config/runSet.ts +35 -9
  528. package/src/capabilities/config/set.test.ts +48 -14
  529. package/src/capabilities/config/set.verb.ts +14 -9
  530. package/src/capabilities/config/show.render.test.ts +77 -5
  531. package/src/capabilities/config/show.render.ts +8 -13
  532. package/src/capabilities/config/show.verb.ts +13 -9
  533. package/src/capabilities/config/types.ts +26 -4
  534. package/src/capabilities/config/unset.verb.ts +58 -0
  535. package/src/capabilities/create/byteEquality.subprocess.test.ts +2 -3
  536. package/src/capabilities/create/byteEquality.test.ts +95 -103
  537. package/src/capabilities/create/cliProjection.ts +227 -0
  538. package/src/capabilities/create/constants.ts +50 -0
  539. package/src/capabilities/create/create.mcp.test.ts +91 -7
  540. package/src/capabilities/create/create.render.ts +71 -7
  541. package/src/capabilities/create/create.test.ts +523 -162
  542. package/src/capabilities/create/create.verb.ts +361 -321
  543. package/src/capabilities/create/createGrammar.test.ts +865 -0
  544. package/src/capabilities/create/createHelp.ts +71 -0
  545. package/src/capabilities/create/createSurface.generated.ts +400 -0
  546. package/src/capabilities/create/crossCli.subprocess.test.ts +745 -0
  547. package/src/capabilities/create/cwdJail.test.ts +24 -5
  548. package/src/capabilities/create/generatorToVerbSpec.test.ts +186 -0
  549. package/src/capabilities/create/generatorToVerbSpec.ts +13 -11
  550. package/src/capabilities/create/index.ts +9 -14
  551. package/src/capabilities/create/messages.ts +18 -0
  552. package/src/capabilities/create/mount.ts +391 -0
  553. package/src/capabilities/create/pathJail.test.ts +90 -0
  554. package/src/capabilities/create/pathJail.ts +8 -5
  555. package/src/capabilities/create/pickGenerator.ts +40 -46
  556. package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
  557. package/src/capabilities/create/types.ts +29 -5
  558. package/src/capabilities/{standard/parity.test.ts → distribution.parity.test.ts} +24 -14
  559. package/src/capabilities/distribution.test.ts +122 -0
  560. package/src/capabilities/distribution.ts +54 -0
  561. package/src/capabilities/doctor/checks/checkKeStore.ts +9 -7
  562. package/src/capabilities/doctor/checks/checkPackageRefs.ts +82 -46
  563. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +5 -4
  564. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +125 -30
  565. package/src/capabilities/doctor/checks/checkShellCompletions.ts +113 -27
  566. package/src/capabilities/doctor/checks/index.ts +27 -0
  567. package/src/capabilities/doctor/checks/mcpCommand.test.ts +100 -0
  568. package/src/capabilities/doctor/checks/mcpCommand.ts +69 -0
  569. package/src/capabilities/doctor/checks/targetHealth.ts +274 -0
  570. package/src/capabilities/doctor/doctor.render.test.ts +24 -13
  571. package/src/capabilities/doctor/doctor.render.ts +45 -20
  572. package/src/capabilities/doctor/doctor.test.ts +158 -40
  573. package/src/capabilities/doctor/doctor.verb.ts +9 -5
  574. package/src/capabilities/doctor/runChecks.ts +65 -66
  575. package/src/capabilities/doctor/types.ts +21 -5
  576. package/src/capabilities/emptyRecovery.test.ts +44 -22
  577. package/src/capabilities/graph/examples.exec.test.ts +107 -0
  578. package/src/capabilities/graph/index.ts +1 -1
  579. package/src/capabilities/graph/inspect.render.ts +70 -22
  580. package/src/capabilities/graph/inspect.test.ts +260 -5
  581. package/src/capabilities/graph/inspect.verb.ts +18 -5
  582. package/src/capabilities/graph/query.render.ts +15 -3
  583. package/src/capabilities/graph/query.verb.ts +5 -4
  584. package/src/capabilities/graph/runQuery.ts +9 -7
  585. package/src/capabilities/index.ts +25 -19
  586. package/src/capabilities/info/collectInfo.ts +15 -10
  587. package/src/capabilities/info/info.render.ts +4 -3
  588. package/src/capabilities/info/info.verb.ts +4 -3
  589. package/src/capabilities/lazy.test.ts +125 -2
  590. package/src/capabilities/meta/complete.verb.ts +1 -1
  591. package/src/capabilities/meta/index.ts +1 -1
  592. package/src/capabilities/meta/mcp.verb.ts +10 -8
  593. package/src/capabilities/ontology/index.ts +15 -11
  594. package/src/capabilities/ontology/ontology.test.ts +6 -55
  595. package/src/capabilities/ontology/queries.ts +2 -2
  596. package/src/capabilities/ontology/render.ts +3 -4
  597. package/src/capabilities/ontology/verbs.ts +42 -83
  598. package/src/capabilities/prompt/index.ts +2 -2
  599. package/src/capabilities/prompt/prompt.render.ts +6 -2
  600. package/src/capabilities/prompt/prompt.test.ts +12 -6
  601. package/src/capabilities/prompt/types.ts +1 -1
  602. package/src/capabilities/prompt/verbs.ts +26 -14
  603. package/src/capabilities/reference.test.ts +63 -0
  604. package/src/capabilities/resources/provider.ts +367 -91
  605. package/src/capabilities/resources/resources.test.ts +411 -59
  606. package/src/capabilities/setup/buildPlan.ts +236 -0
  607. package/src/capabilities/setup/index.ts +7 -7
  608. package/src/capabilities/setup/mode.ts +74 -0
  609. package/src/capabilities/setup/operations/index.ts +74 -0
  610. package/src/capabilities/setup/operations/setupCompletions.ts +97 -24
  611. package/src/capabilities/setup/operations/setupConfig.ts +124 -0
  612. package/src/capabilities/setup/operations/setupGenerator.ts +397 -320
  613. package/src/capabilities/setup/operations/setupLsp.ts +329 -68
  614. package/src/capabilities/setup/operations/setupMcp.ts +137 -97
  615. package/src/capabilities/setup/operations/setupSkills.ts +336 -108
  616. package/src/capabilities/setup/plan.render.ts +241 -0
  617. package/src/capabilities/setup/plan.ts +236 -0
  618. package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
  619. package/src/capabilities/setup/setup.render.test.ts +281 -73
  620. package/src/capabilities/setup/setup.render.ts +45 -77
  621. package/src/capabilities/setup/setup.test.ts +972 -209
  622. package/src/capabilities/setup/setup.verb.ts +233 -74
  623. package/src/capabilities/setup/shell.test.ts +86 -0
  624. package/src/capabilities/setup/shell.ts +166 -14
  625. package/src/capabilities/setup/targets.ts +367 -0
  626. package/src/capabilities/setup/types.ts +18 -57
  627. package/src/capabilities/shared/assertExecOk.ts +68 -10
  628. package/src/capabilities/shared/index.ts +32 -0
  629. package/src/capabilities/shared/packageManager.test.ts +55 -0
  630. package/src/capabilities/shared/packageManager.ts +62 -6
  631. package/src/capabilities/skill/discover.ts +47 -9
  632. package/src/capabilities/skill/index.ts +1 -1
  633. package/src/capabilities/skill/render.ts +14 -14
  634. package/src/capabilities/skill/skill.test.ts +7 -5
  635. package/src/capabilities/skill/verbs.ts +9 -10
  636. package/src/capabilities/sources/collectStatus.ts +61 -51
  637. package/src/capabilities/sources/index.ts +2 -2
  638. package/src/capabilities/sources/installSkills.ts +86 -9
  639. package/src/capabilities/sources/runUpdate.ts +164 -141
  640. package/src/capabilities/sources/sources.test.ts +265 -119
  641. package/src/capabilities/sources/status.render.test.ts +53 -24
  642. package/src/capabilities/sources/status.render.ts +25 -30
  643. package/src/capabilities/sources/status.verb.ts +16 -9
  644. package/src/capabilities/sources/types.ts +18 -25
  645. package/src/capabilities/sources/update.render.ts +10 -3
  646. package/src/capabilities/sources/update.verb.ts +13 -24
  647. package/src/capabilities/surface.test.ts +165 -25
  648. package/src/capabilities/tier.parity.test.ts +144 -0
  649. package/src/capabilities/upgrade/runUpgrade.ts +8 -8
  650. package/src/capabilities/upgrade/upgrade.render.ts +4 -5
  651. package/src/capabilities/upgrade/upgrade.test.ts +3 -3
  652. package/src/capabilities/upgrade/upgrade.verb.ts +8 -4
  653. package/src/capabilities/version/index.ts +12 -0
  654. package/src/capabilities/version/version.test.ts +66 -0
  655. package/src/capabilities/version/version.verb.ts +39 -0
  656. package/src/constants.test.ts +8 -6
  657. package/src/constants.ts +78 -22
  658. package/src/identity.test.ts +348 -0
  659. package/src/index.ts +2 -2
  660. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +20 -15
  661. package/src/kernel/completion/complete.test.ts +12 -2
  662. package/src/kernel/completion/complete.ts +1 -1
  663. package/src/kernel/completion/emitScripts.test.ts +1 -1
  664. package/src/kernel/completion/emitScripts.ts +5 -3
  665. package/src/kernel/completion/entitySource.test.ts +185 -41
  666. package/src/kernel/completion/entitySource.ts +133 -110
  667. package/src/kernel/completion/model.test.ts +165 -13
  668. package/src/kernel/completion/model.ts +105 -14
  669. package/src/kernel/completion/parse.test.ts +4 -7
  670. package/src/kernel/completion/parse.ts +15 -0
  671. package/src/kernel/completion/resolve.test.ts +0 -1
  672. package/src/kernel/completion/safety.test.ts +104 -50
  673. package/src/kernel/completion/shellDrive.test.ts +611 -0
  674. package/src/kernel/completion/templates/bash.ts +7 -2
  675. package/src/kernel/completion/templates/fish.ts +28 -6
  676. package/src/kernel/completion/templates/index.ts +23 -0
  677. package/src/kernel/completion/types.ts +10 -3
  678. package/src/kernel/config/defaults.test.ts +108 -0
  679. package/src/kernel/config/defaults.ts +13 -23
  680. package/src/kernel/config/evaluateProjectConfig.ts +33 -11
  681. package/src/kernel/config/findProjectConfig.ts +4 -3
  682. package/src/kernel/config/firstRun.test.ts +44 -38
  683. package/src/kernel/config/firstRun.ts +24 -81
  684. package/src/kernel/config/globalConfig.ts +2 -2
  685. package/src/kernel/config/index.ts +5 -6
  686. package/src/kernel/config/paths.ts +17 -17
  687. package/src/kernel/config/readConfig.test.ts +246 -7
  688. package/src/kernel/config/readConfig.ts +8 -8
  689. package/src/kernel/config/schema.test.ts +50 -0
  690. package/src/kernel/config/schema.ts +100 -11
  691. package/src/kernel/config/types.ts +75 -19
  692. package/src/kernel/copy.test.ts +483 -0
  693. package/src/kernel/copy.ts +54 -0
  694. package/src/kernel/error/PragmaError.test.ts +6 -3
  695. package/src/kernel/error/PragmaError.ts +4 -2
  696. package/src/kernel/error/constants.ts +7 -4
  697. package/src/kernel/error/fromTaskError.ts +28 -6
  698. package/src/kernel/error/index.ts +1 -1
  699. package/src/kernel/error/recovery.test.ts +22 -45
  700. package/src/kernel/error/recovery.ts +36 -27
  701. package/src/kernel/error/renderError.ts +42 -1
  702. package/src/kernel/error/types.ts +25 -4
  703. package/src/kernel/index.ts +26 -0
  704. package/src/kernel/packs/collect.test.ts +195 -11
  705. package/src/kernel/packs/collect.ts +212 -61
  706. package/src/kernel/packs/compile.test.ts +293 -8
  707. package/src/kernel/packs/compile.ts +108 -15
  708. package/src/kernel/packs/disclosure.test.ts +5 -2
  709. package/src/kernel/packs/disclosure.ts +2 -2
  710. package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
  711. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +13 -13
  712. package/src/kernel/packs/graphql/index.ts +20 -0
  713. package/src/kernel/packs/graphqlSource.test.ts +6 -3
  714. package/src/kernel/packs/index.ts +40 -0
  715. package/src/kernel/packs/iri.test.ts +73 -0
  716. package/src/kernel/packs/iri.ts +70 -20
  717. package/src/kernel/packs/renderPack.ts +28 -7
  718. package/src/kernel/packs/resolveEntity.test.ts +213 -0
  719. package/src/kernel/packs/resolveEntity.ts +132 -34
  720. package/src/kernel/packs/runBodies.ts +16 -16
  721. package/src/kernel/packs/sample.ts +1 -1
  722. package/src/kernel/packs/schema.ts +114 -11
  723. package/src/kernel/packs/sparql/applyFilters.ts +16 -17
  724. package/src/kernel/packs/sparql/buildLookupQuery.ts +75 -3
  725. package/src/kernel/packs/sparql/index.ts +37 -0
  726. package/src/kernel/packs/sparql/runSelect.test.ts +104 -10
  727. package/src/kernel/packs/sparql/runSelect.ts +75 -37
  728. package/src/kernel/packs/toolDescription.test.ts +52 -5
  729. package/src/kernel/packs/types.ts +52 -4
  730. package/src/kernel/packs/uniqueness.ts +5 -5
  731. package/src/kernel/project/cli/buildProgram.test.ts +157 -17
  732. package/src/kernel/project/cli/buildProgram.ts +77 -18
  733. package/src/kernel/project/cli/constants.ts +34 -0
  734. package/src/kernel/project/cli/dispatch.test.ts +227 -3
  735. package/src/kernel/project/cli/dispatch.ts +250 -48
  736. package/src/kernel/project/cli/exitCodes.ts +1 -1
  737. package/src/kernel/project/cli/globalFlags.test.ts +117 -1
  738. package/src/kernel/project/cli/globalFlags.ts +130 -30
  739. package/src/kernel/project/cli/helpFormat.ts +14 -1
  740. package/src/kernel/project/cli/rootHelp.ts +140 -111
  741. package/src/kernel/project/cli/suggest.test.ts +33 -1
  742. package/src/kernel/project/cli/suggest.ts +25 -1
  743. package/src/kernel/project/cli/verbHelp.test.ts +30 -0
  744. package/src/kernel/project/cli/verbHelp.ts +23 -7
  745. package/src/kernel/project/mcp/buildServer.ts +18 -10
  746. package/src/kernel/project/mcp/envelope.ts +2 -2
  747. package/src/kernel/project/mcp/instructions.ts +12 -7
  748. package/src/kernel/project/mcp/mcpError.ts +1 -1
  749. package/src/kernel/project/mcp/parity.test.ts +42 -1
  750. package/src/kernel/project/mcp/prompts/index.ts +37 -0
  751. package/src/kernel/project/mcp/prompts/prompts.test.ts +120 -5
  752. package/src/kernel/project/mcp/prompts/provider.ts +22 -8
  753. package/src/kernel/project/mcp/prompts/source.ts +69 -68
  754. package/src/kernel/project/mcp/registerVerb.ts +56 -11
  755. package/src/kernel/project/mcp/serve.ts +13 -5
  756. package/src/kernel/project/mcp/toolDescriptions.test.ts +6 -2
  757. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
  758. package/src/kernel/render/contracts.ts +21 -0
  759. package/src/kernel/render/disclosure.ts +4 -2
  760. package/src/kernel/render/envelope.ts +2 -3
  761. package/src/kernel/render/formatters.ts +1 -1
  762. package/src/kernel/render/prefixes.test.ts +36 -0
  763. package/src/kernel/render/prefixes.ts +40 -13
  764. package/src/kernel/render/renderers.test.ts +244 -7
  765. package/src/kernel/render/renderers.ts +222 -20
  766. package/src/kernel/render/style.test.ts +75 -24
  767. package/src/kernel/render/style.ts +31 -1
  768. package/src/kernel/render/turtle.ts +222 -0
  769. package/src/kernel/runtime/graphpack/build.ts +29 -3
  770. package/src/kernel/runtime/graphpack/buildIndex.test.ts +46 -0
  771. package/src/kernel/runtime/graphpack/buildIndex.ts +53 -18
  772. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +5 -5
  773. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +3 -3
  774. package/src/kernel/runtime/graphpack/embedded/pack.stories.generated.ts +3 -0
  775. package/src/kernel/runtime/graphpack/embedded.ts +39 -13
  776. package/src/kernel/runtime/graphpack/graphpack.test.ts +205 -5
  777. package/src/kernel/runtime/graphpack/hash.ts +3 -2
  778. package/src/kernel/runtime/graphpack/index.ts +1 -1
  779. package/src/kernel/runtime/graphpack/manifest.ts +114 -12
  780. package/src/kernel/runtime/graphpack/read.ts +5 -11
  781. package/src/kernel/runtime/graphpack/schemas.ts +74 -0
  782. package/src/kernel/runtime/graphpack/stories.ts +84 -0
  783. package/src/kernel/runtime/graphpack/types.ts +61 -48
  784. package/src/kernel/runtime/loadSession.ts +1 -1
  785. package/src/kernel/runtime/paths.ts +64 -15
  786. package/src/kernel/runtime/probe.test.ts +8 -4
  787. package/src/kernel/runtime/probe.ts +6 -6
  788. package/src/kernel/runtime/readEntity.ts +477 -32
  789. package/src/kernel/runtime/refs/gitOps.ts +1 -19
  790. package/src/kernel/runtime/refs/index.ts +39 -0
  791. package/src/kernel/runtime/refs/parseRef.ts +8 -8
  792. package/src/kernel/runtime/refs/resolve.ts +82 -66
  793. package/src/kernel/runtime/resolveSources.test.ts +63 -24
  794. package/src/kernel/runtime/resolveSources.ts +36 -25
  795. package/src/kernel/runtime/storeReadiness.ts +10 -10
  796. package/src/kernel/runtime/storeless.test.ts +1 -1
  797. package/src/kernel/runtime/types.ts +15 -1
  798. package/src/kernel/runtime/wasmEmbed.test.ts +56 -55
  799. package/src/kernel/spec/emitReference.test.ts +3 -3
  800. package/src/kernel/spec/emitReference.ts +242 -34
  801. package/src/kernel/spec/emitSurface.ts +57 -11
  802. package/src/kernel/spec/surfaceConformance.test.ts +4 -2
  803. package/src/kernel/spec/surfaceConformance.ts +8 -0
  804. package/src/kernel/spec/types.ts +277 -13
  805. package/src/kernel/spec/validate.ts +2 -1
  806. package/src/kernel/vocabulary.test.ts +164 -0
  807. package/src/kernel/vocabulary.ts +146 -0
  808. package/src/testing/PARITY_GAPS.ts +8 -2
  809. package/src/testing/behavioral/README.md +3 -3
  810. package/src/testing/behavioral/completion.test.ts +19 -6
  811. package/src/testing/behavioral/docExamples.test.ts +14 -0
  812. package/src/testing/behavioral/errorMatrix.mcp.test.ts +6 -5
  813. package/src/testing/behavioral/errorMatrix.storeless.test.ts +1 -1
  814. package/src/testing/behavioral/exitCodes.e2e.test.ts +6 -5
  815. package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
  816. package/src/testing/behavioral/harness.foundation.test.ts +14 -5
  817. package/src/testing/behavioral/journeys.cli.test.ts +117 -76
  818. package/src/testing/behavioral/journeys.defaultPack.test.ts +88 -182
  819. package/src/testing/behavioral/journeys.firstInstall.test.ts +167 -0
  820. package/src/testing/behavioral/journeys.implementation.test.ts +206 -0
  821. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +2 -2
  822. package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +9 -6
  823. package/src/testing/behavioral/journeys.packageStories.test.ts +188 -0
  824. package/src/testing/behavioral/liveReadSurface.ts +4 -3
  825. package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
  826. package/src/testing/behavioral/mcpSurface.test.ts +10 -5
  827. package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
  828. package/src/testing/behavioral/staleCommands.test.ts +10 -0
  829. package/src/testing/eval/__snapshots__/eval.test.ts.snap +7 -7
  830. package/src/testing/eval/cases/assembly.ts +13 -6
  831. package/src/testing/eval/cases/effectful.ts +28 -15
  832. package/src/testing/eval/cases/readNouns.ts +22 -20
  833. package/src/testing/eval/cases/stable.ts +5 -1
  834. package/src/testing/eval/eval.test.ts +7 -1
  835. package/src/testing/fixtures/blockGraph.ts +79 -0
  836. package/src/testing/fixtures/fixtureCapability.ts +45 -1
  837. package/src/testing/fixtures/graph/canonical.ts +94 -5
  838. package/src/testing/fixtures/graph/defaultPack.ts +7 -6
  839. package/src/testing/fixtures/graph/owlExport.ts +7 -5
  840. package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
  841. package/src/testing/helpers/fixtureGraph.ts +33 -16
  842. package/src/testing/helpers/packRuntime.ts +2 -3
  843. package/src/testing/helpers/projectCli.ts +2 -1
  844. package/src/testing/helpers/projectMcp.ts +38 -6
  845. package/src/testing/helpers/runCli.ts +35 -18
  846. package/src/testing/perf/budgets.test.ts +24 -9
  847. package/src/testing/perf/budgets.ts +76 -12
  848. package/src/testing/perf/codegen.test.ts +126 -0
  849. package/src/testing/perf/globalSetup.test.ts +286 -0
  850. package/src/testing/perf/globalSetup.ts +611 -14
  851. package/src/testing/perf/measure.test.ts +38 -0
  852. package/src/testing/perf/measure.ts +23 -4
  853. package/src/testing/setupXdgIsolation.ts +81 -21
  854. package/src/testing/tempRoot.globalSetup.ts +122 -0
  855. package/src/types.ts +2 -2
  856. package/dist/pragma +0 -0
  857. package/src/capabilities/block/blockList.test.ts +0 -79
  858. package/src/capabilities/block/blockList.verb.ts +0 -163
  859. package/src/capabilities/block/index.ts +0 -25
  860. package/src/capabilities/block/pack.ts +0 -166
  861. package/src/capabilities/block/parity.test.ts +0 -187
  862. package/src/capabilities/block/tierChain.ts +0 -78
  863. package/src/capabilities/colophon/pragmaColophon.ts +0 -66
  864. package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -152
  865. package/src/capabilities/create/templates.embedded.generated.ts +0 -53
  866. package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -41
  867. package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
  868. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -67
  869. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -60
  870. package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
  871. package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
  872. package/src/capabilities/modifier/index.ts +0 -15
  873. package/src/capabilities/modifier/pack.ts +0 -64
  874. package/src/capabilities/standard/index.ts +0 -18
  875. package/src/capabilities/standard/pack.ts +0 -128
  876. package/src/capabilities/tier/index.ts +0 -19
  877. package/src/capabilities/tier/lookup.render.test.ts +0 -72
  878. package/src/capabilities/tier/lookup.render.ts +0 -59
  879. package/src/capabilities/tier/lookup.test.ts +0 -83
  880. package/src/capabilities/tier/lookup.verb.ts +0 -44
  881. package/src/capabilities/tier/pack.ts +0 -28
  882. package/src/capabilities/tier/runLookup.ts +0 -87
  883. package/src/capabilities/token/addConfig.render.ts +0 -27
  884. package/src/capabilities/token/addConfig.test.ts +0 -62
  885. package/src/capabilities/token/addConfig.verb.ts +0 -40
  886. package/src/capabilities/token/index.ts +0 -19
  887. package/src/capabilities/token/pack.ts +0 -58
  888. package/src/capabilities/token/runAddConfig.ts +0 -95
  889. package/src/kernel/completion/bashDrive.test.ts +0 -73
  890. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
  891. package/src/kernel/runtime/graphpack/embedded/sample.ttl +0 -39
  892. package/src/kernel/runtime/lock.ts +0 -90
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * `create` behaviour: real generation + stamp, the SEC-2 path jail, the
3
- * lazy-React discipline, and the generator→grammar adapter parity guard.
3
+ * lazy-React discipline, and the projection-fidelity guard (the committed
4
+ * generated surface vs the live generators).
4
5
  * The MCP plan-first/confirm parity lives in create.mcp.test.ts; the
5
6
  * byte-equality goldens in byteEquality.test.ts.
6
7
  */
@@ -16,6 +17,7 @@ import {
16
17
  import { tmpdir } from "node:os";
17
18
  import { dirname, join, resolve } from "node:path";
18
19
  import { fileURLToPath } from "node:url";
20
+ import chalk from "chalk";
19
21
  import { describe, expect, it } from "vitest";
20
22
  import { PragmaError } from "../../kernel/error/PragmaError.js";
21
23
  import {
@@ -24,15 +26,10 @@ import {
24
26
  } from "../../kernel/project/cli/dispatch.js";
25
27
  import { bootRuntime } from "../../kernel/runtime/boot.js";
26
28
  import type { GlobalFlags } from "../../kernel/runtime/types.js";
27
- import type { ParamSpec } from "../../kernel/spec/types.js";
28
- import {
29
- createApplicationVerb,
30
- createComponentVerb,
31
- createPackageVerb,
32
- INCLUDE_FLAG_ALIASES,
33
- isModuleNotFound,
34
- } from "./create.verb.js";
35
- import { generatorToParams } from "./generatorToVerbSpec.js";
29
+ import { CREATE_GENERATORS } from "./constants.js";
30
+ import { createVerbs, isModuleNotFound } from "./create.verb.js";
31
+ import { CREATE_SURFACE } from "./createSurface.generated.js";
32
+ import { createModule } from "./index.js";
36
33
 
37
34
  const FLAGS: GlobalFlags = {
38
35
  llm: false,
@@ -40,6 +37,7 @@ const FLAGS: GlobalFlags = {
40
37
  format: "plain",
41
38
  verbose: false,
42
39
  };
40
+ const JSON_FLAGS: GlobalFlags = { ...FLAGS, format: "json" };
43
41
  const YES: MutationFlags = { dryRun: false, undo: false, yes: true };
44
42
  const freshCwd = (): string => mkdtempSync(join(tmpdir(), "pragma-create-"));
45
43
 
@@ -48,21 +46,29 @@ async function runIn(
48
46
  dir: string,
49
47
  params: Record<string, unknown>,
50
48
  mutation: MutationFlags = YES,
49
+ verb = createVerbs.component,
50
+ flags: GlobalFlags = FLAGS,
51
51
  ) {
52
52
  const prev = process.cwd();
53
53
  process.chdir(dir);
54
54
  try {
55
- return await executeVerb(
56
- createComponentVerb,
57
- params,
58
- mutation,
59
- bootRuntime(FLAGS, dir),
60
- );
55
+ return await executeVerb(verb, params, mutation, bootRuntime(flags, dir));
61
56
  } finally {
62
57
  process.chdir(prev);
63
58
  }
64
59
  }
65
60
 
61
+ /**
62
+ * The described-effect rows of a `--format json` dry run.
63
+ *
64
+ * The plain preview renders through summon's shared effect formatter now, so
65
+ * `describeEffect`'s `Write file: <path> (N bytes)` spelling — with the byte
66
+ * count two cells below depend on — lives on the JSON surface, which this
67
+ * change deliberately left alone.
68
+ */
69
+ const jsonPlan = (stdout: string | undefined): string[] =>
70
+ (JSON.parse(stdout ?? "{}").data as { plan: string[] }).plan;
71
+
66
72
  const walk = (dir: string, base = ""): string[] =>
67
73
  readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
68
74
  e.isDirectory()
@@ -83,10 +89,16 @@ describe("create — real generation + stamp", () => {
83
89
  expect(outcome.exitCode).toBe(0);
84
90
  const main = join(dir, "src/components/Widget/Widget.tsx");
85
91
  expect(existsSync(main)).toBe(true);
86
- expect(readFileSync(main, "utf-8").split("\n")[0]).toBe(
87
- "// Generated by @canonical/summon-component:react v0.1.0",
92
+ // The stamp version tracks the released generator version (a walk-up of
93
+ // its own manifest), so pin the shape, not a frozen number.
94
+ expect(readFileSync(main, "utf-8").split("\n")[0]).toMatch(
95
+ /^\/\/ Generated by @canonical\/summon-component:react v\d+\.\d+\.\d+/,
88
96
  );
89
- });
97
+ // Explicit timeout, like the package's other real-run gates: this drives a
98
+ // full generator run (~2.4s idle), and under a contended CI matrix the 5s
99
+ // vitest default fails it on load, not on a defect — both build-matrix
100
+ // legs timed out at 5000ms on a run whose import phase alone took 88s.
101
+ }, 60_000);
90
102
 
91
103
  it("--dry-run writes nothing and previews effects (no Prompt lines)", async () => {
92
104
  const dir = freshCwd();
@@ -101,6 +113,191 @@ describe("create — real generation + stamp", () => {
101
113
  expect(walk(dir)).toEqual([]); // nothing written
102
114
  });
103
115
 
116
+ it("--dry-run previews through summon's effect formatter, not the raw dump", async () => {
117
+ // pragma and summon scaffold through the SAME projection and write
118
+ // byte-identical trees, so a preview describing that work differently in
119
+ // each was a difference with nothing behind it. The rows here are
120
+ // `formatEffectLine`'s; the filtering is `visiblePlanEffects`'.
121
+ const dir = freshCwd();
122
+ const outcome = await runIn(
123
+ dir,
124
+ {
125
+ framework: "react",
126
+ componentPath: "Widget",
127
+ withStyles: false,
128
+ withStories: false,
129
+ withSsrTests: false,
130
+ },
131
+ { dryRun: true, undo: false, yes: false },
132
+ );
133
+ expect(outcome.exitCode).toBe(0);
134
+ const stdout = outcome.stdout ?? "";
135
+
136
+ // The shared shape: a titled plan, kind-columned rows, the closing line.
137
+ expect(stdout.startsWith("Plan:\n")).toBe(true);
138
+ expect(stdout).toContain("├─ Create file Widget/Widget.tsx");
139
+ expect(stdout).toContain("└─ Info ");
140
+ expect(
141
+ stdout.endsWith("\nDry-run complete. No files were modified.\n"),
142
+ ).toBe(true);
143
+
144
+ // The noise the filter exists to remove is gone: no internal probes, no
145
+ // directory repeated once per file it holds, no kernel bullet dump.
146
+ expect(stdout).not.toContain("Dry run — planned effects:");
147
+ expect(stdout).not.toContain("Check exists:");
148
+ expect(stdout).not.toContain("Log [");
149
+ expect(stdout.split("\n").filter((l) => l.includes("Create dir"))).toEqual([
150
+ "├─ Create dir Widget",
151
+ ]);
152
+ });
153
+
154
+ it("--dry-run stays ANSI-free when stdout is not a terminal (PROTECTED)", async () => {
155
+ // The row formatter used to call chalk directly, so whether a preview
156
+ // carried escapes was decided by chalk's environment detection at the
157
+ // moment of the call. pragma's gate is stricter than chalk's: it demands
158
+ // an ATTENDED stdout as well as a usable colour level. nx exports
159
+ // FORCE_COLOR to every test task, which is exactly the condition where the
160
+ // two disagree — chalk would colour a piped preview that every other
161
+ // pragma renderer, and `doctor.render.test.ts`'s pin on redirected output,
162
+ // leaves plain.
163
+ const dir = freshCwd();
164
+ const level = chalk.level;
165
+ try {
166
+ chalk.level = 3; // as FORCE_COLOR would leave it
167
+ const outcome = await runIn(
168
+ dir,
169
+ {
170
+ framework: "react",
171
+ componentPath: "Widget",
172
+ withStyles: false,
173
+ withStories: false,
174
+ withSsrTests: false,
175
+ },
176
+ { dryRun: true, undo: false, yes: false },
177
+ );
178
+ expect(outcome.exitCode).toBe(0);
179
+ // Not a TTY under vitest, so the decision is "no colour" — and the
180
+ // formatter is told that rather than left to work it out.
181
+ expect(process.stdout.isTTY).not.toBe(true);
182
+ expect(outcome.stdout ?? "").not.toContain("\u001B[");
183
+ // Still the shared shape, just uncoloured.
184
+ expect(outcome.stdout).toContain("├─ Create file Widget/Widget.tsx");
185
+ } finally {
186
+ chalk.level = level;
187
+ }
188
+ });
189
+
190
+ it("--dry-run PLANS the generator's logs instead of performing them", async () => {
191
+ // A preview that performs an effect is not a preview of that effect. The
192
+ // interpreter's recorded `Log`s used to be written to stderr on the way
193
+ // through AND listed as plan rows, so every line the generator emitted
194
+ // appeared twice in one invocation.
195
+ const dir = freshCwd();
196
+ const written: string[] = [];
197
+ const realWrite = process.stderr.write.bind(process.stderr);
198
+ process.stderr.write = ((chunk: string | Uint8Array) => {
199
+ written.push(String(chunk));
200
+ return true;
201
+ }) as typeof process.stderr.write;
202
+ let outcome: Awaited<ReturnType<typeof executeVerb>>;
203
+ try {
204
+ outcome = await runIn(
205
+ dir,
206
+ { framework: "react", componentPath: "Widget" },
207
+ { dryRun: true, undo: false, yes: false },
208
+ );
209
+ } finally {
210
+ process.stderr.write = realWrite;
211
+ }
212
+ expect(outcome.exitCode).toBe(0);
213
+ // The generator's opening line is planned exactly once…
214
+ const line = "Generating React component: Widget";
215
+ expect((outcome.stdout ?? "").split(line).length - 1).toBe(1);
216
+ // …and performed never.
217
+ expect(written.join("").includes(line)).toBe(false);
218
+ });
219
+
220
+ it("application --dry-run renders carried assets as WRITES — no Copy rows (§L item 6)", async () => {
221
+ // copy()→rawFile() reclassified ~62 carried assets from CopyFile to
222
+ // verbatim WriteFile, changing every dry-run/--llm/json plan row from
223
+ // `Copy file: <src> → <dest>` to `Write file: <dest> (N bytes)`. That is
224
+ // a DELIBERATE observable change (PLAN §L); this literal pin keeps both
225
+ // an accidental reversion and a silent re-rendering visible.
226
+ //
227
+ // Read off `--format json`. The pin is the same literal it always was —
228
+ // only the surface it is read from moved, because the plain preview now
229
+ // renders through summon's effect formatter while the JSON `plan` array
230
+ // stays the `describeEffect` strings it has always carried.
231
+ const dir = freshCwd();
232
+ const prev = process.cwd();
233
+ process.chdir(dir);
234
+ let outcome: Awaited<ReturnType<typeof executeVerb>>;
235
+ try {
236
+ outcome = await executeVerb(
237
+ // The honest variance cast from this file's typed
238
+ // VerbSpec<…, GeneratorResult> down to the unknown-result shape
239
+ // executeVerb takes — the same erasure the mount's `leafVerb`
240
+ // performs (`as VerbSpec`) on the production path.
241
+ createVerbs.application as unknown as Parameters<typeof executeVerb>[0],
242
+ { appPath: "my-app", runInstall: false },
243
+ { dryRun: true, undo: false, yes: false },
244
+ bootRuntime(JSON_FLAGS, dir),
245
+ );
246
+ } finally {
247
+ process.chdir(prev);
248
+ }
249
+ expect(outcome.exitCode).toBe(0);
250
+ const plan = jsonPlan(outcome.stdout).join("\n");
251
+ // A known carried (formerly copied) asset plans as a write…
252
+ expect(plan).toMatch(
253
+ /^Write file: my-app\/\.storybook\/preview\.ts \(\d+ bytes\)$/m,
254
+ );
255
+ // …and no plan row renders as a copy anywhere.
256
+ expect(plan).not.toContain("Copy file:");
257
+ expect(walk(dir)).toEqual([]); // still a dry run
258
+ }, 60_000);
259
+
260
+ it("--dry-run reports the bytes the real run writes (post-stamp)", async () => {
261
+ // The mock previewer never called `onEffectStart`, so summon's stamping
262
+ // transform did not run and every planned byte count under-reported the
263
+ // written file by the stamp's length. The honest previewer runs it.
264
+ const params = {
265
+ framework: "react",
266
+ componentPath: "src/components/Widget",
267
+ withStyles: true,
268
+ withStories: false,
269
+ withSsrTests: false,
270
+ };
271
+ const previewDir = freshCwd();
272
+ const preview = await runIn(
273
+ previewDir,
274
+ params,
275
+ { dryRun: true, undo: false, yes: false },
276
+ createVerbs.component,
277
+ JSON_FLAGS,
278
+ );
279
+ expect(preview.exitCode).toBe(0);
280
+ expect(walk(previewDir)).toEqual([]);
281
+
282
+ const planned = new Map<string, number>();
283
+ for (const line of jsonPlan(preview.stdout)) {
284
+ const match = /^Write file: (.+) \((\d+) bytes\)$/.exec(line);
285
+ if (match) planned.set(match[1] as string, Number(match[2]));
286
+ }
287
+ expect(planned.size).toBeGreaterThan(0);
288
+
289
+ const realDir = freshCwd();
290
+ expect((await runIn(realDir, params)).exitCode).toBe(0);
291
+ for (const [relative, bytes] of planned) {
292
+ expect({
293
+ file: relative,
294
+ bytes: readFileSync(join(realDir, relative), "utf-8").length,
295
+ }).toEqual({ file: relative, bytes });
296
+ }
297
+ // Same set of files, not just the same counts for the ones checked.
298
+ expect(walk(realDir).sort()).toEqual([...planned.keys()].sort());
299
+ });
300
+
104
301
  it("--undo reverses a run", async () => {
105
302
  const dir = freshCwd();
106
303
  await runIn(dir, {
@@ -123,19 +320,27 @@ describe("create — real generation + stamp", () => {
123
320
  );
124
321
  expect(outcome.exitCode).toBe(0);
125
322
  expect(outcome.stdout).toMatch(/Undid \d+ step/);
126
- });
323
+ // TWO real runs (generate, then undo) — the same load-sensitivity as the
324
+ // stamp test above, doubled; same explicit ceiling.
325
+ }, 60_000);
127
326
 
128
- it("rejects an unknown framework with INVALID_INPUT", async () => {
327
+ it("rejects an unknown framework with INVALID_INPUT", () => {
129
328
  const dir = freshCwd();
130
- // coerceParam rejects the enum before run, so drive run directly via a bad
131
- // framework param to exercise pickGenerator's own guard too.
329
+ // coerceParam rejects the enum before run; the binding run's own path
330
+ // mapping guards direct callers too (framework is required — no default).
132
331
  const runtime = bootRuntime(FLAGS, dir);
133
- await expect(
134
- createComponentVerb.run({ framework: "vue" }, {
332
+ expect(() =>
333
+ createVerbs.component.run({ framework: "vue" }, {
334
+ ...runtime,
335
+ interaction: { isTTY: false, transport: "cli", yes: true },
336
+ } as never),
337
+ ).toThrow(PragmaError);
338
+ expect(() =>
339
+ createVerbs.component.run({}, {
135
340
  ...runtime,
136
341
  interaction: { isTTY: false, transport: "cli", yes: true },
137
342
  } as never),
138
- ).rejects.toBeInstanceOf(PragmaError);
343
+ ).toThrow(/framework/);
139
344
  });
140
345
  });
141
346
 
@@ -147,26 +352,88 @@ describe("SEC-2 path jail (PROTECTED)", () => {
147
352
  for (const [label, value] of cases) {
148
353
  it(`rejects ${label} with a PragmaError before any effect`, async () => {
149
354
  const dir = freshCwd();
150
- // The jail throws in `run`, before any effect; the projector maps it to an
151
- // exit code, but exercised directly here `executeVerb` propagates it.
355
+ // Since the round-9 reorder the shared VALIDATOR (`validateAnswers`,
356
+ // running before the jail) refuses these two classes first — the same
357
+ // line in both hosts; the jail below stays the backstop. The jail's
358
+ // OWN tier is driven by the symlink cells here (the one class the
359
+ // value-only validator cannot see) and by pathJail.test.ts directly.
152
360
  await expect(
153
361
  runIn(dir, { framework: "react", componentPath: value }),
154
- ).rejects.toBeInstanceOf(PragmaError);
362
+ ).rejects.toMatchObject({
363
+ name: "PragmaError",
364
+ code: "INVALID_INPUT",
365
+ // The validator's line — flag spelling, value echo, detail —
366
+ message: expect.stringContaining(`Invalid --component-path "${value}"`),
367
+ // — carrying the validator tier's ONE workspace hint for both
368
+ // escape classes (the jail's `..`-branch message; the jail keeps
369
+ // its own per-branch hints — "Use a path relative to the current
370
+ // directory." on absolute — pinned in pathJail.test.ts).
371
+ recovery: { message: "The path must stay inside the workspace." },
372
+ });
155
373
  expect(walk(dir)).toEqual([]);
156
374
  });
157
375
  }
158
376
 
159
- it("rejects a symlink that escapes the workspace (realpath)", async () => {
377
+ it("a NON-escape rejection of the jailed param stays recovery-FREE — the negative direction of the escape narrowing", async () => {
378
+ const dir = freshCwd();
379
+ // The other half of the two escape rows above: `isEscapeValue` keys the
380
+ // workspace hint on the VALUE class, so a casing complaint about the
381
+ // same param must carry NO recovery at all — answering "must be in
382
+ // PascalCase" with "The path must stay inside the workspace." would be
383
+ // affirmatively false guidance. Asserted on the thrown object directly:
384
+ // `toMatchObject` cannot pin a field's ABSENCE.
385
+ const caught: unknown = await runIn(dir, {
386
+ framework: "react",
387
+ componentPath: "not-pascal",
388
+ }).then(
389
+ () => undefined,
390
+ (cause: unknown) => cause,
391
+ );
392
+ expect(caught, "the casing rejection did not throw").toBeInstanceOf(
393
+ PragmaError,
394
+ );
395
+ const error = caught as PragmaError;
396
+ expect(error.code).toBe("INVALID_INPUT");
397
+ expect(error.message).toContain('Invalid --component-path "not-pascal"');
398
+ expect(error.recovery).toBeUndefined();
399
+ expect(walk(dir)).toEqual([]);
400
+ });
401
+
402
+ it("rejects a symlink that escapes the workspace — the JAIL tier (realpath)", async () => {
160
403
  const root = freshCwd();
161
404
  const outside = freshCwd();
162
- // A symlink `link` inside the workspace pointing OUT of it.
405
+ // A symlink `link` inside the workspace pointing OUT of it: relative, no
406
+ // `..`, PascalCase basename — the validator passes it, so the jail's own
407
+ // spelling and covenant `recovery` field prove which tier refused.
163
408
  symlinkSync(outside, join(root, "link"));
164
409
  await expect(
165
410
  runIn(root, { framework: "react", componentPath: "link/Widget" }),
166
- ).rejects.toBeInstanceOf(PragmaError);
411
+ ).rejects.toMatchObject({
412
+ name: "PragmaError",
413
+ code: "INVALID_INPUT",
414
+ message: 'Invalid componentPath "link/Widget".',
415
+ recovery: { message: "The path resolves outside the workspace." },
416
+ });
167
417
  expect(existsSync(join(outside, "Widget"))).toBe(false);
168
418
  });
169
419
 
420
+ it("application/react: a symlink escape lands in the jail — PATH_PARAM.application is pinned", async () => {
421
+ const root = freshCwd();
422
+ const outside = freshCwd();
423
+ symlinkSync(outside, join(root, "link"));
424
+ // `link/app` passes `validateAppPath` (relative, no `..`); only the
425
+ // jail's realpath check — bound to `appPath` via PATH_PARAM — refuses.
426
+ await expect(
427
+ runIn(root, { appPath: "link/app" }, YES, createVerbs.application),
428
+ ).rejects.toMatchObject({
429
+ name: "PragmaError",
430
+ code: "INVALID_INPUT",
431
+ message: 'Invalid appPath "link/app".',
432
+ recovery: { message: "The path resolves outside the workspace." },
433
+ });
434
+ expect(walk(outside)).toEqual([]);
435
+ });
436
+
170
437
  it("accepts an in-workspace path", async () => {
171
438
  const dir = freshCwd();
172
439
  mkdirSync(join(dir, "packages"), { recursive: true });
@@ -217,9 +484,19 @@ describe("lazy-React discipline (PROTECTED)", () => {
217
484
  "@canonical/summon-component",
218
485
  "@canonical/summon-package",
219
486
  "@canonical/summon-application",
487
+ // The generators pull summon-core, and summon-core is what costs the
488
+ // fast paths (+43 MB RSS once it loads). Dropping the `type` from one of
489
+ // the four `import type … from "@canonical/summon-core"` lines in this
490
+ // directory is a one-word regression nothing else catches.
491
+ "@canonical/summon-core",
220
492
  ];
221
493
  for (const file of graph) {
222
- const src = readFileSync(file, "utf-8");
494
+ // Type-only imports are erased before runtime, so they load nothing —
495
+ // strip them before asking what the file actually pulls in.
496
+ const src = readFileSync(file, "utf-8").replace(
497
+ /\bimport\s+type\b[^;]*;/g,
498
+ "",
499
+ );
223
500
  for (const pkg of forbidden) {
224
501
  const esc = pkg.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
225
502
  expect(
@@ -251,158 +528,184 @@ describe("lazy-React discipline (PROTECTED)", () => {
251
528
  });
252
529
  });
253
530
 
254
- describe("generator→grammar adapter parity (PROTECTED)", () => {
255
- // The static mirrors in create.verb.ts are AUTHORITATIVE for omitted CLI
256
- // flags: dispatch.extractParams fills ParamSpec.default when a flag is absent,
257
- // so a drifted mirror default silently overrides the generator's own default.
258
- // These guards assert the EMITTED grammar (names, kinds, defaults, choices)
259
- // still matches the real generators for all three create nouns — the
260
- // byte-equality goldens can't catch this (they pass every param explicitly).
261
-
262
- /** Drop `doc` (help text is intentionally paraphrased in the mirrors) so the
263
- * comparison is purely behavioural: names, kinds, defaults, choices. */
264
- const behavioural = (
265
- params: readonly ParamSpec[],
266
- ): Record<string, unknown>[] =>
267
- params.map((p) => {
268
- const clone: Record<string, unknown> = { ...p };
269
- delete clone.doc;
270
- return clone;
271
- });
531
+ describe("projection fidelity — the committed surface IS the live generators (PROTECTED)", () => {
532
+ // createSurface.generated.ts is what the params, the mount, completion, and
533
+ // the MCP schemas derive from. This test loads the LIVE generators
534
+ // (test-only — production paths never do) and asserts the committed
535
+ // projection deep-equals them, so drift fails the build in the same run
536
+ // that regenerating (`bun run scripts/build.ts`) fixes. The bytes read
537
+ // here are the bytes git holds: the gate's own build runs this codegen in
538
+ // CHECK mode (PRAGMA_BUILD_SKIP_DOCS=1 in scripts/build.ts), failing on a
539
+ // stale committed module instead of rewriting it before workers start.
272
540
 
273
- /** `runInstall` is a DELIBERATE divergence (package + application): the real
274
- * generators default it `true`, but the CLI grammar has no `--no-` form, so
275
- * the mirror makes install opt-in (`default:false`, enabled by `--run-install`).
276
- * Apply that same override to the generator side before comparing. */
277
- const applyRunInstallOverride = (params: readonly ParamSpec[]): ParamSpec[] =>
278
- params.map((p) =>
279
- p.name === "runInstall" ? ({ ...p, default: false } as ParamSpec) : p,
541
+ it("every committed entry deep-equals projectGenerator over the live generator", async () => {
542
+ const [{ projectGenerator }, { pickGenerator }] = await Promise.all([
543
+ import("@canonical/summon-core/projection"),
544
+ import("./pickGenerator.js"),
545
+ ]);
546
+ const declaredPaths = Object.values(CREATE_GENERATORS).flatMap(
547
+ (binding) => binding.paths,
548
+ );
549
+ expect(Object.keys(CREATE_SURFACE).sort()).toEqual(
550
+ [...declaredPaths].sort(),
280
551
  );
552
+ for (const commandPath of declaredPaths) {
553
+ expect(
554
+ projectGenerator(commandPath.split("/"), pickGenerator(commandPath)),
555
+ `projection drift for ${commandPath} — rerun scripts/build.ts`,
556
+ ).toEqual(CREATE_SURFACE[commandPath]);
557
+ }
558
+ });
281
559
 
282
- it("component: framework collapse + shared confirms match the react generator", async () => {
283
- const { generators } = await import("@canonical/summon-component");
284
- const real = generatorToParams(
285
- (generators as Record<string, { prompts: unknown[] }>)["component/react"]
286
- .prompts as never,
560
+ it("every declared positional path prompt validates `..`/absolute escapes — the claim in pathJail.ts and contract §3, enforced", async () => {
561
+ // pathJail.ts and §3 state as FACT that the prompts' own validators
562
+ // reject absolute/`..` uniformly across the declared path prompts — in
563
+ // BOTH hosts, upstream of pragma's jail. Summon has no jail at all, so
564
+ // a positional path prompt landing WITHOUT a validate silently reopens
565
+ // the round-9 escape (summon scaffolds outside the invocation cwd,
566
+ // exit 0) with every suite green. This cell ties the claim to the
567
+ // DECLARATION: every `positional: true` text prompt on the declared
568
+ // bindings' live generators must reject both escape classes.
569
+ const { pickGenerator } = await import("./pickGenerator.js");
570
+ const declaredPaths = Object.values(CREATE_GENERATORS).flatMap(
571
+ (binding) => binding.paths,
287
572
  );
288
- const verb = createComponentVerb.params;
573
+ const audited: string[] = [];
574
+ for (const commandPath of declaredPaths) {
575
+ for (const prompt of pickGenerator(commandPath).prompts) {
576
+ if (prompt.positional !== true || prompt.type !== "text") continue;
577
+ audited.push(`${commandPath}:${prompt.name}`);
578
+ expect(
579
+ prompt.validate,
580
+ `${commandPath}'s ${prompt.name} declares no validate — the shared escape tier is gone for it`,
581
+ ).toBeDefined();
582
+ // PascalCase-SAFE vectors, asserted on the message CONTENT. The
583
+ // original "../x"/"/abs/x" were refused by component's CASING rule
584
+ // alone (basename "x"), so deleting both escape branches kept the
585
+ // three componentPath rows green (round-11 F1, proven live). "../X"
586
+ // and "/abs/X" pass every name rule, and the `..`/"absolute"
587
+ // substring pins WHICH rule refused — a rejection from another tier
588
+ // (or an accepting `true`) reddens the row either way.
589
+ expect(
590
+ prompt.validate?.("../X"),
591
+ `${commandPath}'s ${prompt.name} does not refuse a \`..\` escape with the escape tier's message`,
592
+ ).toContain("..");
593
+ expect(
594
+ prompt.validate?.("/abs/X"),
595
+ `${commandPath}'s ${prompt.name} does not refuse an absolute path with the escape tier's message`,
596
+ ).toContain("absolute");
597
+ }
598
+ }
599
+ // The audited set, pinned: a NEW positional path prompt must join this
600
+ // list (and pass the vectors above) — deliberate, like the conformance
601
+ // matrix's declaration-completeness, so scope-shrink is visible too.
602
+ expect(audited.sort()).toEqual([
603
+ "application/react:appPath",
604
+ "component/lit:componentPath",
605
+ "component/react:componentPath",
606
+ "component/svelte:componentPath",
607
+ ]);
608
+ });
289
609
 
290
- // The verb SYNTHESIZES a `framework` enum (the 3 framework generators
291
- // collapse to one verb): react|svelte|lit, default react — no generator
292
- // prompt corresponds to it.
293
- expect(verb.find((p) => p.name === "framework")).toMatchObject({
294
- kind: "enum",
295
- values: ["react", "svelte", "lit"],
296
- default: "react",
297
- });
610
+ it("component params are the FRAMEWORK UNION of the declared leaves", () => {
611
+ const params = createVerbs.component.params;
612
+ const names = params.map((p) => p.name);
613
+ // First-seen order over declared framework order, positional enum first.
614
+ expect(names).toEqual([
615
+ "framework",
616
+ "componentPath",
617
+ "withStyles",
618
+ "withStories",
619
+ "withSsrTests",
620
+ "useTsStories",
621
+ ]);
298
622
 
299
- // componentPath deliberately drops its ParamSpec default so the SELECTED
300
- // framework's own prompt default applies (react vs svelte/lit differ).
301
- const verbPath = verb.find((p) => p.name === "componentPath") as
302
- | Record<string, unknown>
303
- | undefined;
304
- const realPath = real.find((p) => p.name === "componentPath") as
623
+ // A prompt whose default DIFFERS across frameworks (componentPath:
624
+ // src/components/… on react vs src/lib/components/… on svelte/lit)
625
+ // omits its default and stays optional.
626
+ const componentPath = params.find((p) => p.name === "componentPath") as
305
627
  | Record<string, unknown>
306
628
  | undefined;
307
- expect(verbPath).toMatchObject({
629
+ expect(componentPath).toMatchObject({
308
630
  kind: "string",
309
631
  positional: true,
632
+ required: false,
310
633
  complete: { kind: "files" },
311
634
  });
312
- expect(verbPath?.default).toBeUndefined();
313
- expect(realPath?.default).toBe("src/components/MyComponent");
314
-
315
- // Every other prompt (the shared confirms) must match names, kinds, AND
316
- // defaults exactly — the silent-drift surface.
317
- const shared = (ps: readonly ParamSpec[]) =>
318
- behavioural(
319
- ps.filter((p) => p.name !== "framework" && p.name !== "componentPath"),
320
- );
321
- expect(shared(verb)).toEqual(shared(real));
322
- });
635
+ expect(componentPath?.default).toBeUndefined();
636
+
637
+ // A prompt identical across all frameworks keeps its default.
638
+ expect(params.find((p) => p.name === "withStyles")).toMatchObject({
639
+ kind: "boolean",
640
+ default: true,
641
+ });
323
642
 
324
- it("package: mirror matches the package generator (defaults + type choices)", async () => {
325
- const { generators } = await import("@canonical/summon-package");
326
- const real = generatorToParams(
327
- (generators as Record<string, { prompts: unknown[] }>).package
328
- .prompts as never,
643
+ // A prompt not present on EVERY framework names its frameworks in the doc.
644
+ expect(params.find((p) => p.name === "withSsrTests")?.doc).toContain(
645
+ "(frameworks: react, svelte)",
329
646
  );
330
- // The package verb's grammar IS generatorToParams(PACKAGE_MIRROR).
331
- expect(behavioural(createPackageVerb.params)).toEqual(
332
- behavioural(applyRunInstallOverride(real)),
647
+ expect(params.find((p) => p.name === "useTsStories")?.doc).toContain(
648
+ "(frameworks: svelte)",
333
649
  );
650
+ // …and a universal one does not.
651
+ expect(params.find((p) => p.name === "withStories")?.doc).not.toContain(
652
+ "frameworks:",
653
+ );
654
+ });
334
655
 
335
- // Guard the intentional runInstall override so it can't silently flip.
336
- const realRunInstall = real.find((p) => p.name === "runInstall") as
337
- | Record<string, unknown>
338
- | undefined;
339
- const mirrorRunInstall = createPackageVerb.params.find(
340
- (p) => p.name === "runInstall",
656
+ it("the framework enum DERIVES from the declared tree segments: required, positional, no default", () => {
657
+ const framework = createVerbs.component.params.find(
658
+ (p) => p.name === "framework",
341
659
  ) as Record<string, unknown> | undefined;
342
- expect(realRunInstall?.default).toBe(true);
343
- expect(mirrorRunInstall?.default).toBe(false);
344
-
345
- // The `--type` enum choices are load-bearing and must match exactly.
346
- const realType = real.find((p) => p.name === "type");
347
- expect(realType).toMatchObject({
660
+ expect(framework).toMatchObject({
348
661
  kind: "enum",
349
- values: ["tool-ts", "library", "css"],
350
- default: "tool-ts",
662
+ required: true,
663
+ positional: true,
664
+ values: CREATE_GENERATORS.component.paths.map(
665
+ (path) => path.split("/")[1],
666
+ ),
351
667
  });
668
+ // Summon has no default framework; neither does the projection of it.
669
+ expect(framework?.default).toBeUndefined();
352
670
  });
353
671
 
354
- /** Map a mirror's CLI `--with-X` include-flag names back to the generator
355
- * prompt names (AV-228 B8) so the parity comparison still checks kinds and
356
- * defaults against the real generator despite the deliberate flag rename. */
357
- const toGeneratorNames = (
358
- kind: "application",
359
- params: readonly ParamSpec[],
360
- ): ParamSpec[] =>
361
- params.map((p) => {
362
- const generatorName = INCLUDE_FLAG_ALIASES[kind][p.name];
363
- return generatorName ? ({ ...p, name: generatorName } as ParamSpec) : p;
364
- });
365
-
366
- it("application: mirror matches the application/react generator (defaults)", async () => {
367
- const { generators } = await import("@canonical/summon-application");
368
- const real = generatorToParams(
369
- (generators as Record<string, { prompts: unknown[] }>)[
370
- "application/react"
371
- ].prompts as never,
372
- );
373
- // Bridge the B8 include-flag rename before comparing: the CLI grammar
374
- // exposes `withSsr`/`withRouter`/`withForms`, which map back to the
375
- // generator's `ssr`/`router`/`forms`.
672
+ it("package and application params are the projected prompts VERBATIM (no aliases, no overrides)", () => {
673
+ expect(createVerbs.package.params.map((p) => p.name)).toEqual([
674
+ "name",
675
+ "type",
676
+ "description",
677
+ "withReact",
678
+ "withStorybook",
679
+ "withCli",
680
+ "withPrTemplate",
681
+ "runInstall",
682
+ ]);
683
+ // The prompt names ARE the param names (the flag TOKENS are
684
+ // buildOptionInfo's registered forms): the B8 --with-X aliases are gone —
685
+ // and so are ssr/router, WITH their prompts (always-on facts whose only
686
+ // explicit spelling the generator's old guard rejected).
687
+ expect(createVerbs.application.params.map((p) => p.name)).toEqual([
688
+ "appPath",
689
+ "forms",
690
+ "intl",
691
+ "relay",
692
+ "runInstall",
693
+ ]);
694
+ // The generators' own default governs: install is ON unless --no-run-install.
376
695
  expect(
377
- behavioural(
378
- toGeneratorNames("application", createApplicationVerb.params),
379
- ),
380
- ).toEqual(behavioural(applyRunInstallOverride(real)));
381
-
382
- // Guard the B8 rename itself: ALL application include-flags ARE on the
383
- // `--with-X` convention (params `withSsr`/`withRouter`/`withForms`/
384
- // `withRelay`), not the bare `ssr`/`router`/`forms`/`relay` booleans.
385
- const names = createApplicationVerb.params.map((p) => p.name);
386
- expect(names).toContain("withSsr");
387
- expect(names).toContain("withRouter");
388
- expect(names).toContain("withForms");
389
- expect(names).toContain("withRelay");
390
- expect(names).not.toContain("ssr");
391
- expect(names).not.toContain("relay");
392
-
393
- const realRunInstall = real.find((p) => p.name === "runInstall") as
394
- | Record<string, unknown>
395
- | undefined;
396
- const mirrorRunInstall = createApplicationVerb.params.find(
397
- (p) => p.name === "runInstall",
398
- ) as Record<string, unknown> | undefined;
399
- expect(realRunInstall?.default).toBe(true);
400
- expect(mirrorRunInstall?.default).toBe(false);
401
-
402
- // appPath is the positional entry point (its default carries across).
696
+ createVerbs.package.params.find((p) => p.name === "runInstall"),
697
+ ).toMatchObject({ kind: "boolean", default: true });
698
+ expect(
699
+ createVerbs.application.params.find((p) => p.name === "runInstall"),
700
+ ).toMatchObject({ kind: "boolean", default: true });
701
+ // The package type enum still carries its load-bearing choices.
403
702
  expect(
404
- createApplicationVerb.params.find((p) => p.name === "appPath"),
405
- ).toMatchObject({ kind: "string", positional: true, default: "my-app" });
703
+ createVerbs.package.params.find((p) => p.name === "type"),
704
+ ).toMatchObject({
705
+ kind: "enum",
706
+ values: ["tool-ts", "library", "css"],
707
+ default: "tool-ts",
708
+ });
406
709
  });
407
710
  });
408
711
 
@@ -430,3 +733,61 @@ describe("compiled-binary create gate (M4)", () => {
430
733
  expect(isModuleNotFound("nope")).toBe(false);
431
734
  });
432
735
  });
736
+
737
+ describe("declared generator bindings (PROTECTED)", () => {
738
+ // CREATE_GENERATORS is the one place the create surface's generator facts are
739
+ // written down. What is checkable against something outside itself — the live
740
+ // generator maps — is checked here.
741
+
742
+ it("every declared path resolves to a generator whose meta.name IS the path", async () => {
743
+ const { pickGenerator } = await import("./pickGenerator.js");
744
+ // `meta.name` is the generator's OWN identity, so a swapped path or a
745
+ // path the map does not carry turns this red — which `toBeDefined()`
746
+ // on a non-nullable return could not.
747
+ for (const binding of Object.values(CREATE_GENERATORS)) {
748
+ for (const commandPath of binding.paths) {
749
+ expect(pickGenerator(commandPath).meta.name).toBe(commandPath);
750
+ }
751
+ }
752
+ });
753
+
754
+ it("no binding publishes an availability caveat — every one runs everywhere", () => {
755
+ // The PRA-14 gate is superseded: every generator's templates are reachable
756
+ // from a published install (shippedCreate.subprocess.test.ts proves all
757
+ // three byte-for-byte), so no verb may reintroduce the "Source-run only."
758
+ // marker or an UNSUPPORTED doc. Publishing one would now be a false
759
+ // statement to every agent enumerating the tools.
760
+ for (const verb of createModule.verbs) {
761
+ expect(verb.summary).not.toContain("Source-run only.");
762
+ expect(verb.doc ?? "").not.toContain("UNSUPPORTED");
763
+ }
764
+ });
765
+
766
+ it("the framework enum offers the declared segments — non-empty, and NO default", () => {
767
+ const framework = createVerbs.component.params.find(
768
+ (p) => p.name === "framework",
769
+ );
770
+ // A `values: []` enum would leave every `create component <framework>`
771
+ // rejected — the hazard this names. (That every value resolves is the
772
+ // test above; the derivation shape is pinned in the projection describe.)
773
+ expect(framework?.kind).toBe("enum");
774
+ const values = (framework as { values: readonly string[] }).values;
775
+ expect(values.length).toBeGreaterThan(0);
776
+ expect(framework?.default).toBeUndefined();
777
+ });
778
+
779
+ it("create surfaces exactly the three declared nouns", () => {
780
+ // A LITERAL surface pin, deliberately not derived from CREATE_GENERATORS:
781
+ // surfacing a noun also needs a hand-written prompt mirror, path param and
782
+ // examples in create.verb.ts, so the surface is a deliberate SUBSET of what
783
+ // the declared packages ship (`@canonical/summon-application` also ships
784
+ // `domain`, `route` and `wrapper`). Pinning OUR three nouns rather than any
785
+ // third-party package's generator list keeps an upstream release from
786
+ // turning this red.
787
+ expect(createModule.verbs.map((v) => v.path[1])).toEqual([
788
+ "component",
789
+ "package",
790
+ "application",
791
+ ]);
792
+ });
793
+ });