@canonical/pragma-cli 0.34.0 → 0.36.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 (832) hide show
  1. package/README.md +153 -30
  2. package/bundled-skills/add-standard/SKILL.md +338 -0
  3. package/bundled-skills/adoption-a1-styles/SKILL.md +269 -0
  4. package/bundled-skills/adoption-a2-components/SKILL.md +291 -0
  5. package/bundled-skills/adoption-a3-forms/SKILL.md +260 -0
  6. package/bundled-skills/anatomy-author/ANATOMY_DSL_SPEC.md +406 -0
  7. package/bundled-skills/anatomy-author/SKILL.md +1226 -0
  8. package/bundled-skills/design-auditor/SKILL.md +455 -0
  9. package/bundled-skills/implement-component/SKILL.md +333 -0
  10. package/bundled-skills/specify-component/SKILL.md +331 -0
  11. package/bundled-skills/specify-pattern/SKILL.md +292 -0
  12. package/dist/.build-ok +0 -0
  13. package/dist/package.json +84 -0
  14. package/dist/pragma.conf.js +1016 -0
  15. package/dist/pragma.conf.js.map +1 -0
  16. package/dist/src/bin.js +356 -0
  17. package/dist/src/bin.js.map +1 -0
  18. package/dist/src/capabilities/capabilities/capabilities.render.js +70 -0
  19. package/dist/src/capabilities/capabilities/capabilities.render.js.map +1 -0
  20. package/dist/src/capabilities/capabilities/capabilities.verb.js +59 -0
  21. package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -0
  22. package/dist/src/capabilities/capabilities/catalog.js +130 -0
  23. package/dist/src/capabilities/capabilities/catalog.js.map +1 -0
  24. package/dist/src/capabilities/capabilities/hints.js +195 -0
  25. package/dist/src/capabilities/capabilities/hints.js.map +1 -0
  26. package/dist/src/capabilities/capabilities/index.js +11 -0
  27. package/dist/src/capabilities/capabilities/index.js.map +1 -0
  28. package/dist/src/capabilities/capabilities/types.js +11 -0
  29. package/dist/src/capabilities/capabilities/types.js.map +1 -0
  30. package/dist/src/capabilities/colophon/collectColophon.js +83 -0
  31. package/dist/src/capabilities/colophon/collectColophon.js.map +1 -0
  32. package/dist/src/capabilities/colophon/colophon.render.js +59 -0
  33. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -0
  34. package/dist/src/capabilities/colophon/colophon.verb.js +43 -0
  35. package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -0
  36. package/dist/src/capabilities/colophon/index.js +5 -0
  37. package/dist/src/capabilities/colophon/index.js.map +1 -0
  38. package/dist/src/capabilities/colophon/markdownTerminal.js +90 -0
  39. package/dist/src/capabilities/colophon/markdownTerminal.js.map +1 -0
  40. package/dist/src/capabilities/colophon/types.js +10 -0
  41. package/dist/src/capabilities/colophon/types.js.map +1 -0
  42. package/dist/src/capabilities/config/collectConfigShow.js +59 -0
  43. package/dist/src/capabilities/config/collectConfigShow.js.map +1 -0
  44. package/dist/src/capabilities/config/field.render.js +22 -0
  45. package/dist/src/capabilities/config/field.render.js.map +1 -0
  46. package/dist/src/capabilities/config/fields.js +46 -0
  47. package/dist/src/capabilities/config/fields.js.map +1 -0
  48. package/dist/src/capabilities/config/get.verb.js +61 -0
  49. package/dist/src/capabilities/config/get.verb.js.map +1 -0
  50. package/dist/src/capabilities/config/index.js +5 -0
  51. package/dist/src/capabilities/config/index.js.map +1 -0
  52. package/dist/src/capabilities/config/runField.js +59 -0
  53. package/dist/src/capabilities/config/runField.js.map +1 -0
  54. package/dist/src/capabilities/config/runGet.js +28 -0
  55. package/dist/src/capabilities/config/runGet.js.map +1 -0
  56. package/dist/src/capabilities/config/runSet.js +53 -0
  57. package/dist/src/capabilities/config/runSet.js.map +1 -0
  58. package/dist/src/capabilities/config/set.verb.js +66 -0
  59. package/dist/src/capabilities/config/set.verb.js.map +1 -0
  60. package/dist/src/capabilities/config/show.render.js +84 -0
  61. package/dist/src/capabilities/config/show.render.js.map +1 -0
  62. package/dist/src/capabilities/config/show.verb.js +44 -0
  63. package/dist/src/capabilities/config/show.verb.js.map +1 -0
  64. package/dist/src/capabilities/config/types.js +5 -0
  65. package/dist/src/capabilities/config/types.js.map +1 -0
  66. package/dist/src/capabilities/config/unset.verb.js +49 -0
  67. package/dist/src/capabilities/config/unset.verb.js.map +1 -0
  68. package/dist/src/capabilities/create/cliProjection.js +195 -0
  69. package/dist/src/capabilities/create/cliProjection.js.map +1 -0
  70. package/dist/src/capabilities/create/constants.js +47 -0
  71. package/dist/src/capabilities/create/constants.js.map +1 -0
  72. package/dist/src/capabilities/create/create.render.js +100 -0
  73. package/dist/src/capabilities/create/create.render.js.map +1 -0
  74. package/dist/src/capabilities/create/create.verb.js +438 -0
  75. package/dist/src/capabilities/create/create.verb.js.map +1 -0
  76. package/dist/src/capabilities/create/createHelp.js +47 -0
  77. package/dist/src/capabilities/create/createHelp.js.map +1 -0
  78. package/dist/src/capabilities/create/createSurface.generated.js +394 -0
  79. package/dist/src/capabilities/create/createSurface.generated.js.map +1 -0
  80. package/dist/src/capabilities/create/generatorToVerbSpec.js +106 -0
  81. package/dist/src/capabilities/create/generatorToVerbSpec.js.map +1 -0
  82. package/dist/src/capabilities/create/index.js +18 -0
  83. package/dist/src/capabilities/create/index.js.map +1 -0
  84. package/dist/src/capabilities/create/messages.js +16 -0
  85. package/dist/src/capabilities/create/messages.js.map +1 -0
  86. package/dist/src/capabilities/create/mount.js +294 -0
  87. package/dist/src/capabilities/create/mount.js.map +1 -0
  88. package/dist/src/capabilities/create/pathJail.js +65 -0
  89. package/dist/src/capabilities/create/pathJail.js.map +1 -0
  90. package/dist/src/capabilities/create/pickGenerator.js +53 -0
  91. package/dist/src/capabilities/create/pickGenerator.js.map +1 -0
  92. package/dist/src/capabilities/create/types.js +2 -0
  93. package/dist/src/capabilities/create/types.js.map +1 -0
  94. package/dist/src/capabilities/distribution.js +40 -0
  95. package/dist/src/capabilities/distribution.js.map +1 -0
  96. package/dist/src/capabilities/doctor/checks/checkKeStore.js +40 -0
  97. package/dist/src/capabilities/doctor/checks/checkKeStore.js.map +1 -0
  98. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +21 -0
  99. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -0
  100. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +148 -0
  101. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -0
  102. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js +19 -0
  103. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js.map +1 -0
  104. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +199 -0
  105. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -0
  106. package/dist/src/capabilities/doctor/checks/harnessInventory.js +195 -0
  107. package/dist/src/capabilities/doctor/checks/harnessInventory.js.map +1 -0
  108. package/dist/src/capabilities/doctor/checks/index.js +27 -0
  109. package/dist/src/capabilities/doctor/checks/index.js.map +1 -0
  110. package/dist/src/capabilities/doctor/checks/mcpCommand.js +57 -0
  111. package/dist/src/capabilities/doctor/checks/mcpCommand.js.map +1 -0
  112. package/dist/src/capabilities/doctor/checks/targetHealth.js +349 -0
  113. package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -0
  114. package/dist/src/capabilities/doctor/doctor.render.js +164 -0
  115. package/dist/src/capabilities/doctor/doctor.render.js.map +1 -0
  116. package/dist/src/capabilities/doctor/doctor.verb.js +49 -0
  117. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -0
  118. package/dist/src/capabilities/doctor/index.js +5 -0
  119. package/dist/src/capabilities/doctor/index.js.map +1 -0
  120. package/dist/src/capabilities/doctor/runChecks.js +86 -0
  121. package/dist/src/capabilities/doctor/runChecks.js.map +1 -0
  122. package/dist/src/capabilities/doctor/types.js +5 -0
  123. package/dist/src/capabilities/doctor/types.js.map +1 -0
  124. package/dist/src/capabilities/graph/index.js +19 -0
  125. package/dist/src/capabilities/graph/index.js.map +1 -0
  126. package/dist/src/capabilities/graph/inspect.render.js +76 -0
  127. package/dist/src/capabilities/graph/inspect.render.js.map +1 -0
  128. package/dist/src/capabilities/graph/inspect.verb.js +53 -0
  129. package/dist/src/capabilities/graph/inspect.verb.js.map +1 -0
  130. package/dist/src/capabilities/graph/query.render.js +73 -0
  131. package/dist/src/capabilities/graph/query.render.js.map +1 -0
  132. package/dist/src/capabilities/graph/query.verb.js +49 -0
  133. package/dist/src/capabilities/graph/query.verb.js.map +1 -0
  134. package/dist/src/capabilities/graph/runQuery.js +41 -0
  135. package/dist/src/capabilities/graph/runQuery.js.map +1 -0
  136. package/dist/src/capabilities/index.js +56 -0
  137. package/dist/src/capabilities/index.js.map +1 -0
  138. package/dist/src/capabilities/info/collectInfo.js +72 -0
  139. package/dist/src/capabilities/info/collectInfo.js.map +1 -0
  140. package/dist/src/capabilities/info/index.js +5 -0
  141. package/dist/src/capabilities/info/index.js.map +1 -0
  142. package/dist/src/capabilities/info/info.render.js +57 -0
  143. package/dist/src/capabilities/info/info.render.js.map +1 -0
  144. package/dist/src/capabilities/info/info.verb.js +42 -0
  145. package/dist/src/capabilities/info/info.verb.js.map +1 -0
  146. package/dist/src/capabilities/info/types.js +5 -0
  147. package/dist/src/capabilities/info/types.js.map +1 -0
  148. package/dist/src/capabilities/meta/complete.verb.js +43 -0
  149. package/dist/src/capabilities/meta/complete.verb.js.map +1 -0
  150. package/dist/src/capabilities/meta/index.js +13 -0
  151. package/dist/src/capabilities/meta/index.js.map +1 -0
  152. package/dist/src/capabilities/meta/mcp.verb.js +34 -0
  153. package/dist/src/capabilities/meta/mcp.verb.js.map +1 -0
  154. package/dist/src/capabilities/ontology/index.js +21 -0
  155. package/dist/src/capabilities/ontology/index.js.map +1 -0
  156. package/dist/src/capabilities/ontology/queries.js +123 -0
  157. package/dist/src/capabilities/ontology/queries.js.map +1 -0
  158. package/dist/src/capabilities/ontology/render.js +66 -0
  159. package/dist/src/capabilities/ontology/render.js.map +1 -0
  160. package/dist/src/capabilities/ontology/verbs.js +181 -0
  161. package/dist/src/capabilities/ontology/verbs.js.map +1 -0
  162. package/dist/src/capabilities/prompt/index.js +16 -0
  163. package/dist/src/capabilities/prompt/index.js.map +1 -0
  164. package/dist/src/capabilities/prompt/prompt.render.js +78 -0
  165. package/dist/src/capabilities/prompt/prompt.render.js.map +1 -0
  166. package/dist/src/capabilities/prompt/types.js +10 -0
  167. package/dist/src/capabilities/prompt/types.js.map +1 -0
  168. package/dist/src/capabilities/prompt/verbs.js +93 -0
  169. package/dist/src/capabilities/prompt/verbs.js.map +1 -0
  170. package/dist/src/capabilities/resources/index.js +10 -0
  171. package/dist/src/capabilities/resources/index.js.map +1 -0
  172. package/dist/src/capabilities/resources/provider.js +423 -0
  173. package/dist/src/capabilities/resources/provider.js.map +1 -0
  174. package/dist/src/capabilities/setup/buildPlan.js +172 -0
  175. package/dist/src/capabilities/setup/buildPlan.js.map +1 -0
  176. package/dist/src/capabilities/setup/index.js +5 -0
  177. package/dist/src/capabilities/setup/index.js.map +1 -0
  178. package/dist/src/capabilities/setup/mode.js +53 -0
  179. package/dist/src/capabilities/setup/mode.js.map +1 -0
  180. package/dist/src/capabilities/setup/operations/index.js +39 -0
  181. package/dist/src/capabilities/setup/operations/index.js.map +1 -0
  182. package/dist/src/capabilities/setup/operations/setupCompletions.js +160 -0
  183. package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -0
  184. package/dist/src/capabilities/setup/operations/setupConfig.js +101 -0
  185. package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -0
  186. package/dist/src/capabilities/setup/operations/setupGenerator.js +390 -0
  187. package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -0
  188. package/dist/src/capabilities/setup/operations/setupLsp.js +329 -0
  189. package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -0
  190. package/dist/src/capabilities/setup/operations/setupMcp.js +253 -0
  191. package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -0
  192. package/dist/src/capabilities/setup/operations/setupSkills.js +594 -0
  193. package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -0
  194. package/dist/src/capabilities/setup/plan.js +128 -0
  195. package/dist/src/capabilities/setup/plan.js.map +1 -0
  196. package/dist/src/capabilities/setup/plan.render.js +271 -0
  197. package/dist/src/capabilities/setup/plan.render.js.map +1 -0
  198. package/dist/src/capabilities/setup/setup.render.js +54 -0
  199. package/dist/src/capabilities/setup/setup.render.js.map +1 -0
  200. package/dist/src/capabilities/setup/setup.verb.js +387 -0
  201. package/dist/src/capabilities/setup/setup.verb.js.map +1 -0
  202. package/dist/src/capabilities/setup/shell.js +196 -0
  203. package/dist/src/capabilities/setup/shell.js.map +1 -0
  204. package/dist/src/capabilities/setup/targets.js +328 -0
  205. package/dist/src/capabilities/setup/targets.js.map +1 -0
  206. package/dist/src/capabilities/setup/types.js +5 -0
  207. package/dist/src/capabilities/setup/types.js.map +1 -0
  208. package/dist/src/capabilities/shared/assertExecOk.js +137 -0
  209. package/dist/src/capabilities/shared/assertExecOk.js.map +1 -0
  210. package/dist/src/capabilities/shared/index.js +27 -0
  211. package/dist/src/capabilities/shared/index.js.map +1 -0
  212. package/dist/src/capabilities/shared/packageManager.js +349 -0
  213. package/dist/src/capabilities/shared/packageManager.js.map +1 -0
  214. package/dist/src/capabilities/shared/registry.js +55 -0
  215. package/dist/src/capabilities/shared/registry.js.map +1 -0
  216. package/dist/src/capabilities/skill/discover.js +281 -0
  217. package/dist/src/capabilities/skill/discover.js.map +1 -0
  218. package/dist/src/capabilities/skill/index.js +10 -0
  219. package/dist/src/capabilities/skill/index.js.map +1 -0
  220. package/dist/src/capabilities/skill/render.js +49 -0
  221. package/dist/src/capabilities/skill/render.js.map +1 -0
  222. package/dist/src/capabilities/skill/verbs.js +83 -0
  223. package/dist/src/capabilities/skill/verbs.js.map +1 -0
  224. package/dist/src/capabilities/sources/collectStatus.js +103 -0
  225. package/dist/src/capabilities/sources/collectStatus.js.map +1 -0
  226. package/dist/src/capabilities/sources/index.js +13 -0
  227. package/dist/src/capabilities/sources/index.js.map +1 -0
  228. package/dist/src/capabilities/sources/installSkills.js +309 -0
  229. package/dist/src/capabilities/sources/installSkills.js.map +1 -0
  230. package/dist/src/capabilities/sources/runUpdate.js +460 -0
  231. package/dist/src/capabilities/sources/runUpdate.js.map +1 -0
  232. package/dist/src/capabilities/sources/status.render.js +64 -0
  233. package/dist/src/capabilities/sources/status.render.js.map +1 -0
  234. package/dist/src/capabilities/sources/status.verb.js +40 -0
  235. package/dist/src/capabilities/sources/status.verb.js.map +1 -0
  236. package/dist/src/capabilities/sources/types.js +6 -0
  237. package/dist/src/capabilities/sources/types.js.map +1 -0
  238. package/dist/src/capabilities/sources/update.render.js +34 -0
  239. package/dist/src/capabilities/sources/update.render.js.map +1 -0
  240. package/dist/src/capabilities/sources/update.verb.js +55 -0
  241. package/dist/src/capabilities/sources/update.verb.js.map +1 -0
  242. package/dist/src/capabilities/upgrade/index.js +5 -0
  243. package/dist/src/capabilities/upgrade/index.js.map +1 -0
  244. package/dist/src/capabilities/upgrade/runUpgrade.js +135 -0
  245. package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -0
  246. package/dist/src/capabilities/upgrade/types.js +5 -0
  247. package/dist/src/capabilities/upgrade/types.js.map +1 -0
  248. package/dist/src/capabilities/upgrade/upgrade.render.js +52 -0
  249. package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -0
  250. package/dist/src/capabilities/upgrade/upgrade.verb.js +52 -0
  251. package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -0
  252. package/dist/src/capabilities/version/index.js +10 -0
  253. package/dist/src/capabilities/version/index.js.map +1 -0
  254. package/dist/src/capabilities/version/version.verb.js +36 -0
  255. package/dist/src/capabilities/version/version.verb.js.map +1 -0
  256. package/dist/src/constants.js +87 -0
  257. package/dist/src/constants.js.map +1 -0
  258. package/dist/src/index.js +12 -0
  259. package/dist/src/index.js.map +1 -0
  260. package/dist/src/kernel/completion/complete.js +66 -0
  261. package/dist/src/kernel/completion/complete.js.map +1 -0
  262. package/dist/src/kernel/completion/emitScripts.js +92 -0
  263. package/dist/src/kernel/completion/emitScripts.js.map +1 -0
  264. package/dist/src/kernel/completion/entitySource.js +285 -0
  265. package/dist/src/kernel/completion/entitySource.js.map +1 -0
  266. package/dist/src/kernel/completion/index.js +14 -0
  267. package/dist/src/kernel/completion/index.js.map +1 -0
  268. package/dist/src/kernel/completion/model.js +301 -0
  269. package/dist/src/kernel/completion/model.js.map +1 -0
  270. package/dist/src/kernel/completion/parse.js +253 -0
  271. package/dist/src/kernel/completion/parse.js.map +1 -0
  272. package/dist/src/kernel/completion/rank.js +101 -0
  273. package/dist/src/kernel/completion/rank.js.map +1 -0
  274. package/dist/src/kernel/completion/resolve.js +100 -0
  275. package/dist/src/kernel/completion/resolve.js.map +1 -0
  276. package/dist/src/kernel/completion/templates/bash.js +209 -0
  277. package/dist/src/kernel/completion/templates/bash.js.map +1 -0
  278. package/dist/src/kernel/completion/templates/fish.js +214 -0
  279. package/dist/src/kernel/completion/templates/fish.js.map +1 -0
  280. package/dist/src/kernel/completion/templates/index.js +23 -0
  281. package/dist/src/kernel/completion/templates/index.js.map +1 -0
  282. package/dist/src/kernel/completion/templates/shared.js +98 -0
  283. package/dist/src/kernel/completion/templates/shared.js.map +1 -0
  284. package/dist/src/kernel/completion/templates/zsh.js +201 -0
  285. package/dist/src/kernel/completion/templates/zsh.js.map +1 -0
  286. package/dist/src/kernel/completion/types.js +13 -0
  287. package/dist/src/kernel/completion/types.js.map +1 -0
  288. package/dist/src/kernel/config/defaults.js +17 -0
  289. package/dist/src/kernel/config/defaults.js.map +1 -0
  290. package/dist/src/kernel/config/evaluateProjectConfig.js +126 -0
  291. package/dist/src/kernel/config/evaluateProjectConfig.js.map +1 -0
  292. package/dist/src/kernel/config/findProjectConfig.js +43 -0
  293. package/dist/src/kernel/config/findProjectConfig.js.map +1 -0
  294. package/dist/src/kernel/config/firstRun.js +34 -0
  295. package/dist/src/kernel/config/firstRun.js.map +1 -0
  296. package/dist/src/kernel/config/globalConfig.js +79 -0
  297. package/dist/src/kernel/config/globalConfig.js.map +1 -0
  298. package/dist/src/kernel/config/index.js +16 -0
  299. package/dist/src/kernel/config/index.js.map +1 -0
  300. package/dist/src/kernel/config/paths.js +35 -0
  301. package/dist/src/kernel/config/paths.js.map +1 -0
  302. package/dist/src/kernel/config/readConfig.js +78 -0
  303. package/dist/src/kernel/config/readConfig.js.map +1 -0
  304. package/dist/src/kernel/config/schema.js +130 -0
  305. package/dist/src/kernel/config/schema.js.map +1 -0
  306. package/dist/src/kernel/config/types.js +19 -0
  307. package/dist/src/kernel/config/types.js.map +1 -0
  308. package/dist/src/kernel/config/writeConfigField.js +59 -0
  309. package/dist/src/kernel/config/writeConfigField.js.map +1 -0
  310. package/dist/src/kernel/copy.js +43 -0
  311. package/dist/src/kernel/copy.js.map +1 -0
  312. package/dist/src/kernel/error/PragmaError.js +149 -0
  313. package/dist/src/kernel/error/PragmaError.js.map +1 -0
  314. package/dist/src/kernel/error/constants.js +40 -0
  315. package/dist/src/kernel/error/constants.js.map +1 -0
  316. package/dist/src/kernel/error/fromTaskError.js +96 -0
  317. package/dist/src/kernel/error/fromTaskError.js.map +1 -0
  318. package/dist/src/kernel/error/index.js +13 -0
  319. package/dist/src/kernel/error/index.js.map +1 -0
  320. package/dist/src/kernel/error/recovery.js +52 -0
  321. package/dist/src/kernel/error/recovery.js.map +1 -0
  322. package/dist/src/kernel/error/renderError.js +115 -0
  323. package/dist/src/kernel/error/renderError.js.map +1 -0
  324. package/dist/src/kernel/error/serialize.js +25 -0
  325. package/dist/src/kernel/error/serialize.js.map +1 -0
  326. package/dist/src/kernel/error/types.js +9 -0
  327. package/dist/src/kernel/error/types.js.map +1 -0
  328. package/dist/src/kernel/index.js +34 -0
  329. package/dist/src/kernel/index.js.map +1 -0
  330. package/dist/src/kernel/interactivity.js +68 -0
  331. package/dist/src/kernel/interactivity.js.map +1 -0
  332. package/dist/src/kernel/packs/collect.js +187 -0
  333. package/dist/src/kernel/packs/collect.js.map +1 -0
  334. package/dist/src/kernel/packs/compile.js +304 -0
  335. package/dist/src/kernel/packs/compile.js.map +1 -0
  336. package/dist/src/kernel/packs/disclosure.js +76 -0
  337. package/dist/src/kernel/packs/disclosure.js.map +1 -0
  338. package/dist/src/kernel/packs/glob.js +38 -0
  339. package/dist/src/kernel/packs/glob.js.map +1 -0
  340. package/dist/src/kernel/packs/graphql/buildLookupDocument.js +258 -0
  341. package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -0
  342. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +157 -0
  343. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -0
  344. package/dist/src/kernel/packs/graphql/index.js +20 -0
  345. package/dist/src/kernel/packs/graphql/index.js.map +1 -0
  346. package/dist/src/kernel/packs/graphql/nameMap.js +63 -0
  347. package/dist/src/kernel/packs/graphql/nameMap.js.map +1 -0
  348. package/dist/src/kernel/packs/index.js +34 -0
  349. package/dist/src/kernel/packs/index.js.map +1 -0
  350. package/dist/src/kernel/packs/iri.js +110 -0
  351. package/dist/src/kernel/packs/iri.js.map +1 -0
  352. package/dist/src/kernel/packs/renderPack.js +129 -0
  353. package/dist/src/kernel/packs/renderPack.js.map +1 -0
  354. package/dist/src/kernel/packs/resolveEntity.js +274 -0
  355. package/dist/src/kernel/packs/resolveEntity.js.map +1 -0
  356. package/dist/src/kernel/packs/runBodies.js +140 -0
  357. package/dist/src/kernel/packs/runBodies.js.map +1 -0
  358. package/dist/src/kernel/packs/sample.js +56 -0
  359. package/dist/src/kernel/packs/sample.js.map +1 -0
  360. package/dist/src/kernel/packs/schema.js +421 -0
  361. package/dist/src/kernel/packs/schema.js.map +1 -0
  362. package/dist/src/kernel/packs/sparql/applyFilters.js +167 -0
  363. package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -0
  364. package/dist/src/kernel/packs/sparql/applySearch.js +25 -0
  365. package/dist/src/kernel/packs/sparql/applySearch.js.map +1 -0
  366. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +480 -0
  367. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -0
  368. package/dist/src/kernel/packs/sparql/escape.js +21 -0
  369. package/dist/src/kernel/packs/sparql/escape.js.map +1 -0
  370. package/dist/src/kernel/packs/sparql/index.js +31 -0
  371. package/dist/src/kernel/packs/sparql/index.js.map +1 -0
  372. package/dist/src/kernel/packs/sparql/runSelect.js +101 -0
  373. package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -0
  374. package/dist/src/kernel/packs/types.js +30 -0
  375. package/dist/src/kernel/packs/types.js.map +1 -0
  376. package/dist/src/kernel/packs/uniqueness.js +30 -0
  377. package/dist/src/kernel/packs/uniqueness.js.map +1 -0
  378. package/dist/src/kernel/project/cli/buildProgram.js +263 -0
  379. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -0
  380. package/dist/src/kernel/project/cli/constants.js +27 -0
  381. package/dist/src/kernel/project/cli/constants.js.map +1 -0
  382. package/dist/src/kernel/project/cli/dispatch.js +420 -0
  383. package/dist/src/kernel/project/cli/dispatch.js.map +1 -0
  384. package/dist/src/kernel/project/cli/exitCodes.js +66 -0
  385. package/dist/src/kernel/project/cli/exitCodes.js.map +1 -0
  386. package/dist/src/kernel/project/cli/globalFlags.js +219 -0
  387. package/dist/src/kernel/project/cli/globalFlags.js.map +1 -0
  388. package/dist/src/kernel/project/cli/helpFormat.js +58 -0
  389. package/dist/src/kernel/project/cli/helpFormat.js.map +1 -0
  390. package/dist/src/kernel/project/cli/index.js +14 -0
  391. package/dist/src/kernel/project/cli/index.js.map +1 -0
  392. package/dist/src/kernel/project/cli/rootHelp.js +227 -0
  393. package/dist/src/kernel/project/cli/rootHelp.js.map +1 -0
  394. package/dist/src/kernel/project/cli/suggest.js +75 -0
  395. package/dist/src/kernel/project/cli/suggest.js.map +1 -0
  396. package/dist/src/kernel/project/cli/suggestNames.js +96 -0
  397. package/dist/src/kernel/project/cli/suggestNames.js.map +1 -0
  398. package/dist/src/kernel/project/cli/verbHelp.js +131 -0
  399. package/dist/src/kernel/project/cli/verbHelp.js.map +1 -0
  400. package/dist/src/kernel/project/mcp/buildServer.js +67 -0
  401. package/dist/src/kernel/project/mcp/buildServer.js.map +1 -0
  402. package/dist/src/kernel/project/mcp/envelope.js +37 -0
  403. package/dist/src/kernel/project/mcp/envelope.js.map +1 -0
  404. package/dist/src/kernel/project/mcp/index.js +8 -0
  405. package/dist/src/kernel/project/mcp/index.js.map +1 -0
  406. package/dist/src/kernel/project/mcp/instructions.js +44 -0
  407. package/dist/src/kernel/project/mcp/instructions.js.map +1 -0
  408. package/dist/src/kernel/project/mcp/mcpError.js +42 -0
  409. package/dist/src/kernel/project/mcp/mcpError.js.map +1 -0
  410. package/dist/src/kernel/project/mcp/prompts/index.js +36 -0
  411. package/dist/src/kernel/project/mcp/prompts/index.js.map +1 -0
  412. package/dist/src/kernel/project/mcp/prompts/provider.js +98 -0
  413. package/dist/src/kernel/project/mcp/prompts/provider.js.map +1 -0
  414. package/dist/src/kernel/project/mcp/prompts/source.js +154 -0
  415. package/dist/src/kernel/project/mcp/prompts/source.js.map +1 -0
  416. package/dist/src/kernel/project/mcp/registerVerb.js +315 -0
  417. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -0
  418. package/dist/src/kernel/project/mcp/serve.js +35 -0
  419. package/dist/src/kernel/project/mcp/serve.js.map +1 -0
  420. package/dist/src/kernel/render/compactUri.js +24 -0
  421. package/dist/src/kernel/render/compactUri.js.map +1 -0
  422. package/dist/src/kernel/render/contracts.js +10 -0
  423. package/dist/src/kernel/render/contracts.js.map +1 -0
  424. package/dist/src/kernel/render/disclosure.js +34 -0
  425. package/dist/src/kernel/render/disclosure.js.map +1 -0
  426. package/dist/src/kernel/render/envelope.js +30 -0
  427. package/dist/src/kernel/render/envelope.js.map +1 -0
  428. package/dist/src/kernel/render/formatters.js +27 -0
  429. package/dist/src/kernel/render/formatters.js.map +1 -0
  430. package/dist/src/kernel/render/index.js +15 -0
  431. package/dist/src/kernel/render/index.js.map +1 -0
  432. package/dist/src/kernel/render/prefixes.js +46 -0
  433. package/dist/src/kernel/render/prefixes.js.map +1 -0
  434. package/dist/src/kernel/render/renderers.js +468 -0
  435. package/dist/src/kernel/render/renderers.js.map +1 -0
  436. package/dist/src/kernel/render/style.js +105 -0
  437. package/dist/src/kernel/render/style.js.map +1 -0
  438. package/dist/src/kernel/render/turtle.js +194 -0
  439. package/dist/src/kernel/render/turtle.js.map +1 -0
  440. package/dist/src/kernel/render/vocabulary.js +174 -0
  441. package/dist/src/kernel/render/vocabulary.js.map +1 -0
  442. package/dist/src/kernel/render/writeStdout.js +43 -0
  443. package/dist/src/kernel/render/writeStdout.js.map +1 -0
  444. package/dist/src/kernel/runtime/boot.js +49 -0
  445. package/dist/src/kernel/runtime/boot.js.map +1 -0
  446. package/dist/src/kernel/runtime/facade.js +39 -0
  447. package/dist/src/kernel/runtime/facade.js.map +1 -0
  448. package/dist/src/kernel/runtime/graphpack/build.js +122 -0
  449. package/dist/src/kernel/runtime/graphpack/build.js.map +1 -0
  450. package/dist/src/kernel/runtime/graphpack/buildIndex.js +303 -0
  451. package/dist/src/kernel/runtime/graphpack/buildIndex.js.map +1 -0
  452. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +6 -0
  453. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -0
  454. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +4 -0
  455. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -0
  456. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js +4 -0
  457. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js.map +1 -0
  458. package/dist/src/kernel/runtime/graphpack/embedded.js +82 -0
  459. package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -0
  460. package/dist/src/kernel/runtime/graphpack/hash.js +38 -0
  461. package/dist/src/kernel/runtime/graphpack/hash.js.map +1 -0
  462. package/dist/src/kernel/runtime/graphpack/index.js +11 -0
  463. package/dist/src/kernel/runtime/graphpack/index.js.map +1 -0
  464. package/dist/src/kernel/runtime/graphpack/manifest.js +145 -0
  465. package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -0
  466. package/dist/src/kernel/runtime/graphpack/read.js +92 -0
  467. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -0
  468. package/dist/src/kernel/runtime/graphpack/schemas.js +70 -0
  469. package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -0
  470. package/dist/src/kernel/runtime/graphpack/stories.js +68 -0
  471. package/dist/src/kernel/runtime/graphpack/stories.js.map +1 -0
  472. package/dist/src/kernel/runtime/graphpack/types.js +55 -0
  473. package/dist/src/kernel/runtime/graphpack/types.js.map +1 -0
  474. package/dist/src/kernel/runtime/index.js +8 -0
  475. package/dist/src/kernel/runtime/index.js.map +1 -0
  476. package/dist/src/kernel/runtime/loadSession.js +34 -0
  477. package/dist/src/kernel/runtime/loadSession.js.map +1 -0
  478. package/dist/src/kernel/runtime/paths.js +78 -0
  479. package/dist/src/kernel/runtime/paths.js.map +1 -0
  480. package/dist/src/kernel/runtime/probe.js +37 -0
  481. package/dist/src/kernel/runtime/probe.js.map +1 -0
  482. package/dist/src/kernel/runtime/readEntity.js +363 -0
  483. package/dist/src/kernel/runtime/readEntity.js.map +1 -0
  484. package/dist/src/kernel/runtime/refs/gitOps.js +65 -0
  485. package/dist/src/kernel/runtime/refs/gitOps.js.map +1 -0
  486. package/dist/src/kernel/runtime/refs/index.js +29 -0
  487. package/dist/src/kernel/runtime/refs/index.js.map +1 -0
  488. package/dist/src/kernel/runtime/refs/parseRef.js +70 -0
  489. package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -0
  490. package/dist/src/kernel/runtime/refs/resolve.js +332 -0
  491. package/dist/src/kernel/runtime/refs/resolve.js.map +1 -0
  492. package/dist/src/kernel/runtime/resolveSources.js +62 -0
  493. package/dist/src/kernel/runtime/resolveSources.js.map +1 -0
  494. package/dist/src/kernel/runtime/store.js +75 -0
  495. package/dist/src/kernel/runtime/store.js.map +1 -0
  496. package/dist/src/kernel/runtime/storeReadiness.js +51 -0
  497. package/dist/src/kernel/runtime/storeReadiness.js.map +1 -0
  498. package/dist/src/kernel/runtime/types.js +11 -0
  499. package/dist/src/kernel/runtime/types.js.map +1 -0
  500. package/dist/src/kernel/spec/asVerb.js +21 -0
  501. package/dist/src/kernel/spec/asVerb.js.map +1 -0
  502. package/dist/src/kernel/spec/emitReference.js +578 -0
  503. package/dist/src/kernel/spec/emitReference.js.map +1 -0
  504. package/dist/src/kernel/spec/emitSurface.js +202 -0
  505. package/dist/src/kernel/spec/emitSurface.js.map +1 -0
  506. package/dist/src/kernel/spec/index.js +11 -0
  507. package/dist/src/kernel/spec/index.js.map +1 -0
  508. package/dist/src/kernel/spec/surfaceConformance.js +103 -0
  509. package/dist/src/kernel/spec/surfaceConformance.js.map +1 -0
  510. package/dist/src/kernel/spec/types.js +14 -0
  511. package/dist/src/kernel/spec/types.js.map +1 -0
  512. package/dist/src/kernel/spec/validate.js +110 -0
  513. package/dist/src/kernel/spec/validate.js.map +1 -0
  514. package/dist/src/kernel/vocabulary.js +97 -0
  515. package/dist/src/kernel/vocabulary.js.map +1 -0
  516. package/dist/src/types.js +11 -0
  517. package/dist/src/types.js.map +1 -0
  518. package/package.json +22 -23
  519. package/pragma.conf.ts +486 -90
  520. package/src/bin.ts +274 -82
  521. package/src/capabilities/block.parity.test.ts +29 -12
  522. package/src/capabilities/block.shipped.exec.test.ts +282 -0
  523. package/src/capabilities/block.tierRank.exec.test.ts +300 -0
  524. package/src/capabilities/capabilities/capabilities.render.ts +1 -1
  525. package/src/capabilities/capabilities/capabilities.verb.ts +1 -1
  526. package/src/capabilities/capabilities/catalog.ts +3 -3
  527. package/src/capabilities/capabilities/hints.ts +32 -7
  528. package/src/capabilities/capabilities/index.ts +1 -1
  529. package/src/capabilities/colophon/collectColophon.ts +35 -24
  530. package/src/capabilities/colophon/colophon.render.ts +24 -1
  531. package/src/capabilities/colophon/colophon.test.ts +42 -21
  532. package/src/capabilities/colophon/colophon.verb.ts +4 -4
  533. package/src/capabilities/config/collectConfigShow.test.ts +1 -0
  534. package/src/capabilities/config/collectConfigShow.ts +3 -3
  535. package/src/capabilities/config/field.render.ts +4 -5
  536. package/src/capabilities/config/fields.ts +17 -10
  537. package/src/capabilities/config/get.verb.ts +70 -0
  538. package/src/capabilities/config/getUnset.test.ts +264 -0
  539. package/src/capabilities/config/index.ts +5 -1
  540. package/src/capabilities/config/runField.ts +40 -22
  541. package/src/capabilities/config/runGet.ts +34 -0
  542. package/src/capabilities/config/runSet.ts +35 -9
  543. package/src/capabilities/config/set.test.ts +48 -14
  544. package/src/capabilities/config/set.verb.ts +8 -7
  545. package/src/capabilities/config/show.render.ts +1 -1
  546. package/src/capabilities/config/show.verb.ts +9 -6
  547. package/src/capabilities/config/types.ts +18 -4
  548. package/src/capabilities/config/unset.verb.ts +58 -0
  549. package/src/capabilities/create/byteEquality.subprocess.test.ts +2 -3
  550. package/src/capabilities/create/byteEquality.test.ts +25 -11
  551. package/src/capabilities/create/cliProjection.ts +227 -0
  552. package/src/capabilities/create/constants.ts +36 -61
  553. package/src/capabilities/create/create.mcp.test.ts +89 -5
  554. package/src/capabilities/create/create.render.ts +71 -7
  555. package/src/capabilities/create/create.test.ts +433 -219
  556. package/src/capabilities/create/create.verb.ts +297 -328
  557. package/src/capabilities/create/createGrammar.test.ts +865 -0
  558. package/src/capabilities/create/createHelp.ts +71 -0
  559. package/src/capabilities/create/createSurface.generated.ts +400 -0
  560. package/src/capabilities/create/crossCli.subprocess.test.ts +745 -0
  561. package/src/capabilities/create/cwdJail.test.ts +24 -5
  562. package/src/capabilities/create/generatorToVerbSpec.test.ts +186 -0
  563. package/src/capabilities/create/generatorToVerbSpec.ts +13 -11
  564. package/src/capabilities/create/index.ts +7 -4
  565. package/src/capabilities/create/messages.ts +18 -0
  566. package/src/capabilities/create/mount.ts +391 -0
  567. package/src/capabilities/create/pathJail.test.ts +90 -0
  568. package/src/capabilities/create/pathJail.ts +8 -5
  569. package/src/capabilities/create/pickGenerator.ts +23 -35
  570. package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
  571. package/src/capabilities/create/types.ts +20 -0
  572. package/src/capabilities/distribution.parity.test.ts +4 -0
  573. package/src/capabilities/distribution.test.ts +3 -1
  574. package/src/capabilities/distribution.ts +10 -15
  575. package/src/capabilities/doctor/checks/checkKeStore.ts +7 -5
  576. package/src/capabilities/doctor/checks/checkPackageRefs.ts +75 -8
  577. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +2 -2
  578. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +76 -29
  579. package/src/capabilities/doctor/checks/checkShellCompletions.ts +63 -17
  580. package/src/capabilities/doctor/checks/harnessInventory.test.ts +219 -0
  581. package/src/capabilities/doctor/checks/harnessInventory.ts +298 -0
  582. package/src/capabilities/doctor/checks/index.ts +27 -0
  583. package/src/capabilities/doctor/checks/mcpCommand.test.ts +100 -0
  584. package/src/capabilities/doctor/checks/mcpCommand.ts +69 -0
  585. package/src/capabilities/doctor/checks/targetHealth.ts +444 -0
  586. package/src/capabilities/doctor/doctor.render.test.ts +125 -38
  587. package/src/capabilities/doctor/doctor.render.ts +74 -74
  588. package/src/capabilities/doctor/doctor.test.ts +338 -37
  589. package/src/capabilities/doctor/doctor.verb.ts +8 -3
  590. package/src/capabilities/doctor/runChecks.ts +65 -63
  591. package/src/capabilities/doctor/types.ts +22 -15
  592. package/src/capabilities/emptyRecovery.test.ts +21 -8
  593. package/src/capabilities/graph/examples.exec.test.ts +107 -0
  594. package/src/capabilities/graph/index.ts +1 -1
  595. package/src/capabilities/graph/inspect.render.ts +70 -22
  596. package/src/capabilities/graph/inspect.test.ts +260 -5
  597. package/src/capabilities/graph/inspect.verb.ts +18 -6
  598. package/src/capabilities/graph/query.render.ts +15 -3
  599. package/src/capabilities/graph/query.verb.ts +3 -3
  600. package/src/capabilities/graph/runQuery.ts +2 -3
  601. package/src/capabilities/index.ts +3 -1
  602. package/src/capabilities/info/collectInfo.ts +13 -5
  603. package/src/capabilities/info/info.render.ts +7 -3
  604. package/src/capabilities/info/info.test.ts +37 -1
  605. package/src/capabilities/info/info.verb.ts +1 -1
  606. package/src/capabilities/info/types.ts +10 -2
  607. package/src/capabilities/lazy.test.ts +32 -0
  608. package/src/capabilities/meta/complete.verb.ts +1 -1
  609. package/src/capabilities/meta/index.ts +1 -1
  610. package/src/capabilities/meta/mcp.verb.ts +10 -8
  611. package/src/capabilities/ontology/index.ts +15 -11
  612. package/src/capabilities/ontology/ontology.test.ts +6 -55
  613. package/src/capabilities/ontology/queries.ts +2 -2
  614. package/src/capabilities/ontology/render.ts +3 -4
  615. package/src/capabilities/ontology/verbs.ts +27 -68
  616. package/src/capabilities/prompt/index.ts +2 -2
  617. package/src/capabilities/prompt/prompt.render.ts +6 -2
  618. package/src/capabilities/prompt/types.ts +1 -1
  619. package/src/capabilities/prompt/verbs.ts +4 -5
  620. package/src/capabilities/reference.test.ts +63 -0
  621. package/src/capabilities/renderVocabularySync.test.ts +82 -0
  622. package/src/capabilities/resources/provider.ts +342 -85
  623. package/src/capabilities/resources/resources.test.ts +355 -59
  624. package/src/capabilities/scopeTypeSync.test.ts +29 -15
  625. package/src/capabilities/setup/buildPlan.ts +240 -0
  626. package/src/capabilities/setup/index.ts +7 -7
  627. package/src/capabilities/setup/mode.ts +74 -0
  628. package/src/capabilities/setup/operations/index.ts +79 -0
  629. package/src/capabilities/setup/operations/setupCompletions.ts +97 -24
  630. package/src/capabilities/setup/operations/setupConfig.ts +124 -0
  631. package/src/capabilities/setup/operations/setupGenerator.ts +478 -334
  632. package/src/capabilities/setup/operations/setupLsp.ts +420 -67
  633. package/src/capabilities/setup/operations/setupMcp.ts +238 -127
  634. package/src/capabilities/setup/operations/setupSkills.ts +667 -105
  635. package/src/capabilities/setup/plan.render.ts +336 -0
  636. package/src/capabilities/setup/plan.ts +241 -0
  637. package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
  638. package/src/capabilities/setup/setup.render.test.ts +297 -75
  639. package/src/capabilities/setup/setup.render.ts +45 -77
  640. package/src/capabilities/setup/setup.test.ts +1819 -225
  641. package/src/capabilities/setup/setup.verb.ts +288 -78
  642. package/src/capabilities/setup/shell.test.ts +86 -0
  643. package/src/capabilities/setup/shell.ts +137 -11
  644. package/src/capabilities/setup/targets.ts +435 -0
  645. package/src/capabilities/setup/types.ts +23 -70
  646. package/src/capabilities/shared/assertExecOk.ts +68 -10
  647. package/src/capabilities/shared/index.ts +43 -0
  648. package/src/capabilities/shared/packageManager.test.ts +470 -0
  649. package/src/capabilities/shared/packageManager.ts +425 -34
  650. package/src/capabilities/skill/bundledSkills.test.ts +347 -0
  651. package/src/capabilities/skill/discover.ts +131 -10
  652. package/src/capabilities/skill/index.ts +1 -1
  653. package/src/capabilities/skill/render.ts +10 -9
  654. package/src/capabilities/skill/skill.test.ts +22 -7
  655. package/src/capabilities/skill/verbs.ts +3 -4
  656. package/src/capabilities/sources/collectStatus.ts +7 -2
  657. package/src/capabilities/sources/index.ts +1 -1
  658. package/src/capabilities/sources/installSkills.ts +265 -10
  659. package/src/capabilities/sources/runUpdate.ts +131 -23
  660. package/src/capabilities/sources/sources.test.ts +382 -2
  661. package/src/capabilities/sources/status.render.ts +1 -1
  662. package/src/capabilities/sources/status.verb.ts +1 -1
  663. package/src/capabilities/sources/update.render.ts +1 -1
  664. package/src/capabilities/sources/update.verb.ts +4 -4
  665. package/src/capabilities/surface.test.ts +136 -19
  666. package/src/capabilities/upgrade/runUpgrade.ts +53 -14
  667. package/src/capabilities/upgrade/types.ts +10 -2
  668. package/src/capabilities/upgrade/upgrade.render.ts +13 -7
  669. package/src/capabilities/upgrade/upgrade.test.ts +75 -3
  670. package/src/capabilities/upgrade/upgrade.verb.ts +1 -1
  671. package/src/capabilities/version/index.ts +12 -0
  672. package/src/capabilities/version/version.test.ts +66 -0
  673. package/src/capabilities/version/version.verb.ts +39 -0
  674. package/src/constants.ts +36 -1
  675. package/src/identity.test.ts +57 -29
  676. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +15 -13
  677. package/src/kernel/completion/complete.test.ts +12 -2
  678. package/src/kernel/completion/complete.ts +1 -1
  679. package/src/kernel/completion/emitScripts.ts +1 -1
  680. package/src/kernel/completion/entitySource.test.ts +16 -3
  681. package/src/kernel/completion/entitySource.ts +21 -8
  682. package/src/kernel/completion/model.test.ts +164 -12
  683. package/src/kernel/completion/model.ts +94 -14
  684. package/src/kernel/completion/parse.test.ts +4 -7
  685. package/src/kernel/completion/parse.ts +15 -0
  686. package/src/kernel/completion/resolve.test.ts +0 -1
  687. package/src/kernel/completion/safety.test.ts +50 -35
  688. package/src/kernel/completion/shellDrive.test.ts +28 -9
  689. package/src/kernel/completion/templates/bash.ts +7 -2
  690. package/src/kernel/completion/templates/index.ts +23 -0
  691. package/src/kernel/completion/types.ts +7 -0
  692. package/src/kernel/config/defaults.test.ts +27 -3
  693. package/src/kernel/config/defaults.ts +4 -3
  694. package/src/kernel/config/evaluateProjectConfig.ts +31 -8
  695. package/src/kernel/config/firstRun.test.ts +44 -38
  696. package/src/kernel/config/firstRun.ts +24 -88
  697. package/src/kernel/config/index.ts +1 -1
  698. package/src/kernel/config/readConfig.test.ts +6 -3
  699. package/src/kernel/config/readConfig.ts +1 -1
  700. package/src/kernel/config/schema.ts +3 -1
  701. package/src/kernel/config/types.ts +3 -1
  702. package/src/kernel/copy.test.ts +34 -4
  703. package/src/kernel/copy.ts +54 -0
  704. package/src/kernel/error/PragmaError.test.ts +5 -2
  705. package/src/kernel/error/PragmaError.ts +4 -2
  706. package/src/kernel/error/constants.ts +7 -5
  707. package/src/kernel/error/fromTaskError.ts +28 -6
  708. package/src/kernel/error/recovery.ts +14 -0
  709. package/src/kernel/error/renderError.ts +42 -1
  710. package/src/kernel/error/types.ts +21 -1
  711. package/src/kernel/index.ts +35 -0
  712. package/src/kernel/interactivity.test.ts +76 -0
  713. package/src/kernel/interactivity.ts +69 -0
  714. package/src/kernel/packs/collect.ts +12 -16
  715. package/src/kernel/packs/compile.test.ts +222 -1
  716. package/src/kernel/packs/compile.ts +93 -3
  717. package/src/kernel/packs/disclosure.ts +2 -2
  718. package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
  719. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +3 -4
  720. package/src/kernel/packs/graphql/index.ts +20 -0
  721. package/src/kernel/packs/index.ts +40 -0
  722. package/src/kernel/packs/iri.test.ts +73 -0
  723. package/src/kernel/packs/iri.ts +66 -14
  724. package/src/kernel/packs/renderPack.ts +25 -6
  725. package/src/kernel/packs/resolveEntity.test.ts +274 -0
  726. package/src/kernel/packs/resolveEntity.ts +200 -42
  727. package/src/kernel/packs/runBodies.ts +86 -22
  728. package/src/kernel/packs/sample.ts +1 -1
  729. package/src/kernel/packs/schema.ts +78 -5
  730. package/src/kernel/packs/sparql/applyFilters.ts +136 -16
  731. package/src/kernel/packs/sparql/buildLookupQuery.test.ts +290 -0
  732. package/src/kernel/packs/sparql/buildLookupQuery.ts +367 -17
  733. package/src/kernel/packs/sparql/index.ts +37 -0
  734. package/src/kernel/packs/sparql/runSelect.test.ts +1 -1
  735. package/src/kernel/packs/sparql/runSelect.ts +3 -4
  736. package/src/kernel/packs/toolDescription.test.ts +77 -4
  737. package/src/kernel/packs/types.ts +136 -0
  738. package/src/kernel/packs/uniqueness.ts +1 -1
  739. package/src/kernel/project/cli/buildProgram.test.ts +218 -12
  740. package/src/kernel/project/cli/buildProgram.ts +84 -18
  741. package/src/kernel/project/cli/constants.ts +34 -0
  742. package/src/kernel/project/cli/dispatch.test.ts +160 -2
  743. package/src/kernel/project/cli/dispatch.ts +226 -45
  744. package/src/kernel/project/cli/exitCodes.ts +1 -1
  745. package/src/kernel/project/cli/globalFlags.test.ts +117 -1
  746. package/src/kernel/project/cli/globalFlags.ts +134 -31
  747. package/src/kernel/project/cli/helpFormat.ts +14 -2
  748. package/src/kernel/project/cli/rootHelp.ts +74 -12
  749. package/src/kernel/project/cli/suggest.test.ts +33 -1
  750. package/src/kernel/project/cli/suggest.ts +25 -1
  751. package/src/kernel/project/cli/verbHelp.test.ts +30 -0
  752. package/src/kernel/project/cli/verbHelp.ts +23 -7
  753. package/src/kernel/project/mcp/buildServer.ts +7 -4
  754. package/src/kernel/project/mcp/envelope.ts +2 -2
  755. package/src/kernel/project/mcp/instructions.ts +2 -2
  756. package/src/kernel/project/mcp/mcpError.ts +1 -1
  757. package/src/kernel/project/mcp/parity.test.ts +5 -2
  758. package/src/kernel/project/mcp/prompts/index.ts +37 -0
  759. package/src/kernel/project/mcp/prompts/source.ts +2 -2
  760. package/src/kernel/project/mcp/registerVerb.ts +55 -10
  761. package/src/kernel/project/mcp/serve.ts +2 -2
  762. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
  763. package/src/kernel/render/contracts.ts +21 -0
  764. package/src/kernel/render/envelope.ts +2 -3
  765. package/src/kernel/render/formatters.ts +1 -1
  766. package/src/kernel/render/renderers.test.ts +243 -6
  767. package/src/kernel/render/renderers.ts +222 -20
  768. package/src/kernel/render/style.test.ts +75 -24
  769. package/src/kernel/render/style.ts +59 -6
  770. package/src/kernel/render/turtle.ts +222 -0
  771. package/src/kernel/render/vocabulary.ts +276 -0
  772. package/src/kernel/runtime/graphpack/buildIndex.ts +1 -1
  773. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +3 -3
  774. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
  775. package/src/kernel/runtime/graphpack/embedded.ts +3 -3
  776. package/src/kernel/runtime/graphpack/manifest.ts +1 -1
  777. package/src/kernel/runtime/graphpack/read.ts +1 -2
  778. package/src/kernel/runtime/loadSession.ts +1 -1
  779. package/src/kernel/runtime/probe.ts +6 -6
  780. package/src/kernel/runtime/readEntity.ts +472 -28
  781. package/src/kernel/runtime/refs/index.ts +39 -0
  782. package/src/kernel/runtime/refs/parseRef.ts +2 -2
  783. package/src/kernel/runtime/refs/resolve.ts +4 -4
  784. package/src/kernel/runtime/storeReadiness.ts +1 -2
  785. package/src/kernel/runtime/types.ts +15 -1
  786. package/src/kernel/runtime/wasmEmbed.test.ts +37 -39
  787. package/src/kernel/spec/emitReference.ts +105 -30
  788. package/src/kernel/spec/emitSurface.ts +48 -6
  789. package/src/kernel/spec/surfaceConformance.test.ts +4 -2
  790. package/src/kernel/spec/types.ts +277 -4
  791. package/src/testing/PARITY_GAPS.ts +9 -3
  792. package/src/testing/behavioral/docExamples.test.ts +16 -0
  793. package/src/testing/behavioral/errorMatrix.mcp.test.ts +112 -9
  794. package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
  795. package/src/testing/behavioral/journeys.cli.test.ts +1 -1
  796. package/src/testing/behavioral/journeys.defaultPack.test.ts +7 -7
  797. package/src/testing/behavioral/journeys.firstInstall.test.ts +7 -2
  798. package/src/testing/behavioral/journeys.implementation.test.ts +206 -0
  799. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +2 -2
  800. package/src/testing/behavioral/journeys.packageStories.test.ts +10 -7
  801. package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
  802. package/src/testing/behavioral/mcpSurface.test.ts +1 -1
  803. package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
  804. package/src/testing/eval/__snapshots__/eval.test.ts.snap +26 -1
  805. package/src/testing/eval/cases/effectful.ts +3 -2
  806. package/src/testing/eval/cases/readNouns.ts +245 -9
  807. package/src/testing/fixtures/blockGraph.ts +104 -10
  808. package/src/testing/fixtures/graph/canonical.ts +182 -13
  809. package/src/testing/fixtures/graph/defaultPack.ts +1 -1
  810. package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
  811. package/src/testing/helpers/projectMcp.ts +32 -6
  812. package/src/testing/helpers/runCli.ts +35 -18
  813. package/src/testing/perf/budgets.test.ts +20 -9
  814. package/src/testing/perf/budgets.ts +58 -9
  815. package/src/testing/perf/codegen.test.ts +126 -0
  816. package/src/testing/perf/globalSetup.test.ts +286 -0
  817. package/src/testing/perf/globalSetup.ts +505 -23
  818. package/src/testing/perf/measure.test.ts +38 -0
  819. package/src/testing/perf/measure.ts +23 -4
  820. package/src/testing/setupXdgIsolation.ts +81 -21
  821. package/src/testing/tempRoot.globalSetup.ts +122 -0
  822. package/dist/pragma +0 -0
  823. package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -189
  824. package/src/capabilities/create/templates.embedded.generated.ts +0 -28
  825. package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -42
  826. package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
  827. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -68
  828. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -61
  829. package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
  830. package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
  831. package/src/capabilities/shared/bands.ts +0 -16
  832. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
