@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
@@ -0,0 +1,865 @@
1
+ /**
2
+ * The mounted create grammar, end to end on the REAL bin (subprocess — the
3
+ * mount, the designed help, the R1 migration error, the excess guard and the
4
+ * refusal all live across bin.ts + buildProgram + the mount, so in-process
5
+ * slices would miss their composition), plus in-process pins for the
6
+ * dispatchPrepared refusal cell and the wizard's explicit-answer seed.
7
+ */
8
+
9
+ import { spawnSync } from "node:child_process";
10
+ import { mkdirSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { dirname, join, resolve } from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ import {
15
+ buildOptionInfo,
16
+ missingExplicitFlags,
17
+ } from "@canonical/summon-core/projection";
18
+ import { afterEach, describe, expect, it, vi } from "vitest";
19
+ import { RECOVERY_CLI_PREFIX, VERSION } from "../../constants.js";
20
+ import type { GlobalFlags } from "../../kernel/runtime/types.js";
21
+ import { CREATE_SURFACE } from "./createSurface.generated.js";
22
+ import {
23
+ explicitLeafAnswers,
24
+ leafVerb,
25
+ resolveCreateMode,
26
+ topicTree,
27
+ } from "./mount.js";
28
+
29
+ const here = dirname(fileURLToPath(import.meta.url));
30
+ const packageRoot = resolve(here, "../../..");
31
+ const pragmaBin = join(packageRoot, "src/bin.ts");
32
+ const freshCwd = (): string => mkdtempSync(join(tmpdir(), "pragma-grammar-"));
33
+
34
+ const FLAGS: GlobalFlags = {
35
+ llm: false,
36
+ autoLlm: false,
37
+ format: "plain",
38
+ verbose: false,
39
+ };
40
+
41
+ /** Spawn the real bin non-interactively in a fresh, XDG-isolated cwd. */
42
+ function run(args: readonly string[]): {
43
+ status: number | null;
44
+ stdout: string;
45
+ stderr: string;
46
+ cwd: string;
47
+ } {
48
+ const cwd = freshCwd();
49
+ const result = spawnSync("bun", [pragmaBin, ...args], {
50
+ cwd,
51
+ encoding: "utf-8",
52
+ input: "",
53
+ env: {
54
+ ...process.env,
55
+ XDG_CONFIG_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-")),
56
+ XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
57
+ XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
58
+ },
59
+ });
60
+ return {
61
+ status: result.status,
62
+ stdout: result.stdout ?? "",
63
+ stderr: result.stderr ?? "",
64
+ cwd,
65
+ };
66
+ }
67
+
68
+ describe("the mounted create grammar (subprocess)", () => {
69
+ it("bare `create` prints the topic tree and exits 0", () => {
70
+ const { status, stdout } = run(["create"]);
71
+ expect(status).toBe(0);
72
+ expect(stdout).toContain("component");
73
+ expect(stdout).toContain("react");
74
+ expect(stdout).toContain("svelte");
75
+ expect(stdout).toContain("lit");
76
+ expect(stdout).toContain("package");
77
+ expect(stdout).toContain("application");
78
+ // Derived from the manifest: paths + descriptions.
79
+ expect(stdout).toContain(
80
+ CREATE_SURFACE["component/react"]?.description ?? "",
81
+ );
82
+ }, 60_000);
83
+
84
+ it("`create --help` prints the same topic tree, exit 0", () => {
85
+ const bare = run(["create"]);
86
+ const help = run(["create", "--help"]);
87
+ expect(help.status).toBe(0);
88
+ // Same tree; Commander's help path appends one extra blank line.
89
+ expect(help.stdout.trimEnd()).toBe(bare.stdout.trimEnd());
90
+ }, 60_000);
91
+
92
+ it("a bare namespace mirrors summon: Commander help on stderr, exit 1", () => {
93
+ const { status, stdout, stderr } = run(["create", "component"]);
94
+ expect(status).toBe(1);
95
+ expect(stdout).toBe("");
96
+ expect(stderr).toContain("Usage:");
97
+ expect(stderr).toContain("react");
98
+ expect(stderr).toContain("svelte");
99
+ expect(stderr).toContain("lit");
100
+ }, 60_000);
101
+
102
+ it("R1: the old --framework grammar dies loudly, naming the new form", () => {
103
+ // The FACTS repro, verbatim.
104
+ const { status, stderr, cwd } = run([
105
+ "create",
106
+ "component",
107
+ "src/components/X",
108
+ "--framework",
109
+ "react",
110
+ ]);
111
+ expect(status).toBe(2);
112
+ expect(stderr).toContain(
113
+ "error: unknown option '--framework' — the framework is now a path segment: " +
114
+ "`pragma create component <react|svelte|lit> [component-path]` (create mirrors summon).",
115
+ );
116
+ expect(readdirSync(cwd)).toEqual([]);
117
+ }, 60_000);
118
+
119
+ it("R1 stays scoped: `create package --framework` gets the real unknown-option error", () => {
120
+ // Only `create component` ever had the flag; the other bindings must
121
+ // keep Commander's honest unknown-option error instead of a migration
122
+ // message about a grammar they never spoke.
123
+ const { status, stderr } = run([
124
+ "create",
125
+ "package",
126
+ "--framework",
127
+ "react",
128
+ ]);
129
+ expect(status).toBe(2);
130
+ expect(stderr).toContain("unknown option '--framework'");
131
+ expect(stderr).not.toContain("the framework is now a path segment");
132
+ }, 60_000);
133
+
134
+ it("R1 stops at the terminator: `--framework` after `--` is an operand, not the retired flag", () => {
135
+ // The retired-grammar scan must read only the pre-`--` span: here the
136
+ // parse failure is the unknown option BEFORE the terminator, and the
137
+ // `--framework` after it is user data — the honest error must stand
138
+ // instead of a migration message about a flag that was never passed.
139
+ const { status, stderr } = run([
140
+ "create",
141
+ "component",
142
+ "react",
143
+ "--bogus",
144
+ "--",
145
+ "--framework",
146
+ ]);
147
+ expect(status).toBe(2);
148
+ expect(stderr).toContain("unknown option '--bogus'");
149
+ expect(stderr).not.toContain("the framework is now a path segment");
150
+ }, 60_000);
151
+
152
+ it("an excess positional errors with the designed message, exit 2", () => {
153
+ const { status, stderr, cwd } = run([
154
+ "create",
155
+ "component",
156
+ "react",
157
+ "MyComponent",
158
+ "Extra",
159
+ "--yes",
160
+ ]);
161
+ expect(status).toBe(2);
162
+ expect(stderr).toContain('error: unexpected argument "Extra"');
163
+ expect(readdirSync(cwd)).toEqual([]);
164
+ }, 60_000);
165
+
166
+ it("a sibling segment among the operands earns a did-you-mean", () => {
167
+ const { status, stderr } = run([
168
+ "create",
169
+ "component",
170
+ "react",
171
+ "svelte",
172
+ "X",
173
+ ]);
174
+ expect(status).toBe(2);
175
+ expect(stderr).toContain('error: unexpected argument "X"');
176
+ expect(stderr).toContain("Did you mean 'pragma create component svelte'?");
177
+ }, 60_000);
178
+
179
+ it("an unknown segment beneath a namespace names itself, exit 2", () => {
180
+ const { status, stderr } = run(["create", "component", "vue"]);
181
+ expect(status).toBe(2);
182
+ expect(stderr).toContain("error: unknown command 'vue'");
183
+ }, 60_000);
184
+
185
+ // The projection's two usage errors were the LAST create failure class
186
+ // still writing raw prose under an explicit machine format (round-1 M5
187
+ // closed the refusal; unknown option/verb already enveloped). The host
188
+ // writer reframes them under writeRefusal's exact condition — explicit
189
+ // `--format json`/`--format llm` only — with bin.ts's code taxonomy:
190
+ // unknown command → UNKNOWN_VERB, excess/usage → INVALID_INPUT — and a
191
+ // single prefix-stripped `message` line. The match serializes PER KIND:
192
+ // an unknown segment is a FUZZY match, so its bare candidate rides in
193
+ // `suggestions` (substitutable for the token the message names —
194
+ // ErrorPayload.suggestions' convention, matching bin.ts's UNKNOWN_VERB
195
+ // tier); an excess positional's match is NOT substitutable (it may BE
196
+ // the stray its own message calls unexpected), so that kind omits
197
+ // `suggestions` and carries the runnable correction as `recovery.cli` —
198
+ // the same command the DEFAULT prose did-you-mean line names.
199
+ it("the unknown-segment error envelopes under --format json — UNKNOWN_VERB with the bare segment in `suggestions`", () => {
200
+ const { status, stderr, cwd } = run([
201
+ "create",
202
+ "component",
203
+ "reakt",
204
+ "--format",
205
+ "json",
206
+ ]);
207
+ expect(status).toBe(2);
208
+ const line = stderr
209
+ .split("\n")
210
+ .find((candidate) => candidate.startsWith("{"));
211
+ expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
212
+ const envelope = JSON.parse(line as string) as {
213
+ ok: boolean;
214
+ error: { code: string; message: string; suggestions?: string[] };
215
+ };
216
+ expect(envelope.ok).toBe(false);
217
+ expect(envelope.error.code).toBe("UNKNOWN_VERB");
218
+ // SINGLE line — an agent rendering `message` never meets an embedded
219
+ // newline, and the structured match sits where every other pragma
220
+ // fuzzy-match error puts it, in the field's convention: the bare
221
+ // candidate token, exactly as `pragma blok --format json` serializes.
222
+ expect(envelope.error.message).toBe("unknown command 'reakt'");
223
+ expect(envelope.error.suggestions).toEqual(["react"]);
224
+ expect(readdirSync(cwd)).toEqual([]);
225
+ }, 60_000);
226
+
227
+ it("the excess-positional error envelopes under --format json — INVALID_INPUT, recovery.cli carrying the correction", () => {
228
+ /** Parse the one JSON line an envelope-writing spawn leaves on stderr. */
229
+ const envelopeOf = (stderr: string) => {
230
+ const line = stderr
231
+ .split("\n")
232
+ .find((candidate) => candidate.startsWith("{"));
233
+ expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
234
+ return JSON.parse(line as string) as {
235
+ ok: boolean;
236
+ error: {
237
+ code: string;
238
+ message: string;
239
+ suggestions?: string[];
240
+ recovery?: { message: string; cli?: string };
241
+ };
242
+ };
243
+ };
244
+
245
+ const { status, stderr, cwd } = run([
246
+ "create",
247
+ "component",
248
+ "react",
249
+ "MyComponent",
250
+ "Extra",
251
+ "--format",
252
+ "json",
253
+ ]);
254
+ expect(status).toBe(2);
255
+ const envelope = envelopeOf(stderr);
256
+ expect(envelope.ok).toBe(false);
257
+ expect(envelope.error.code).toBe("INVALID_INPUT");
258
+ expect(envelope.error.message).toBe('unexpected argument "Extra"');
259
+ // No operand matched a segment: nothing runnable exists, so BOTH
260
+ // optional fields are OMITTED — exactly as serializeError drops every
261
+ // empty optional.
262
+ expect(envelope.error.suggestions).toBeUndefined();
263
+ expect(envelope.error.recovery).toBeUndefined();
264
+ expect(readdirSync(cwd)).toEqual([]);
265
+
266
+ // WITH a match the correction is STRUCTURAL, never a substitution: in
267
+ // `react MyThing svelte` the matched operand (`svelte`) IS the token
268
+ // the message calls unexpected — a `suggestions` entry here told an
269
+ // agent to substitute `svelte` for `svelte` and retry the same argv
270
+ // (round-11 F2, found by four reviewers). The kind omits `suggestions`
271
+ // and carries the runnable command in the covenant's `recovery.cli` —
272
+ // byte-for-byte the command the default prose did-you-mean names.
273
+ const matched = run([
274
+ "create",
275
+ "component",
276
+ "react",
277
+ "MyThing",
278
+ "svelte",
279
+ "--format",
280
+ "json",
281
+ ]);
282
+ expect(matched.status).toBe(2);
283
+ const matchedEnvelope = envelopeOf(matched.stderr);
284
+ expect(matchedEnvelope.error.code).toBe("INVALID_INPUT");
285
+ expect(matchedEnvelope.error.message).toBe('unexpected argument "svelte"');
286
+ expect(matchedEnvelope.error.suggestions).toBeUndefined();
287
+ // D5's third route, pinned as the INVARIANT and not only the output:
288
+ // this cli is COMPUTED at the mount (chain[0] = the root program's
289
+ // name), bypassing cliRecovery and invisible to copy.test.ts's
290
+ // quoted-literal position rule — so the expectation is COMPOSED from
291
+ // the same constant the derivation must land on. A `startsWith` check
292
+ // behind an exact literal could never fail (the literal throws first
293
+ // on every divergence); composing the ONE expectation makes a
294
+ // root-program rename redden this cell naming RECOVERY_CLI_PREFIX,
295
+ // not a stale-looking literal a maintainer would just update.
296
+ expect(matchedEnvelope.error.recovery).toEqual({
297
+ message: "Run the corrected invocation.",
298
+ cli: `${RECOVERY_CLI_PREFIX}create component svelte`,
299
+ });
300
+
301
+ // The stray≠suggestion shape — `react svelte X` binds `svelte` as the
302
+ // positional and overflows `X` — carries the SAME correction while its
303
+ // message names an operand the correction never mentions: the shape
304
+ // that made a bare `suggestions` token unactionable.
305
+ const crossed = run([
306
+ "create",
307
+ "component",
308
+ "react",
309
+ "svelte",
310
+ "X",
311
+ "--format",
312
+ "json",
313
+ ]);
314
+ expect(crossed.status).toBe(2);
315
+ const crossedEnvelope = envelopeOf(crossed.stderr);
316
+ expect(crossedEnvelope.error.code).toBe("INVALID_INPUT");
317
+ expect(crossedEnvelope.error.message).toBe('unexpected argument "X"');
318
+ expect(crossedEnvelope.error.suggestions).toBeUndefined();
319
+ expect(crossedEnvelope.error.recovery).toEqual({
320
+ message: "Run the corrected invocation.",
321
+ cli: `${RECOVERY_CLI_PREFIX}create component svelte`,
322
+ });
323
+ }, 60_000);
324
+
325
+ it("the excess-positional recovery renders under --format llm through the renderer's own Recovery row", () => {
326
+ const { status, stderr } = run([
327
+ "create",
328
+ "component",
329
+ "react",
330
+ "MyThing",
331
+ "svelte",
332
+ "--format",
333
+ "llm",
334
+ ]);
335
+ expect(status).toBe(2);
336
+ expect(stderr).toContain("## Error: INVALID_INPUT");
337
+ expect(stderr).toContain('unexpected argument "svelte"');
338
+ // renderErrorLlm's existing recovery framing — no Suggestions row for
339
+ // this kind, and no bespoke framing invented for it.
340
+ expect(stderr).toContain(
341
+ "Recovery: Run the corrected invocation. `pragma create component svelte`",
342
+ );
343
+ expect(stderr).not.toContain("Suggestions:");
344
+ expect(stderr).not.toContain("Did you mean");
345
+ }, 60_000);
346
+
347
+ it("a NAMESPACE match ships no recovery — `package`'s only siblings cannot scaffold, so the covenant's run-to-recover field never names one", () => {
348
+ // The one declared leaf whose siblings are namespaces: from `package`,
349
+ // a matched operand can only be `component`/`application` — and a bare
350
+ // namespace exits 1 with a help page in every format (§2), so a
351
+ // recovery.cli naming it told an agent to "run" a command that cannot
352
+ // scaffold (pre-gate this envelope carried
353
+ // cli: "pragma create component"; measured red before the fix). The
354
+ // mount's runnability gate (CREATE_SURFACE lookup) drops the recovery;
355
+ // like the no-match arm, the envelope then carries NEITHER optional
356
+ // field.
357
+ const { status, stderr, cwd } = run([
358
+ "create",
359
+ "package",
360
+ "component",
361
+ "--format",
362
+ "json",
363
+ ]);
364
+ expect(status).toBe(2);
365
+ const line = stderr
366
+ .split("\n")
367
+ .find((candidate) => candidate.startsWith("{"));
368
+ expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
369
+ const envelope = JSON.parse(line as string) as {
370
+ ok: boolean;
371
+ error: {
372
+ code: string;
373
+ message: string;
374
+ suggestions?: string[];
375
+ recovery?: unknown;
376
+ };
377
+ };
378
+ expect(envelope.ok).toBe(false);
379
+ expect(envelope.error.code).toBe("INVALID_INPUT");
380
+ expect(envelope.error.message).toBe('unexpected argument "component"');
381
+ expect(envelope.error.suggestions).toBeUndefined();
382
+ expect(envelope.error.recovery).toBeUndefined();
383
+ expect(readdirSync(cwd)).toEqual([]);
384
+
385
+ // The DEFAULT prose keeps the navigation hint unchanged: an
386
+ // interrogative did-you-mean pointing at the namespace is fine — the
387
+ // delta was only ever the machine-format imperative.
388
+ const prose = run(["create", "package", "component"]);
389
+ expect(prose.status).toBe(2);
390
+ expect(prose.stderr).toContain('error: unexpected argument "component"');
391
+ expect(prose.stderr).toContain("Did you mean 'pragma create component'?");
392
+ expect(readdirSync(prose.cwd)).toEqual([]);
393
+ }, 60_000);
394
+
395
+ it("bin-tier usage errors envelope under --format llm too — the unknown option and the --framework migration error", () => {
396
+ // Before the hoist the machine-format decision existed as four copies
397
+ // under TWO gates: bin.ts's two sites enveloped on json ONLY, so under
398
+ // --format llm an excess positional enveloped while an unknown option
399
+ // and the --framework migration error stayed raw prose — one taxonomy
400
+ // class, split. All five usage-error sites (these two, the
401
+ // unknown-command arm, and the projection writer's two classes) now
402
+ // share renderErrorForFormat; the unknown-command member is pinned by
403
+ // its own cells below.
404
+ const bogus = run(["create", "package", "--bogus", "--format", "llm"]);
405
+ expect(bogus.status).toBe(2);
406
+ expect(bogus.stderr).toContain("## Error: INVALID_INPUT");
407
+ expect(bogus.stderr).toContain("unknown option '--bogus'");
408
+
409
+ const framework = run([
410
+ "create",
411
+ "component",
412
+ "src/components/X",
413
+ "--framework",
414
+ "react",
415
+ "--format",
416
+ "llm",
417
+ ]);
418
+ expect(framework.status).toBe(2);
419
+ expect(framework.stderr).toContain("## Error: INVALID_INPUT");
420
+ expect(framework.stderr).toContain("the framework is now a path segment");
421
+ }, 60_000);
422
+
423
+ it("the unknown-segment error under --format llm carries the condensed framing with a Suggestions line", () => {
424
+ const { status, stderr } = run([
425
+ "create",
426
+ "component",
427
+ "reakt",
428
+ "--format",
429
+ "llm",
430
+ ]);
431
+ expect(status).toBe(2);
432
+ expect(stderr).toContain("## Error: UNKNOWN_VERB");
433
+ expect(stderr).toContain("unknown command 'reakt'");
434
+ // The renderer's own Suggestions row — not a third prose line — with
435
+ // the bare candidate segment, the field's one convention.
436
+ expect(stderr).toContain("Suggestions: react");
437
+ expect(stderr).not.toContain("Did you mean");
438
+ }, 60_000);
439
+
440
+ it("the bin-tier unknown command envelopes under --format llm — UNKNOWN_VERB with bare-token suggestions", () => {
441
+ // The unknown-command arm was the last handleProgramError site off
442
+ // renderErrorForFormat: under an explicit --format llm a typo'd verb
443
+ // (`pragma blok`) rendered the plain prose while its create-tier
444
+ // sibling (`create component reakt`) enveloped — one code, two gates.
445
+ const { status, stderr } = run(["blok", "--format", "llm"]);
446
+ expect(status).toBe(2);
447
+ expect(stderr).toContain("## Error: UNKNOWN_VERB");
448
+ expect(stderr).toContain('Unknown command "blok".');
449
+ expect(stderr).toContain("Suggestions: block");
450
+ expect(stderr).not.toContain("Did you mean");
451
+ }, 60_000);
452
+
453
+ it("the bin-tier unknown command envelopes under --format json — bare-token suggestions, byte-stable", () => {
454
+ const { status, stderr } = run(["blok", "--format", "json"]);
455
+ expect(status).toBe(2);
456
+ const line = stderr
457
+ .split("\n")
458
+ .find((candidate) => candidate.startsWith("{"));
459
+ expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
460
+ const envelope = JSON.parse(line as string) as {
461
+ ok: boolean;
462
+ error: { code: string; message: string; suggestions?: string[] };
463
+ };
464
+ expect(envelope.ok).toBe(false);
465
+ expect(envelope.error.code).toBe("UNKNOWN_VERB");
466
+ expect(envelope.error.message).toBe('Unknown command "blok".');
467
+ // The bare candidate token — the same convention the create tier's
468
+ // envelope carries, so one code has one `suggestions` shape.
469
+ expect(envelope.error.suggestions).toEqual(["block"]);
470
+ }, 60_000);
471
+
472
+ it("DEFAULT piped output for both projection usage errors stays the raw prose — full stderr, no envelope", () => {
473
+ // Full-stderr byte-equality needs a quiet stream: seed the global config
474
+ // so the one-time first-run note (stderr by design) does not fire.
475
+ const configHome = mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-"));
476
+ mkdirSync(join(configHome, "pragma"));
477
+ writeFileSync(join(configHome, "pragma", "config.json"), "{}\n");
478
+ const spawn = (args: readonly string[]) =>
479
+ spawnSync("bun", [pragmaBin, ...args], {
480
+ cwd: freshCwd(),
481
+ encoding: "utf-8",
482
+ input: "",
483
+ env: {
484
+ ...process.env,
485
+ XDG_CONFIG_HOME: configHome,
486
+ XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
487
+ XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
488
+ },
489
+ });
490
+ const segment = spawn(["create", "component", "reakt"]);
491
+ expect(segment.status).toBe(2);
492
+ expect(segment.stderr).toBe(
493
+ "error: unknown command 'reakt'\n" +
494
+ "Did you mean 'pragma create component react'?\n",
495
+ );
496
+ const excess = spawn(["create", "component", "react", "MyComponent", "X"]);
497
+ expect(excess.status).toBe(2);
498
+ expect(excess.stderr).toBe('error: unexpected argument "X"\n');
499
+ }, 60_000);
500
+
501
+ it("`-v` is an unknown option in the subtree — exit 2, nothing written (§2)", () => {
502
+ // summon's `-v` is `--verbose` (its run proceeds); pragma has no short
503
+ // flags at all — one spelling per flag — so the token reaches the
504
+ // subtree and fails as an ordinary unknown option instead of silently
505
+ // meaning something else. This cell keeps the divergence deliberate,
506
+ // not accidental (the host flag surface is bin.ts's — out of CIS scope;
507
+ // the covenant freezes neither token).
508
+ const { status, stdout, stderr, cwd } = run([
509
+ "create",
510
+ "component",
511
+ "react",
512
+ "src/components/X",
513
+ "-v",
514
+ "--yes",
515
+ ]);
516
+ expect(status).toBe(2);
517
+ expect(stdout).toBe("");
518
+ expect(stderr).toContain("error: unknown option '-v'");
519
+ expect(readdirSync(cwd)).toEqual([]);
520
+ }, 60_000);
521
+
522
+ it("the confirm convention is summon's: --no-with-styles is accepted, --with-styles is not", () => {
523
+ const accepted = run([
524
+ "create",
525
+ "component",
526
+ "react",
527
+ "src/components/W",
528
+ "--no-with-styles",
529
+ "--dry-run",
530
+ ]);
531
+ expect(accepted.status).toBe(0);
532
+ expect(accepted.stdout).toContain("Dry-run complete.");
533
+ expect(readdirSync(accepted.cwd)).toEqual([]);
534
+
535
+ const rejected = run([
536
+ "create",
537
+ "component",
538
+ "react",
539
+ "src/components/W",
540
+ "--with-styles",
541
+ "--dry-run",
542
+ ]);
543
+ expect(rejected.status).toBe(2);
544
+ expect(rejected.stderr).toContain("--with-styles");
545
+ }, 60_000);
546
+
547
+ it("row 6 on the wire: a bare non-TTY leaf refuses with the shared message, exit 2", () => {
548
+ const { status, stderr, cwd } = run(["create", "component", "react"]);
549
+ expect(status).toBe(2);
550
+ expect(stderr).toContain(
551
+ "Refusing to scaffold in a non-interactive run without complete input. " +
552
+ "Pass --yes to accept defaults, --dry-run to preview, or provide every answer as a flag. " +
553
+ "Missing: --component-path, --no-with-styles, --no-with-stories, --no-with-ssr-tests.",
554
+ );
555
+ expect(readdirSync(cwd)).toEqual([]);
556
+ }, 60_000);
557
+
558
+ it("the refusal envelopes under --format json (D3) — never raw prose on a machine stream", () => {
559
+ const { status, stderr, cwd } = run([
560
+ "create",
561
+ "component",
562
+ "react",
563
+ "--format",
564
+ "json",
565
+ ]);
566
+ expect(status).toBe(2);
567
+ // The one JSON line is the same {ok:false, error} envelope every other
568
+ // pragma error emits; the shared refusal text rides inside it.
569
+ const line = stderr
570
+ .split("\n")
571
+ .find((candidate) => candidate.startsWith("{"));
572
+ expect(line, `no JSON envelope on stderr:\n${stderr}`).toBeDefined();
573
+ const envelope = JSON.parse(line as string) as {
574
+ ok: boolean;
575
+ error: { code: string; message: string };
576
+ };
577
+ expect(envelope.ok).toBe(false);
578
+ expect(envelope.error.code).toBe("INVALID_INPUT");
579
+ expect(envelope.error.message).toContain(
580
+ "Refusing to scaffold in a non-interactive run without complete input.",
581
+ );
582
+ expect(envelope.error.message).toContain("Missing: --component-path");
583
+ expect(readdirSync(cwd)).toEqual([]);
584
+ }, 60_000);
585
+
586
+ it("the refusal envelopes under an explicit --format llm — the condensed D3 error form", () => {
587
+ const { status, stderr, cwd } = run([
588
+ "create",
589
+ "component",
590
+ "react",
591
+ "--format",
592
+ "llm",
593
+ ]);
594
+ expect(status).toBe(2);
595
+ // The same `## Error: <code>` framing every other pragma error carries in
596
+ // llm form, with the shared refusal line riding beneath it.
597
+ expect(stderr).toContain("## Error: INVALID_INPUT");
598
+ expect(stderr).toContain(
599
+ "Refusing to scaffold in a non-interactive run without complete input.",
600
+ );
601
+ expect(readdirSync(cwd)).toEqual([]);
602
+ }, 60_000);
603
+
604
+ it("a DEFAULT piped refusal is the bare shared line — no envelope; auto-LLM never reframes it", () => {
605
+ // Full-stderr byte-equality needs a quiet stream: seed the global config
606
+ // so the one-time first-run note (stderr by design) does not fire.
607
+ const configHome = mkdtempSync(join(tmpdir(), "pragma-grammar-cfg-"));
608
+ mkdirSync(join(configHome, "pragma"));
609
+ writeFileSync(join(configHome, "pragma", "config.json"), "{}\n");
610
+ const cwd = freshCwd();
611
+ const result = spawnSync(
612
+ "bun",
613
+ [pragmaBin, "create", "component", "react"],
614
+ {
615
+ cwd,
616
+ encoding: "utf-8",
617
+ input: "",
618
+ env: {
619
+ ...process.env,
620
+ XDG_CONFIG_HOME: configHome,
621
+ XDG_STATE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-state-")),
622
+ XDG_CACHE_HOME: mkdtempSync(join(tmpdir(), "pragma-grammar-cache-")),
623
+ },
624
+ },
625
+ );
626
+ expect(result.status).toBe(2);
627
+ // Byte-equality of the WHOLE stream with the shared message (contract §3):
628
+ // the parity surface summon writes verbatim, with no framing line above it.
629
+ expect(result.stderr).toBe(
630
+ "Refusing to scaffold in a non-interactive run without complete input. " +
631
+ "Pass --yes to accept defaults, --dry-run to preview, or provide every answer as a flag. " +
632
+ "Missing: --component-path, --no-with-styles, --no-with-stories, --no-with-ssr-tests.\n",
633
+ );
634
+ expect(readdirSync(cwd)).toEqual([]);
635
+ }, 60_000);
636
+
637
+ // The refusal's own instruction WORKS — on EVERY declared leaf. Take the
638
+ // message's advice VERBATIM: extract the tokens the bare refusal prints,
639
+ // supply each back (a valid value where the registered form takes one, the
640
+ // `--no-` confirms bare), add --dry-run, and the same leaf must preview
641
+ // cleanly and write nothing. Round 14 proved the tokens PARSE; this closes
642
+ // the round trip: a leaf may not advertise a completion its own generator
643
+ // then rejects — `application/react` did exactly that (its Missing list
644
+ // named `--no-ssr, --no-router` and its guard refused precisely those two,
645
+ // a two-state loop with no all-flags exit) until the dead prompt pair was
646
+ // removed. Pre-round-14 the list kebab-cased prompt NAMES (`--with-styles`
647
+ // and friends, which no host registers), so the round-trip was `error:
648
+ // unknown option` — this cell reddens on either regression.
649
+ const REPLY_VALUES: Record<string, Record<string, string>> = {
650
+ "component/react": { "--component-path": "src/components/Replied" },
651
+ "component/svelte": { "--component-path": "src/lib/Replied" },
652
+ "component/lit": { "--component-path": "src/lib/Replied" },
653
+ package: {
654
+ "--name": "@canonical/replied-lib",
655
+ "--type": "library",
656
+ "--description": "A replied library.",
657
+ },
658
+ "application/react": { "--app-path": "replied-app" },
659
+ };
660
+ for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
661
+ it(`${commandPath}: the refusal's own instruction WORKS — its Missing tokens supplied back (+ --dry-run) preview, exit 0`, () => {
662
+ const path = commandPath.split("/");
663
+ const refusal = run(["create", ...path]);
664
+ expect(refusal.status).toBe(2);
665
+ const missing = /Missing: ([^\n]*)\./.exec(refusal.stderr);
666
+ expect(missing, `no Missing list in:\n${refusal.stderr}`).not.toBeNull();
667
+ const tokens = (missing as RegExpExecArray)[1]?.split(", ") ?? [];
668
+ // The live list IS the derivation — parsed off the wire, tied to the
669
+ // same authority the mount registers from (non-empty by declaration).
670
+ expect(tokens).toEqual(missingExplicitFlags(surface.prompts, {}));
671
+ expect(tokens.length).toBeGreaterThan(0);
672
+ // A token whose registered form takes a value gets a valid one from
673
+ // the table above — fail loudly on a leaf the table does not know.
674
+ const takesValue = new Map(
675
+ surface.prompts.map((prompt) => {
676
+ const info = buildOptionInfo(prompt);
677
+ return [info.flags.split(" ")[0], info.flags.includes(" ")] as const;
678
+ }),
679
+ );
680
+ const supplied = tokens.flatMap((token) => {
681
+ if (!takesValue.get(token)) return [token];
682
+ const value = REPLY_VALUES[commandPath]?.[token];
683
+ if (value === undefined) {
684
+ throw new Error(`no reply value for ${token} on ${commandPath}`);
685
+ }
686
+ return [token, value];
687
+ });
688
+ const replied = run(["create", ...path, ...supplied, "--dry-run"]);
689
+ expect(replied.stderr).not.toContain("unknown option");
690
+ expect(replied.status, replied.stderr).toBe(0);
691
+ expect(replied.stdout).toContain("Dry-run complete.");
692
+ expect(readdirSync(replied.cwd)).toEqual([]);
693
+ }, 60_000);
694
+ }
695
+ // The react list stays pinned at its exact bytes (the round-14 literal):
696
+ // the loop above ties every leaf to the derivation; this cell keeps one
697
+ // wire literal a derivation bug cannot move silently.
698
+ it("component/react's Missing list is the exact four registered tokens", () => {
699
+ const refusal = run(["create", "component", "react"]);
700
+ const missing = /Missing: ([^\n]*)\./.exec(refusal.stderr);
701
+ expect((missing as RegExpExecArray)[1]?.split(", ")).toEqual([
702
+ "--component-path",
703
+ "--no-with-styles",
704
+ "--no-with-stories",
705
+ "--no-with-ssr-tests",
706
+ ]);
707
+ }, 60_000);
708
+
709
+ it("row 5 on the wire: a fully-explicit non-TTY leaf runs without --yes", () => {
710
+ const { status, cwd } = run([
711
+ "create",
712
+ "component",
713
+ "react",
714
+ "src/components/Widget",
715
+ "--no-with-styles",
716
+ "--no-with-stories",
717
+ "--no-with-ssr-tests",
718
+ ]);
719
+ expect(status).toBe(0);
720
+ expect(readdirSync(join(cwd, "src/components/Widget"))).toContain(
721
+ "Widget.tsx",
722
+ );
723
+ }, 60_000);
724
+
725
+ it("the invalid-value cell echoes the offending value, exit 2", () => {
726
+ const { status, stderr, cwd } = run([
727
+ "create",
728
+ "component",
729
+ "react",
730
+ "not-pascal",
731
+ "--yes",
732
+ ]);
733
+ expect(status).toBe(2);
734
+ expect(stderr).toContain(
735
+ 'Invalid --component-path "not-pascal": ' +
736
+ "Component name must be in PascalCase",
737
+ );
738
+ expect(readdirSync(cwd)).toEqual([]);
739
+ }, 60_000);
740
+ });
741
+
742
+ describe("the refusal cell through dispatchPrepared (in-process)", () => {
743
+ afterEach(() => {
744
+ process.exitCode = 0;
745
+ vi.restoreAllMocks();
746
+ });
747
+
748
+ it("runCreate re-derives refuse and the kernel renders it, exit 2", async () => {
749
+ const { dispatchPrepared } = await import(
750
+ "../../kernel/project/cli/dispatch.js"
751
+ );
752
+ const stderr = vi
753
+ .spyOn(process.stderr, "write")
754
+ .mockImplementation(() => true);
755
+ await dispatchPrepared(
756
+ leafVerb("component/react"),
757
+ {},
758
+ { dryRun: false, undo: false, yes: false },
759
+ FLAGS,
760
+ );
761
+ const written = stderr.mock.calls.map((call) => String(call[0])).join("");
762
+ expect(written).toContain("Refusing to scaffold in a non-interactive run");
763
+ expect(written).toContain("Missing: --component-path");
764
+ expect(process.exitCode).toBe(2);
765
+ }, 60_000);
766
+ });
767
+
768
+ describe("the mount's mode resolution — TTY driven through the seam", () => {
769
+ // No suite can hand a subprocess a real TTY, so the §L rows that depend on
770
+ // isTTY: true are pinned HERE, through the exported resolver the action
771
+ // itself calls (with canPrompt()). The OLD decision block routed TTY
772
+ // dry-run/undo into Ink; these rows keep that from silently returning.
773
+ const prompts = CREATE_SURFACE["component/react"]?.prompts ?? [];
774
+ const flags = (dryRun: boolean, undo: boolean, yes: boolean) => ({
775
+ dryRun,
776
+ undo,
777
+ yes,
778
+ });
779
+
780
+ it("TTY --dry-run resolves batch-dry-run — never an interactive preview", () => {
781
+ expect(
782
+ resolveCreateMode(prompts, {}, flags(true, false, false), true),
783
+ ).toBe("batch-dry-run");
784
+ });
785
+
786
+ it("TTY --undo resolves batch-undo — never a prompting wizard", () => {
787
+ expect(
788
+ resolveCreateMode(prompts, {}, flags(false, true, false), true),
789
+ ).toBe("batch-undo");
790
+ });
791
+
792
+ it("TTY --dry-run outranks --undo (the shared precedence)", () => {
793
+ expect(resolveCreateMode(prompts, {}, flags(true, true, false), true)).toBe(
794
+ "batch-dry-run",
795
+ );
796
+ });
797
+
798
+ it("a bare TTY leaf resolves wizard; the same input without a TTY refuses", () => {
799
+ expect(
800
+ resolveCreateMode(prompts, {}, flags(false, false, false), true),
801
+ ).toBe("wizard");
802
+ expect(
803
+ resolveCreateMode(prompts, {}, flags(false, false, false), false),
804
+ ).toBe("refuse");
805
+ });
806
+ });
807
+
808
+ describe("the wizard's seed — explicit answers only", () => {
809
+ const prompts = CREATE_SURFACE["component/react"]?.prompts ?? [];
810
+
811
+ it("extracts ONLY explicit answers (defaults never leak into the seed)", () => {
812
+ // The wizard cell asks pendingPrompts(prompts, explicit); the seed handed
813
+ // to runCreate must therefore be the EXPLICIT set, not defaults.
814
+ expect(
815
+ explicitLeafAnswers(prompts, undefined, {
816
+ withStyles: false,
817
+ dryRun: false,
818
+ }),
819
+ ).toEqual({ withStyles: false });
820
+ // A confirm equal to its default is NOT explicit (Commander reports
821
+ // untouched --no- flags as true).
822
+ expect(
823
+ explicitLeafAnswers(prompts, undefined, { withStyles: true }),
824
+ ).toEqual({});
825
+ });
826
+
827
+ it("the positional lands under its prompt name", () => {
828
+ expect(explicitLeafAnswers(prompts, "src/components/X", {})).toEqual({
829
+ componentPath: "src/components/X",
830
+ });
831
+ });
832
+
833
+ it("the topic tree lists every declared path with its description", () => {
834
+ const tree = topicTree("pragma");
835
+ for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
836
+ for (const segment of commandPath.split("/")) {
837
+ expect(tree).toContain(segment);
838
+ }
839
+ expect(tree).toContain(surface.description);
840
+ }
841
+ });
842
+ });
843
+
844
+ describe("the refusal's Missing tokens are REGISTERED flags — every declared leaf", () => {
845
+ // The round-14 defect: kebab-casing prompt NAMES advertised 13 of the 25
846
+ // tokens across the five leaves under spellings NO host registers (a
847
+ // default-true confirm registers ONLY `--no-<kebab>`), so following the
848
+ // refusal's own instruction exited 2. The pin: for every declared leaf,
849
+ // the bare-invocation Missing list ⊆ the long-flag set the single
850
+ // flag-shape authority yields for that leaf's prompts.
851
+ for (const [commandPath, surface] of Object.entries(CREATE_SURFACE)) {
852
+ it(`${commandPath}: missingExplicitFlags({}) names only buildOptionInfo's registered long forms`, () => {
853
+ const registered = surface.prompts.map(
854
+ (prompt) => buildOptionInfo(prompt).flags.split(" ")[0],
855
+ );
856
+ const missing = missingExplicitFlags(surface.prompts, {});
857
+ // Every declared leaf has at least one unconditional prompt, so an
858
+ // empty list can never green this pin vacuously.
859
+ expect(missing.length).toBeGreaterThan(0);
860
+ for (const token of missing) {
861
+ expect(registered).toContain(token);
862
+ }
863
+ });
864
+ }
865
+ });