@@ -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,14 +26,9 @@ 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
29
  import { CREATE_GENERATORS } from "./constants.js";
29
- import {
30
- createVerbs,
31
- INCLUDE_FLAG_ALIASES,
32
- isModuleNotFound,
33
- } from "./create.verb.js";
34
- import { generatorToParams } from "./generatorToVerbSpec.js";
30
+ import { createVerbs, isModuleNotFound } from "./create.verb.js";
31
+ import { CREATE_SURFACE } from "./createSurface.generated.js";
35
32
  import { createModule } from "./index.js";
36
33
 
37
34
  const FLAGS: GlobalFlags = {
@@ -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
- createVerbs.component,
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,8 +89,10 @@ 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
90
98
  // full generator run (~2.4s idle), and under a contended CI matrix the 5s
@@ -105,6 +113,150 @@ describe("create — real generation + stamp", () => {
105
113
  expect(walk(dir)).toEqual([]); // nothing written
106
114
  });
107
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
+
108
260
  it("--dry-run reports the bytes the real run writes (post-stamp)", async () => {
109
261
  // The mock previewer never called `onEffectStart`, so summon's stamping
110
262
  // transform did not run and every planned byte count under-reported the
@@ -117,17 +269,19 @@ describe("create — real generation + stamp", () => {
117
269
  withSsrTests: false,
118
270
  };
119
271
  const previewDir = freshCwd();
120
- const preview = await runIn(previewDir, params, {
121
- dryRun: true,
122
- undo: false,
123
- yes: false,
124
- });
272
+ const preview = await runIn(
273
+ previewDir,
274
+ params,
275
+ { dryRun: true, undo: false, yes: false },
276
+ createVerbs.component,
277
+ JSON_FLAGS,
278
+ );
125
279
  expect(preview.exitCode).toBe(0);
126
280
  expect(walk(previewDir)).toEqual([]);
127
281
 
128
282
  const planned = new Map<string, number>();
129
- for (const line of (preview.stdout ?? "").split("\n")) {
130
- const match = /^ {2}- Write file: (.+) \((\d+) bytes\)$/.exec(line);
283
+ for (const line of jsonPlan(preview.stdout)) {
284
+ const match = /^Write file: (.+) \((\d+) bytes\)$/.exec(line);
131
285
  if (match) planned.set(match[1] as string, Number(match[2]));
132
286
  }
133
287
  expect(planned.size).toBeGreaterThan(0);
@@ -170,17 +324,23 @@ describe("create — real generation + stamp", () => {
170
324
  // stamp test above, doubled; same explicit ceiling.
171
325
  }, 60_000);
172
326
 
173
- it("rejects an unknown framework with INVALID_INPUT", async () => {
327
+ it("rejects an unknown framework with INVALID_INPUT", () => {
174
328
  const dir = freshCwd();
175
- // coerceParam rejects the enum before run, so drive run directly via a bad
176
- // 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).
177
331
  const runtime = bootRuntime(FLAGS, dir);
178
- await expect(
332
+ expect(() =>
179
333
  createVerbs.component.run({ framework: "vue" }, {
180
334
  ...runtime,
181
335
  interaction: { isTTY: false, transport: "cli", yes: true },
182
336
  } as never),
183
- ).rejects.toBeInstanceOf(PragmaError);
337
+ ).toThrow(PragmaError);
338
+ expect(() =>
339
+ createVerbs.component.run({}, {
340
+ ...runtime,
341
+ interaction: { isTTY: false, transport: "cli", yes: true },
342
+ } as never),
343
+ ).toThrow(/framework/);
184
344
  });
185
345
  });
186
346
 
@@ -192,26 +352,88 @@ describe("SEC-2 path jail (PROTECTED)", () => {
192
352
  for (const [label, value] of cases) {
193
353
  it(`rejects ${label} with a PragmaError before any effect`, async () => {
194
354
  const dir = freshCwd();
195
- // The jail throws in `run`, before any effect; the projector maps it to an
196
- // 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.
197
360
  await expect(
198
361
  runIn(dir, { framework: "react", componentPath: value }),
199
- ).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
+ });
200
373
  expect(walk(dir)).toEqual([]);
201
374
  });
202
375
  }
203
376
 
204
- 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 () => {
205
403
  const root = freshCwd();
206
404
  const outside = freshCwd();
207
- // 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.
208
408
  symlinkSync(outside, join(root, "link"));
209
409
  await expect(
210
410
  runIn(root, { framework: "react", componentPath: "link/Widget" }),
211
- ).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
+ });
212
417
  expect(existsSync(join(outside, "Widget"))).toBe(false);
213
418
  });
214
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
+
215
437
  it("accepts an in-workspace path", async () => {
216
438
  const dir = freshCwd();
217
439
  mkdirSync(join(dir, "packages"), { recursive: true });
@@ -306,158 +528,184 @@ describe("lazy-React discipline (PROTECTED)", () => {
306
528
  });
307
529
  });
308
530
 
309
- describe("generator→grammar adapter parity (PROTECTED)", () => {
310
- // The static mirrors in create.verb.ts are AUTHORITATIVE for omitted CLI
311
- // flags: dispatch.extractParams fills ParamSpec.default when a flag is absent,
312
- // so a drifted mirror default silently overrides the generator's own default.
313
- // These guards assert the EMITTED grammar (names, kinds, defaults, choices)
314
- // still matches the real generators for all three create nouns — the
315
- // byte-equality goldens can't catch this (they pass every param explicitly).
316
-
317
- /** Drop `doc` (help text is intentionally paraphrased in the mirrors) so the
318
- * comparison is purely behavioural: names, kinds, defaults, choices. */
319
- const behavioural = (
320
- params: readonly ParamSpec[],
321
- ): Record<string, unknown>[] =>
322
- params.map((p) => {
323
- const clone: Record<string, unknown> = { ...p };
324
- delete clone.doc;
325
- return clone;
326
- });
327
-
328
- /** `runInstall` is a DELIBERATE divergence (package + application): the real
329
- * generators default it `true`, but the CLI grammar has no `--no-` form, so
330
- * the mirror makes install opt-in (`default:false`, enabled by `--run-install`).
331
- * Apply that same override to the generator side before comparing. */
332
- const applyRunInstallOverride = (params: readonly ParamSpec[]): ParamSpec[] =>
333
- params.map((p) =>
334
- p.name === "runInstall" ? ({ ...p, default: false } as ParamSpec) : p,
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.
540
+
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,
335
548
  );
549
+ expect(Object.keys(CREATE_SURFACE).sort()).toEqual(
550
+ [...declaredPaths].sort(),
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
+ });
336
559
 
337
- it("component: framework collapse + shared confirms match the react generator", async () => {
338
- const { generators } = await import("@canonical/summon-component");
339
- const real = generatorToParams(
340
- (generators as Record<string, { prompts: unknown[] }>)["component/react"]
341
- .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,
342
572
  );
343
- const verb = createVerbs.component.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
+ });
344
609
 
345
- // The verb SYNTHESIZES a `framework` enum (the 3 framework generators
346
- // collapse to one verb): react|svelte|lit, default react — no generator
347
- // prompt corresponds to it.
348
- expect(verb.find((p) => p.name === "framework")).toMatchObject({
349
- kind: "enum",
350
- values: ["react", "svelte", "lit"],
351
- default: "react",
352
- });
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
+ ]);
353
622
 
354
- // componentPath deliberately drops its ParamSpec default so the SELECTED
355
- // framework's own prompt default applies (react vs svelte/lit differ).
356
- const verbPath = verb.find((p) => p.name === "componentPath") as
357
- | Record<string, unknown>
358
- | undefined;
359
- 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
360
627
  | Record<string, unknown>
361
628
  | undefined;
362
- expect(verbPath).toMatchObject({
629
+ expect(componentPath).toMatchObject({
363
630
  kind: "string",
364
631
  positional: true,
632
+ required: false,
365
633
  complete: { kind: "files" },
366
634
  });
367
- expect(verbPath?.default).toBeUndefined();
368
- expect(realPath?.default).toBe("src/components/MyComponent");
369
-
370
- // Every other prompt (the shared confirms) must match names, kinds, AND
371
- // defaults exactly — the silent-drift surface.
372
- const shared = (ps: readonly ParamSpec[]) =>
373
- behavioural(
374
- ps.filter((p) => p.name !== "framework" && p.name !== "componentPath"),
375
- );
376
- expect(shared(verb)).toEqual(shared(real));
377
- });
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
+ });
378
642
 
379
- it("package: mirror matches the package generator (defaults + type choices)", async () => {
380
- const { generators } = await import("@canonical/summon-package");
381
- const real = generatorToParams(
382
- (generators as Record<string, { prompts: unknown[] }>).package
383
- .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)",
384
646
  );
385
- // The package verb's grammar IS generatorToParams(PACKAGE_MIRROR).
386
- expect(behavioural(createVerbs.package.params)).toEqual(
387
- behavioural(applyRunInstallOverride(real)),
647
+ expect(params.find((p) => p.name === "useTsStories")?.doc).toContain(
648
+ "(frameworks: svelte)",
388
649
  );
650
+ // …and a universal one does not.
651
+ expect(params.find((p) => p.name === "withStories")?.doc).not.toContain(
652
+ "frameworks:",
653
+ );
654
+ });
389
655
 
390
- // Guard the intentional runInstall override so it can't silently flip.
391
- const realRunInstall = real.find((p) => p.name === "runInstall") as
392
- | Record<string, unknown>
393
- | undefined;
394
- const mirrorRunInstall = createVerbs.package.params.find(
395
- (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",
396
659
  ) as Record<string, unknown> | undefined;
397
- expect(realRunInstall?.default).toBe(true);
398
- expect(mirrorRunInstall?.default).toBe(false);
399
-
400
- // The `--type` enum choices are load-bearing and must match exactly.
401
- const realType = real.find((p) => p.name === "type");
402
- expect(realType).toMatchObject({
660
+ expect(framework).toMatchObject({
403
661
  kind: "enum",
404
- values: ["tool-ts", "library", "css"],
405
- default: "tool-ts",
662
+ required: true,
663
+ positional: true,
664
+ values: CREATE_GENERATORS.component.paths.map(
665
+ (path) => path.split("/")[1],
666
+ ),
406
667
  });
668
+ // Summon has no default framework; neither does the projection of it.
669
+ expect(framework?.default).toBeUndefined();
407
670
  });
408
671
 
409
- /** Map a mirror's CLI `--with-X` include-flag names back to the generator
410
- * prompt names (AV-228 B8) so the parity comparison still checks kinds and
411
- * defaults against the real generator despite the deliberate flag rename. */
412
- const toGeneratorNames = (
413
- kind: "application",
414
- params: readonly ParamSpec[],
415
- ): ParamSpec[] =>
416
- params.map((p) => {
417
- const generatorName = INCLUDE_FLAG_ALIASES[kind][p.name];
418
- return generatorName ? ({ ...p, name: generatorName } as ParamSpec) : p;
419
- });
420
-
421
- it("application: mirror matches the application/react generator (defaults)", async () => {
422
- const { generators } = await import("@canonical/summon-application");
423
- const real = generatorToParams(
424
- (generators as Record<string, { prompts: unknown[] }>)[
425
- "application/react"
426
- ].prompts as never,
427
- );
428
- // Bridge the B8 include-flag rename before comparing: the CLI grammar
429
- // exposes `withSsr`/`withRouter`/`withForms`, which map back to the
430
- // 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.
431
695
  expect(
432
- behavioural(
433
- toGeneratorNames("application", createVerbs.application.params),
434
- ),
435
- ).toEqual(behavioural(applyRunInstallOverride(real)));
436
-
437
- // Guard the B8 rename itself: ALL application include-flags ARE on the
438
- // `--with-X` convention (params `withSsr`/`withRouter`/`withForms`/
439
- // `withRelay`), not the bare `ssr`/`router`/`forms`/`relay` booleans.
440
- const names = createVerbs.application.params.map((p) => p.name);
441
- expect(names).toContain("withSsr");
442
- expect(names).toContain("withRouter");
443
- expect(names).toContain("withForms");
444
- expect(names).toContain("withRelay");
445
- expect(names).not.toContain("ssr");
446
- expect(names).not.toContain("relay");
447
-
448
- const realRunInstall = real.find((p) => p.name === "runInstall") as
449
- | Record<string, unknown>
450
- | undefined;
451
- const mirrorRunInstall = createVerbs.application.params.find(
452
- (p) => p.name === "runInstall",
453
- ) as Record<string, unknown> | undefined;
454
- expect(realRunInstall?.default).toBe(true);
455
- expect(mirrorRunInstall?.default).toBe(false);
456
-
457
- // 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.
458
702
  expect(
459
- createVerbs.application.params.find((p) => p.name === "appPath"),
460
- ).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
+ });
461
709
  });
462
710
  });
463
711
 
@@ -489,77 +737,43 @@ describe("compiled-binary create gate (M4)", () => {
489
737
  describe("declared generator bindings (PROTECTED)", () => {
490
738
  // CREATE_GENERATORS is the one place the create surface's generator facts are
491
739
  // written down. What is checkable against something outside itself — the live
492
- // generator maps and the embedded manifest — is checked here.
740
+ // generator maps — is checked here.
493
741
 
494
- it("every binding resolves to the generator it names", async () => {
742
+ it("every declared path resolves to a generator whose meta.name IS the path", async () => {
495
743
  const { pickGenerator } = await import("./pickGenerator.js");
496
- // `meta.name` is the generator's OWN identity, so a swapped `key` or a
497
- // framework the map does not carry turns this red — which `toBeDefined()`
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()`
498
746
  // on a non-nullable return could not.
499
- for (const framework of CREATE_GENERATORS.component.frameworks) {
500
- expect(pickGenerator("component", { framework }).meta.name).toBe(
501
- `component/${framework}`,
502
- );
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
+ }
503
751
  }
504
- expect(pickGenerator("package", {}).meta.name).toBe("package");
505
- expect(pickGenerator("application", {}).meta.name).toBe(
506
- "application/react",
507
- );
508
752
  });
509
753
 
510
- it("exactly the two source-run-only verbs publish the availability caveat", () => {
511
- // A LITERAL list, for the same reason `compiledCreate.subprocess.test.ts`
512
- // uses one: the caveat is DERIVED from `readsEmbeddedTemplates`, so an
513
- // assertion derived from the same bit would agree with itself no matter
514
- // which way the bit was flipped. These two are the nouns that test proves
515
- // refuse on a real compiled binary, so this is what the reference is held
516
- // to — and flipping the bit turns this red, along with the reference
517
- // drift-guard, in the same run.
518
- const caveated = createModule.verbs
519
- .filter((verb) => verb.summary.includes("Source-run only."))
520
- .map((verb) => verb.path.at(1));
521
- expect(caveated).toEqual(["package", "application"]);
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.
522
760
  for (const verb of createModule.verbs) {
523
- const kind = verb.path.at(1);
524
- const gated = caveated.includes(kind);
525
- // The `doc` is what `tools.md` and the MCP tool description render, so
526
- // the explanation has to travel with the marker, and it quotes the
527
- // command it is about — a copy-paste between bindings is then visible.
528
- expect(verb.doc?.includes("UNSUPPORTED") ?? false, kind).toBe(gated);
529
- if (gated) {
530
- expect(verb.doc).toContain(`create ${kind}`);
531
- // And it still says what the verb MAKES. `doc ?? summary` means a doc
532
- // REPLACES the summary on the MCP surface, so a caveat alone left an
533
- // agent no statement anywhere of what `create_package` scaffolds.
534
- expect(verb.doc).toContain(
535
- verb.summary.replace(" Source-run only.", ""),
536
- );
537
- }
761
+ expect(verb.summary).not.toContain("Source-run only.");
762
+ expect(verb.doc ?? "").not.toContain("UNSUPPORTED");
538
763
  }
539
764
  });
540
765
 
541
- it("the --framework enum offers the declared frameworks and defaults to one of them", () => {
766
+ it("the framework enum offers the declared segments — non-empty, and NO default", () => {
542
767
  const framework = createVerbs.component.params.find(
543
768
  (p) => p.name === "framework",
544
769
  );
545
- // A `values: []` enum with a `default` would leave every `--framework`
546
- // rejected while `--help` still advertises a default — the hazard this names.
547
- // (That every value resolves is the test above.)
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.)
548
773
  expect(framework?.kind).toBe("enum");
549
774
  const values = (framework as { values: readonly string[] }).values;
550
775
  expect(values.length).toBeGreaterThan(0);
551
- expect(values).toContain(framework?.default);
552
- });
553
-
554
- it("embeds only the templates the component loader can key", async () => {
555
- const { TEMPLATES } = await import("./templates.embedded.generated.js");
556
- const keys = Object.keys(TEMPLATES);
557
- // summon-component's `qualifiedKey()` prefixes EVERY lookup with
558
- // `component/`, so any other entry ships dead weight the binary can never
559
- // read — and a binding embedded without a manifest-reading generator would
560
- // put one here. Non-empty first: `.every()` over an empty list is vacuous.
561
- expect(keys.length).toBeGreaterThan(0);
562
- expect(keys.filter((k) => !k.startsWith("component/"))).toEqual([]);
776
+ expect(framework?.default).toBeUndefined();
563
777
  });
564
778
 
565
779
  it("create surfaces exactly the three declared nouns", () => {