@canonical/pragma-cli 0.34.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (798) hide show
  1. package/README.md +153 -30
  2. package/dist/.build-ok +0 -0
  3. package/dist/package.json +83 -0
  4. package/dist/pragma.conf.js +814 -0
  5. package/dist/pragma.conf.js.map +1 -0
  6. package/dist/src/bin.js +356 -0
  7. package/dist/src/bin.js.map +1 -0
  8. package/dist/src/capabilities/capabilities/capabilities.render.js +70 -0
  9. package/dist/src/capabilities/capabilities/capabilities.render.js.map +1 -0
  10. package/dist/src/capabilities/capabilities/capabilities.verb.js +59 -0
  11. package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -0
  12. package/dist/src/capabilities/capabilities/catalog.js +130 -0
  13. package/dist/src/capabilities/capabilities/catalog.js.map +1 -0
  14. package/dist/src/capabilities/capabilities/hints.js +195 -0
  15. package/dist/src/capabilities/capabilities/hints.js.map +1 -0
  16. package/dist/src/capabilities/capabilities/index.js +11 -0
  17. package/dist/src/capabilities/capabilities/index.js.map +1 -0
  18. package/dist/src/capabilities/capabilities/types.js +11 -0
  19. package/dist/src/capabilities/capabilities/types.js.map +1 -0
  20. package/dist/src/capabilities/colophon/collectColophon.js +83 -0
  21. package/dist/src/capabilities/colophon/collectColophon.js.map +1 -0
  22. package/dist/src/capabilities/colophon/colophon.render.js +59 -0
  23. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -0
  24. package/dist/src/capabilities/colophon/colophon.verb.js +43 -0
  25. package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -0
  26. package/dist/src/capabilities/colophon/index.js +5 -0
  27. package/dist/src/capabilities/colophon/index.js.map +1 -0
  28. package/dist/src/capabilities/colophon/markdownTerminal.js +90 -0
  29. package/dist/src/capabilities/colophon/markdownTerminal.js.map +1 -0
  30. package/dist/src/capabilities/colophon/types.js +10 -0
  31. package/dist/src/capabilities/colophon/types.js.map +1 -0
  32. package/dist/src/capabilities/config/collectConfigShow.js +59 -0
  33. package/dist/src/capabilities/config/collectConfigShow.js.map +1 -0
  34. package/dist/src/capabilities/config/field.render.js +22 -0
  35. package/dist/src/capabilities/config/field.render.js.map +1 -0
  36. package/dist/src/capabilities/config/fields.js +46 -0
  37. package/dist/src/capabilities/config/fields.js.map +1 -0
  38. package/dist/src/capabilities/config/get.verb.js +61 -0
  39. package/dist/src/capabilities/config/get.verb.js.map +1 -0
  40. package/dist/src/capabilities/config/index.js +5 -0
  41. package/dist/src/capabilities/config/index.js.map +1 -0
  42. package/dist/src/capabilities/config/runField.js +59 -0
  43. package/dist/src/capabilities/config/runField.js.map +1 -0
  44. package/dist/src/capabilities/config/runGet.js +28 -0
  45. package/dist/src/capabilities/config/runGet.js.map +1 -0
  46. package/dist/src/capabilities/config/runSet.js +53 -0
  47. package/dist/src/capabilities/config/runSet.js.map +1 -0
  48. package/dist/src/capabilities/config/set.verb.js +66 -0
  49. package/dist/src/capabilities/config/set.verb.js.map +1 -0
  50. package/dist/src/capabilities/config/show.render.js +84 -0
  51. package/dist/src/capabilities/config/show.render.js.map +1 -0
  52. package/dist/src/capabilities/config/show.verb.js +44 -0
  53. package/dist/src/capabilities/config/show.verb.js.map +1 -0
  54. package/dist/src/capabilities/config/types.js +5 -0
  55. package/dist/src/capabilities/config/types.js.map +1 -0
  56. package/dist/src/capabilities/config/unset.verb.js +49 -0
  57. package/dist/src/capabilities/config/unset.verb.js.map +1 -0
  58. package/dist/src/capabilities/create/cliProjection.js +195 -0
  59. package/dist/src/capabilities/create/cliProjection.js.map +1 -0
  60. package/dist/src/capabilities/create/constants.js +47 -0
  61. package/dist/src/capabilities/create/constants.js.map +1 -0
  62. package/dist/src/capabilities/create/create.render.js +100 -0
  63. package/dist/src/capabilities/create/create.render.js.map +1 -0
  64. package/dist/src/capabilities/create/create.verb.js +438 -0
  65. package/dist/src/capabilities/create/create.verb.js.map +1 -0
  66. package/dist/src/capabilities/create/createHelp.js +47 -0
  67. package/dist/src/capabilities/create/createHelp.js.map +1 -0
  68. package/dist/src/capabilities/create/createSurface.generated.js +394 -0
  69. package/dist/src/capabilities/create/createSurface.generated.js.map +1 -0
  70. package/dist/src/capabilities/create/generatorToVerbSpec.js +106 -0
  71. package/dist/src/capabilities/create/generatorToVerbSpec.js.map +1 -0
  72. package/dist/src/capabilities/create/index.js +18 -0
  73. package/dist/src/capabilities/create/index.js.map +1 -0
  74. package/dist/src/capabilities/create/messages.js +16 -0
  75. package/dist/src/capabilities/create/messages.js.map +1 -0
  76. package/dist/src/capabilities/create/mount.js +293 -0
  77. package/dist/src/capabilities/create/mount.js.map +1 -0
  78. package/dist/src/capabilities/create/pathJail.js +65 -0
  79. package/dist/src/capabilities/create/pathJail.js.map +1 -0
  80. package/dist/src/capabilities/create/pickGenerator.js +53 -0
  81. package/dist/src/capabilities/create/pickGenerator.js.map +1 -0
  82. package/dist/src/capabilities/create/types.js +2 -0
  83. package/dist/src/capabilities/create/types.js.map +1 -0
  84. package/dist/src/capabilities/distribution.js +40 -0
  85. package/dist/src/capabilities/distribution.js.map +1 -0
  86. package/dist/src/capabilities/doctor/checks/checkKeStore.js +40 -0
  87. package/dist/src/capabilities/doctor/checks/checkKeStore.js.map +1 -0
  88. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js +21 -0
  89. package/dist/src/capabilities/doctor/checks/checkNodeVersion.js.map +1 -0
  90. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +92 -0
  91. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -0
  92. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js +19 -0
  93. package/dist/src/capabilities/doctor/checks/checkPragmaVersion.js.map +1 -0
  94. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js +199 -0
  95. package/dist/src/capabilities/doctor/checks/checkShellCompletions.js.map +1 -0
  96. package/dist/src/capabilities/doctor/checks/index.js +27 -0
  97. package/dist/src/capabilities/doctor/checks/index.js.map +1 -0
  98. package/dist/src/capabilities/doctor/checks/mcpCommand.js +57 -0
  99. package/dist/src/capabilities/doctor/checks/mcpCommand.js.map +1 -0
  100. package/dist/src/capabilities/doctor/checks/targetHealth.js +205 -0
  101. package/dist/src/capabilities/doctor/checks/targetHealth.js.map +1 -0
  102. package/dist/src/capabilities/doctor/doctor.render.js +185 -0
  103. package/dist/src/capabilities/doctor/doctor.render.js.map +1 -0
  104. package/dist/src/capabilities/doctor/doctor.verb.js +45 -0
  105. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -0
  106. package/dist/src/capabilities/doctor/index.js +5 -0
  107. package/dist/src/capabilities/doctor/index.js.map +1 -0
  108. package/dist/src/capabilities/doctor/runChecks.js +83 -0
  109. package/dist/src/capabilities/doctor/runChecks.js.map +1 -0
  110. package/dist/src/capabilities/doctor/types.js +5 -0
  111. package/dist/src/capabilities/doctor/types.js.map +1 -0
  112. package/dist/src/capabilities/graph/index.js +19 -0
  113. package/dist/src/capabilities/graph/index.js.map +1 -0
  114. package/dist/src/capabilities/graph/inspect.render.js +76 -0
  115. package/dist/src/capabilities/graph/inspect.render.js.map +1 -0
  116. package/dist/src/capabilities/graph/inspect.verb.js +53 -0
  117. package/dist/src/capabilities/graph/inspect.verb.js.map +1 -0
  118. package/dist/src/capabilities/graph/query.render.js +73 -0
  119. package/dist/src/capabilities/graph/query.render.js.map +1 -0
  120. package/dist/src/capabilities/graph/query.verb.js +49 -0
  121. package/dist/src/capabilities/graph/query.verb.js.map +1 -0
  122. package/dist/src/capabilities/graph/runQuery.js +41 -0
  123. package/dist/src/capabilities/graph/runQuery.js.map +1 -0
  124. package/dist/src/capabilities/index.js +56 -0
  125. package/dist/src/capabilities/index.js.map +1 -0
  126. package/dist/src/capabilities/info/collectInfo.js +66 -0
  127. package/dist/src/capabilities/info/collectInfo.js.map +1 -0
  128. package/dist/src/capabilities/info/index.js +5 -0
  129. package/dist/src/capabilities/info/index.js.map +1 -0
  130. package/dist/src/capabilities/info/info.render.js +53 -0
  131. package/dist/src/capabilities/info/info.render.js.map +1 -0
  132. package/dist/src/capabilities/info/info.verb.js +42 -0
  133. package/dist/src/capabilities/info/info.verb.js.map +1 -0
  134. package/dist/src/capabilities/info/types.js +5 -0
  135. package/dist/src/capabilities/info/types.js.map +1 -0
  136. package/dist/src/capabilities/meta/complete.verb.js +43 -0
  137. package/dist/src/capabilities/meta/complete.verb.js.map +1 -0
  138. package/dist/src/capabilities/meta/index.js +13 -0
  139. package/dist/src/capabilities/meta/index.js.map +1 -0
  140. package/dist/src/capabilities/meta/mcp.verb.js +34 -0
  141. package/dist/src/capabilities/meta/mcp.verb.js.map +1 -0
  142. package/dist/src/capabilities/ontology/index.js +21 -0
  143. package/dist/src/capabilities/ontology/index.js.map +1 -0
  144. package/dist/src/capabilities/ontology/queries.js +123 -0
  145. package/dist/src/capabilities/ontology/queries.js.map +1 -0
  146. package/dist/src/capabilities/ontology/render.js +66 -0
  147. package/dist/src/capabilities/ontology/render.js.map +1 -0
  148. package/dist/src/capabilities/ontology/verbs.js +181 -0
  149. package/dist/src/capabilities/ontology/verbs.js.map +1 -0
  150. package/dist/src/capabilities/prompt/index.js +16 -0
  151. package/dist/src/capabilities/prompt/index.js.map +1 -0
  152. package/dist/src/capabilities/prompt/prompt.render.js +78 -0
  153. package/dist/src/capabilities/prompt/prompt.render.js.map +1 -0
  154. package/dist/src/capabilities/prompt/types.js +10 -0
  155. package/dist/src/capabilities/prompt/types.js.map +1 -0
  156. package/dist/src/capabilities/prompt/verbs.js +93 -0
  157. package/dist/src/capabilities/prompt/verbs.js.map +1 -0
  158. package/dist/src/capabilities/resources/index.js +10 -0
  159. package/dist/src/capabilities/resources/index.js.map +1 -0
  160. package/dist/src/capabilities/resources/provider.js +423 -0
  161. package/dist/src/capabilities/resources/provider.js.map +1 -0
  162. package/dist/src/capabilities/setup/buildPlan.js +168 -0
  163. package/dist/src/capabilities/setup/buildPlan.js.map +1 -0
  164. package/dist/src/capabilities/setup/index.js +5 -0
  165. package/dist/src/capabilities/setup/index.js.map +1 -0
  166. package/dist/src/capabilities/setup/mode.js +53 -0
  167. package/dist/src/capabilities/setup/mode.js.map +1 -0
  168. package/dist/src/capabilities/setup/operations/index.js +39 -0
  169. package/dist/src/capabilities/setup/operations/index.js.map +1 -0
  170. package/dist/src/capabilities/setup/operations/setupCompletions.js +160 -0
  171. package/dist/src/capabilities/setup/operations/setupCompletions.js.map +1 -0
  172. package/dist/src/capabilities/setup/operations/setupConfig.js +101 -0
  173. package/dist/src/capabilities/setup/operations/setupConfig.js.map +1 -0
  174. package/dist/src/capabilities/setup/operations/setupGenerator.js +343 -0
  175. package/dist/src/capabilities/setup/operations/setupGenerator.js.map +1 -0
  176. package/dist/src/capabilities/setup/operations/setupLsp.js +277 -0
  177. package/dist/src/capabilities/setup/operations/setupLsp.js.map +1 -0
  178. package/dist/src/capabilities/setup/operations/setupMcp.js +207 -0
  179. package/dist/src/capabilities/setup/operations/setupMcp.js.map +1 -0
  180. package/dist/src/capabilities/setup/operations/setupSkills.js +316 -0
  181. package/dist/src/capabilities/setup/operations/setupSkills.js.map +1 -0
  182. package/dist/src/capabilities/setup/plan.js +128 -0
  183. package/dist/src/capabilities/setup/plan.js.map +1 -0
  184. package/dist/src/capabilities/setup/plan.render.js +193 -0
  185. package/dist/src/capabilities/setup/plan.render.js.map +1 -0
  186. package/dist/src/capabilities/setup/setup.render.js +54 -0
  187. package/dist/src/capabilities/setup/setup.render.js.map +1 -0
  188. package/dist/src/capabilities/setup/setup.verb.js +334 -0
  189. package/dist/src/capabilities/setup/setup.verb.js.map +1 -0
  190. package/dist/src/capabilities/setup/shell.js +196 -0
  191. package/dist/src/capabilities/setup/shell.js.map +1 -0
  192. package/dist/src/capabilities/setup/targets.js +263 -0
  193. package/dist/src/capabilities/setup/targets.js.map +1 -0
  194. package/dist/src/capabilities/setup/types.js +5 -0
  195. package/dist/src/capabilities/setup/types.js.map +1 -0
  196. package/dist/src/capabilities/shared/assertExecOk.js +137 -0
  197. package/dist/src/capabilities/shared/assertExecOk.js.map +1 -0
  198. package/dist/src/capabilities/shared/bands.js +16 -0
  199. package/dist/src/capabilities/shared/bands.js.map +1 -0
  200. package/dist/src/capabilities/shared/index.js +26 -0
  201. package/dist/src/capabilities/shared/index.js.map +1 -0
  202. package/dist/src/capabilities/shared/packageManager.js +103 -0
  203. package/dist/src/capabilities/shared/packageManager.js.map +1 -0
  204. package/dist/src/capabilities/shared/registry.js +55 -0
  205. package/dist/src/capabilities/shared/registry.js.map +1 -0
  206. package/dist/src/capabilities/skill/discover.js +195 -0
  207. package/dist/src/capabilities/skill/discover.js.map +1 -0
  208. package/dist/src/capabilities/skill/index.js +10 -0
  209. package/dist/src/capabilities/skill/index.js.map +1 -0
  210. package/dist/src/capabilities/skill/render.js +49 -0
  211. package/dist/src/capabilities/skill/render.js.map +1 -0
  212. package/dist/src/capabilities/skill/verbs.js +83 -0
  213. package/dist/src/capabilities/skill/verbs.js.map +1 -0
  214. package/dist/src/capabilities/sources/collectStatus.js +103 -0
  215. package/dist/src/capabilities/sources/collectStatus.js.map +1 -0
  216. package/dist/src/capabilities/sources/index.js +13 -0
  217. package/dist/src/capabilities/sources/index.js.map +1 -0
  218. package/dist/src/capabilities/sources/installSkills.js +167 -0
  219. package/dist/src/capabilities/sources/installSkills.js.map +1 -0
  220. package/dist/src/capabilities/sources/runUpdate.js +394 -0
  221. package/dist/src/capabilities/sources/runUpdate.js.map +1 -0
  222. package/dist/src/capabilities/sources/status.render.js +64 -0
  223. package/dist/src/capabilities/sources/status.render.js.map +1 -0
  224. package/dist/src/capabilities/sources/status.verb.js +40 -0
  225. package/dist/src/capabilities/sources/status.verb.js.map +1 -0
  226. package/dist/src/capabilities/sources/types.js +6 -0
  227. package/dist/src/capabilities/sources/types.js.map +1 -0
  228. package/dist/src/capabilities/sources/update.render.js +34 -0
  229. package/dist/src/capabilities/sources/update.render.js.map +1 -0
  230. package/dist/src/capabilities/sources/update.verb.js +55 -0
  231. package/dist/src/capabilities/sources/update.verb.js.map +1 -0
  232. package/dist/src/capabilities/upgrade/index.js +5 -0
  233. package/dist/src/capabilities/upgrade/index.js.map +1 -0
  234. package/dist/src/capabilities/upgrade/runUpgrade.js +99 -0
  235. package/dist/src/capabilities/upgrade/runUpgrade.js.map +1 -0
  236. package/dist/src/capabilities/upgrade/types.js +5 -0
  237. package/dist/src/capabilities/upgrade/types.js.map +1 -0
  238. package/dist/src/capabilities/upgrade/upgrade.render.js +44 -0
  239. package/dist/src/capabilities/upgrade/upgrade.render.js.map +1 -0
  240. package/dist/src/capabilities/upgrade/upgrade.verb.js +52 -0
  241. package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -0
  242. package/dist/src/capabilities/version/index.js +10 -0
  243. package/dist/src/capabilities/version/index.js.map +1 -0
  244. package/dist/src/capabilities/version/version.verb.js +36 -0
  245. package/dist/src/capabilities/version/version.verb.js.map +1 -0
  246. package/dist/src/constants.js +82 -0
  247. package/dist/src/constants.js.map +1 -0
  248. package/dist/src/index.js +12 -0
  249. package/dist/src/index.js.map +1 -0
  250. package/dist/src/kernel/completion/complete.js +66 -0
  251. package/dist/src/kernel/completion/complete.js.map +1 -0
  252. package/dist/src/kernel/completion/emitScripts.js +92 -0
  253. package/dist/src/kernel/completion/emitScripts.js.map +1 -0
  254. package/dist/src/kernel/completion/entitySource.js +285 -0
  255. package/dist/src/kernel/completion/entitySource.js.map +1 -0
  256. package/dist/src/kernel/completion/index.js +14 -0
  257. package/dist/src/kernel/completion/index.js.map +1 -0
  258. package/dist/src/kernel/completion/model.js +301 -0
  259. package/dist/src/kernel/completion/model.js.map +1 -0
  260. package/dist/src/kernel/completion/parse.js +253 -0
  261. package/dist/src/kernel/completion/parse.js.map +1 -0
  262. package/dist/src/kernel/completion/rank.js +101 -0
  263. package/dist/src/kernel/completion/rank.js.map +1 -0
  264. package/dist/src/kernel/completion/resolve.js +100 -0
  265. package/dist/src/kernel/completion/resolve.js.map +1 -0
  266. package/dist/src/kernel/completion/templates/bash.js +209 -0
  267. package/dist/src/kernel/completion/templates/bash.js.map +1 -0
  268. package/dist/src/kernel/completion/templates/fish.js +214 -0
  269. package/dist/src/kernel/completion/templates/fish.js.map +1 -0
  270. package/dist/src/kernel/completion/templates/index.js +23 -0
  271. package/dist/src/kernel/completion/templates/index.js.map +1 -0
  272. package/dist/src/kernel/completion/templates/shared.js +98 -0
  273. package/dist/src/kernel/completion/templates/shared.js.map +1 -0
  274. package/dist/src/kernel/completion/templates/zsh.js +201 -0
  275. package/dist/src/kernel/completion/templates/zsh.js.map +1 -0
  276. package/dist/src/kernel/completion/types.js +13 -0
  277. package/dist/src/kernel/completion/types.js.map +1 -0
  278. package/dist/src/kernel/config/defaults.js +17 -0
  279. package/dist/src/kernel/config/defaults.js.map +1 -0
  280. package/dist/src/kernel/config/evaluateProjectConfig.js +126 -0
  281. package/dist/src/kernel/config/evaluateProjectConfig.js.map +1 -0
  282. package/dist/src/kernel/config/findProjectConfig.js +43 -0
  283. package/dist/src/kernel/config/findProjectConfig.js.map +1 -0
  284. package/dist/src/kernel/config/firstRun.js +34 -0
  285. package/dist/src/kernel/config/firstRun.js.map +1 -0
  286. package/dist/src/kernel/config/globalConfig.js +79 -0
  287. package/dist/src/kernel/config/globalConfig.js.map +1 -0
  288. package/dist/src/kernel/config/index.js +16 -0
  289. package/dist/src/kernel/config/index.js.map +1 -0
  290. package/dist/src/kernel/config/paths.js +35 -0
  291. package/dist/src/kernel/config/paths.js.map +1 -0
  292. package/dist/src/kernel/config/readConfig.js +78 -0
  293. package/dist/src/kernel/config/readConfig.js.map +1 -0
  294. package/dist/src/kernel/config/schema.js +130 -0
  295. package/dist/src/kernel/config/schema.js.map +1 -0
  296. package/dist/src/kernel/config/types.js +19 -0
  297. package/dist/src/kernel/config/types.js.map +1 -0
  298. package/dist/src/kernel/config/writeConfigField.js +59 -0
  299. package/dist/src/kernel/config/writeConfigField.js.map +1 -0
  300. package/dist/src/kernel/copy.js +43 -0
  301. package/dist/src/kernel/copy.js.map +1 -0
  302. package/dist/src/kernel/error/PragmaError.js +149 -0
  303. package/dist/src/kernel/error/PragmaError.js.map +1 -0
  304. package/dist/src/kernel/error/constants.js +40 -0
  305. package/dist/src/kernel/error/constants.js.map +1 -0
  306. package/dist/src/kernel/error/fromTaskError.js +96 -0
  307. package/dist/src/kernel/error/fromTaskError.js.map +1 -0
  308. package/dist/src/kernel/error/index.js +13 -0
  309. package/dist/src/kernel/error/index.js.map +1 -0
  310. package/dist/src/kernel/error/recovery.js +52 -0
  311. package/dist/src/kernel/error/recovery.js.map +1 -0
  312. package/dist/src/kernel/error/renderError.js +115 -0
  313. package/dist/src/kernel/error/renderError.js.map +1 -0
  314. package/dist/src/kernel/error/serialize.js +25 -0
  315. package/dist/src/kernel/error/serialize.js.map +1 -0
  316. package/dist/src/kernel/error/types.js +9 -0
  317. package/dist/src/kernel/error/types.js.map +1 -0
  318. package/dist/src/kernel/index.js +25 -0
  319. package/dist/src/kernel/index.js.map +1 -0
  320. package/dist/src/kernel/packs/collect.js +187 -0
  321. package/dist/src/kernel/packs/collect.js.map +1 -0
  322. package/dist/src/kernel/packs/compile.js +304 -0
  323. package/dist/src/kernel/packs/compile.js.map +1 -0
  324. package/dist/src/kernel/packs/disclosure.js +76 -0
  325. package/dist/src/kernel/packs/disclosure.js.map +1 -0
  326. package/dist/src/kernel/packs/glob.js +38 -0
  327. package/dist/src/kernel/packs/glob.js.map +1 -0
  328. package/dist/src/kernel/packs/graphql/buildLookupDocument.js +258 -0
  329. package/dist/src/kernel/packs/graphql/buildLookupDocument.js.map +1 -0
  330. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +157 -0
  331. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -0
  332. package/dist/src/kernel/packs/graphql/index.js +20 -0
  333. package/dist/src/kernel/packs/graphql/index.js.map +1 -0
  334. package/dist/src/kernel/packs/graphql/nameMap.js +63 -0
  335. package/dist/src/kernel/packs/graphql/nameMap.js.map +1 -0
  336. package/dist/src/kernel/packs/index.js +34 -0
  337. package/dist/src/kernel/packs/index.js.map +1 -0
  338. package/dist/src/kernel/packs/iri.js +110 -0
  339. package/dist/src/kernel/packs/iri.js.map +1 -0
  340. package/dist/src/kernel/packs/renderPack.js +129 -0
  341. package/dist/src/kernel/packs/renderPack.js.map +1 -0
  342. package/dist/src/kernel/packs/resolveEntity.js +223 -0
  343. package/dist/src/kernel/packs/resolveEntity.js.map +1 -0
  344. package/dist/src/kernel/packs/runBodies.js +87 -0
  345. package/dist/src/kernel/packs/runBodies.js.map +1 -0
  346. package/dist/src/kernel/packs/sample.js +56 -0
  347. package/dist/src/kernel/packs/sample.js.map +1 -0
  348. package/dist/src/kernel/packs/schema.js +369 -0
  349. package/dist/src/kernel/packs/schema.js.map +1 -0
  350. package/dist/src/kernel/packs/sparql/applyFilters.js +68 -0
  351. package/dist/src/kernel/packs/sparql/applyFilters.js.map +1 -0
  352. package/dist/src/kernel/packs/sparql/applySearch.js +25 -0
  353. package/dist/src/kernel/packs/sparql/applySearch.js.map +1 -0
  354. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +217 -0
  355. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -0
  356. package/dist/src/kernel/packs/sparql/escape.js +21 -0
  357. package/dist/src/kernel/packs/sparql/escape.js.map +1 -0
  358. package/dist/src/kernel/packs/sparql/index.js +31 -0
  359. package/dist/src/kernel/packs/sparql/index.js.map +1 -0
  360. package/dist/src/kernel/packs/sparql/runSelect.js +101 -0
  361. package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -0
  362. package/dist/src/kernel/packs/types.js +30 -0
  363. package/dist/src/kernel/packs/types.js.map +1 -0
  364. package/dist/src/kernel/packs/uniqueness.js +30 -0
  365. package/dist/src/kernel/packs/uniqueness.js.map +1 -0
  366. package/dist/src/kernel/project/cli/buildProgram.js +263 -0
  367. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -0
  368. package/dist/src/kernel/project/cli/constants.js +27 -0
  369. package/dist/src/kernel/project/cli/constants.js.map +1 -0
  370. package/dist/src/kernel/project/cli/dispatch.js +420 -0
  371. package/dist/src/kernel/project/cli/dispatch.js.map +1 -0
  372. package/dist/src/kernel/project/cli/exitCodes.js +66 -0
  373. package/dist/src/kernel/project/cli/exitCodes.js.map +1 -0
  374. package/dist/src/kernel/project/cli/globalFlags.js +216 -0
  375. package/dist/src/kernel/project/cli/globalFlags.js.map +1 -0
  376. package/dist/src/kernel/project/cli/helpFormat.js +59 -0
  377. package/dist/src/kernel/project/cli/helpFormat.js.map +1 -0
  378. package/dist/src/kernel/project/cli/index.js +14 -0
  379. package/dist/src/kernel/project/cli/index.js.map +1 -0
  380. package/dist/src/kernel/project/cli/rootHelp.js +197 -0
  381. package/dist/src/kernel/project/cli/rootHelp.js.map +1 -0
  382. package/dist/src/kernel/project/cli/suggest.js +75 -0
  383. package/dist/src/kernel/project/cli/suggest.js.map +1 -0
  384. package/dist/src/kernel/project/cli/suggestNames.js +96 -0
  385. package/dist/src/kernel/project/cli/suggestNames.js.map +1 -0
  386. package/dist/src/kernel/project/cli/verbHelp.js +131 -0
  387. package/dist/src/kernel/project/cli/verbHelp.js.map +1 -0
  388. package/dist/src/kernel/project/mcp/buildServer.js +67 -0
  389. package/dist/src/kernel/project/mcp/buildServer.js.map +1 -0
  390. package/dist/src/kernel/project/mcp/envelope.js +37 -0
  391. package/dist/src/kernel/project/mcp/envelope.js.map +1 -0
  392. package/dist/src/kernel/project/mcp/index.js +8 -0
  393. package/dist/src/kernel/project/mcp/index.js.map +1 -0
  394. package/dist/src/kernel/project/mcp/instructions.js +44 -0
  395. package/dist/src/kernel/project/mcp/instructions.js.map +1 -0
  396. package/dist/src/kernel/project/mcp/mcpError.js +42 -0
  397. package/dist/src/kernel/project/mcp/mcpError.js.map +1 -0
  398. package/dist/src/kernel/project/mcp/prompts/index.js +36 -0
  399. package/dist/src/kernel/project/mcp/prompts/index.js.map +1 -0
  400. package/dist/src/kernel/project/mcp/prompts/provider.js +98 -0
  401. package/dist/src/kernel/project/mcp/prompts/provider.js.map +1 -0
  402. package/dist/src/kernel/project/mcp/prompts/source.js +154 -0
  403. package/dist/src/kernel/project/mcp/prompts/source.js.map +1 -0
  404. package/dist/src/kernel/project/mcp/registerVerb.js +300 -0
  405. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -0
  406. package/dist/src/kernel/project/mcp/serve.js +35 -0
  407. package/dist/src/kernel/project/mcp/serve.js.map +1 -0
  408. package/dist/src/kernel/render/compactUri.js +24 -0
  409. package/dist/src/kernel/render/compactUri.js.map +1 -0
  410. package/dist/src/kernel/render/contracts.js +10 -0
  411. package/dist/src/kernel/render/contracts.js.map +1 -0
  412. package/dist/src/kernel/render/disclosure.js +34 -0
  413. package/dist/src/kernel/render/disclosure.js.map +1 -0
  414. package/dist/src/kernel/render/envelope.js +30 -0
  415. package/dist/src/kernel/render/envelope.js.map +1 -0
  416. package/dist/src/kernel/render/formatters.js +27 -0
  417. package/dist/src/kernel/render/formatters.js.map +1 -0
  418. package/dist/src/kernel/render/index.js +15 -0
  419. package/dist/src/kernel/render/index.js.map +1 -0
  420. package/dist/src/kernel/render/prefixes.js +46 -0
  421. package/dist/src/kernel/render/prefixes.js.map +1 -0
  422. package/dist/src/kernel/render/renderers.js +468 -0
  423. package/dist/src/kernel/render/renderers.js.map +1 -0
  424. package/dist/src/kernel/render/style.js +85 -0
  425. package/dist/src/kernel/render/style.js.map +1 -0
  426. package/dist/src/kernel/render/turtle.js +194 -0
  427. package/dist/src/kernel/render/turtle.js.map +1 -0
  428. package/dist/src/kernel/render/writeStdout.js +43 -0
  429. package/dist/src/kernel/render/writeStdout.js.map +1 -0
  430. package/dist/src/kernel/runtime/boot.js +49 -0
  431. package/dist/src/kernel/runtime/boot.js.map +1 -0
  432. package/dist/src/kernel/runtime/facade.js +39 -0
  433. package/dist/src/kernel/runtime/facade.js.map +1 -0
  434. package/dist/src/kernel/runtime/graphpack/build.js +122 -0
  435. package/dist/src/kernel/runtime/graphpack/build.js.map +1 -0
  436. package/dist/src/kernel/runtime/graphpack/buildIndex.js +303 -0
  437. package/dist/src/kernel/runtime/graphpack/buildIndex.js.map +1 -0
  438. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js +6 -0
  439. package/dist/src/kernel/runtime/graphpack/embedded/pack.generated.js.map +1 -0
  440. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js +4 -0
  441. package/dist/src/kernel/runtime/graphpack/embedded/pack.index.generated.js.map +1 -0
  442. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js +4 -0
  443. package/dist/src/kernel/runtime/graphpack/embedded/pack.stories.generated.js.map +1 -0
  444. package/dist/src/kernel/runtime/graphpack/embedded.js +82 -0
  445. package/dist/src/kernel/runtime/graphpack/embedded.js.map +1 -0
  446. package/dist/src/kernel/runtime/graphpack/hash.js +38 -0
  447. package/dist/src/kernel/runtime/graphpack/hash.js.map +1 -0
  448. package/dist/src/kernel/runtime/graphpack/index.js +11 -0
  449. package/dist/src/kernel/runtime/graphpack/index.js.map +1 -0
  450. package/dist/src/kernel/runtime/graphpack/manifest.js +145 -0
  451. package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -0
  452. package/dist/src/kernel/runtime/graphpack/read.js +92 -0
  453. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -0
  454. package/dist/src/kernel/runtime/graphpack/schemas.js +70 -0
  455. package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -0
  456. package/dist/src/kernel/runtime/graphpack/stories.js +68 -0
  457. package/dist/src/kernel/runtime/graphpack/stories.js.map +1 -0
  458. package/dist/src/kernel/runtime/graphpack/types.js +55 -0
  459. package/dist/src/kernel/runtime/graphpack/types.js.map +1 -0
  460. package/dist/src/kernel/runtime/index.js +8 -0
  461. package/dist/src/kernel/runtime/index.js.map +1 -0
  462. package/dist/src/kernel/runtime/loadSession.js +34 -0
  463. package/dist/src/kernel/runtime/loadSession.js.map +1 -0
  464. package/dist/src/kernel/runtime/paths.js +78 -0
  465. package/dist/src/kernel/runtime/paths.js.map +1 -0
  466. package/dist/src/kernel/runtime/probe.js +37 -0
  467. package/dist/src/kernel/runtime/probe.js.map +1 -0
  468. package/dist/src/kernel/runtime/readEntity.js +363 -0
  469. package/dist/src/kernel/runtime/readEntity.js.map +1 -0
  470. package/dist/src/kernel/runtime/refs/gitOps.js +65 -0
  471. package/dist/src/kernel/runtime/refs/gitOps.js.map +1 -0
  472. package/dist/src/kernel/runtime/refs/index.js +29 -0
  473. package/dist/src/kernel/runtime/refs/index.js.map +1 -0
  474. package/dist/src/kernel/runtime/refs/parseRef.js +70 -0
  475. package/dist/src/kernel/runtime/refs/parseRef.js.map +1 -0
  476. package/dist/src/kernel/runtime/refs/resolve.js +332 -0
  477. package/dist/src/kernel/runtime/refs/resolve.js.map +1 -0
  478. package/dist/src/kernel/runtime/resolveSources.js +62 -0
  479. package/dist/src/kernel/runtime/resolveSources.js.map +1 -0
  480. package/dist/src/kernel/runtime/store.js +75 -0
  481. package/dist/src/kernel/runtime/store.js.map +1 -0
  482. package/dist/src/kernel/runtime/storeReadiness.js +51 -0
  483. package/dist/src/kernel/runtime/storeReadiness.js.map +1 -0
  484. package/dist/src/kernel/runtime/types.js +11 -0
  485. package/dist/src/kernel/runtime/types.js.map +1 -0
  486. package/dist/src/kernel/spec/asVerb.js +21 -0
  487. package/dist/src/kernel/spec/asVerb.js.map +1 -0
  488. package/dist/src/kernel/spec/emitReference.js +578 -0
  489. package/dist/src/kernel/spec/emitReference.js.map +1 -0
  490. package/dist/src/kernel/spec/emitSurface.js +202 -0
  491. package/dist/src/kernel/spec/emitSurface.js.map +1 -0
  492. package/dist/src/kernel/spec/index.js +11 -0
  493. package/dist/src/kernel/spec/index.js.map +1 -0
  494. package/dist/src/kernel/spec/surfaceConformance.js +103 -0
  495. package/dist/src/kernel/spec/surfaceConformance.js.map +1 -0
  496. package/dist/src/kernel/spec/types.js +14 -0
  497. package/dist/src/kernel/spec/types.js.map +1 -0
  498. package/dist/src/kernel/spec/validate.js +110 -0
  499. package/dist/src/kernel/spec/validate.js.map +1 -0
  500. package/dist/src/kernel/vocabulary.js +97 -0
  501. package/dist/src/kernel/vocabulary.js.map +1 -0
  502. package/dist/src/types.js +11 -0
  503. package/dist/src/types.js.map +1 -0
  504. package/package.json +20 -22
  505. package/pragma.conf.ts +249 -60
  506. package/src/bin.ts +267 -82
  507. package/src/capabilities/block.parity.test.ts +6 -3
  508. package/src/capabilities/capabilities/capabilities.render.ts +1 -1
  509. package/src/capabilities/capabilities/capabilities.verb.ts +1 -1
  510. package/src/capabilities/capabilities/catalog.ts +3 -3
  511. package/src/capabilities/capabilities/hints.ts +32 -7
  512. package/src/capabilities/capabilities/index.ts +1 -1
  513. package/src/capabilities/colophon/collectColophon.ts +35 -24
  514. package/src/capabilities/colophon/colophon.render.ts +25 -1
  515. package/src/capabilities/colophon/colophon.test.ts +42 -21
  516. package/src/capabilities/colophon/colophon.verb.ts +4 -4
  517. package/src/capabilities/config/collectConfigShow.test.ts +1 -0
  518. package/src/capabilities/config/collectConfigShow.ts +3 -3
  519. package/src/capabilities/config/field.render.ts +4 -5
  520. package/src/capabilities/config/fields.ts +17 -10
  521. package/src/capabilities/config/get.verb.ts +70 -0
  522. package/src/capabilities/config/getUnset.test.ts +264 -0
  523. package/src/capabilities/config/index.ts +5 -1
  524. package/src/capabilities/config/runField.ts +40 -22
  525. package/src/capabilities/config/runGet.ts +34 -0
  526. package/src/capabilities/config/runSet.ts +35 -9
  527. package/src/capabilities/config/set.test.ts +48 -14
  528. package/src/capabilities/config/set.verb.ts +8 -7
  529. package/src/capabilities/config/show.render.ts +1 -1
  530. package/src/capabilities/config/show.verb.ts +9 -6
  531. package/src/capabilities/config/types.ts +18 -4
  532. package/src/capabilities/config/unset.verb.ts +58 -0
  533. package/src/capabilities/create/byteEquality.subprocess.test.ts +2 -3
  534. package/src/capabilities/create/byteEquality.test.ts +25 -11
  535. package/src/capabilities/create/cliProjection.ts +227 -0
  536. package/src/capabilities/create/constants.ts +36 -61
  537. package/src/capabilities/create/create.mcp.test.ts +89 -5
  538. package/src/capabilities/create/create.render.ts +71 -7
  539. package/src/capabilities/create/create.test.ts +433 -219
  540. package/src/capabilities/create/create.verb.ts +297 -328
  541. package/src/capabilities/create/createGrammar.test.ts +865 -0
  542. package/src/capabilities/create/createHelp.ts +71 -0
  543. package/src/capabilities/create/createSurface.generated.ts +400 -0
  544. package/src/capabilities/create/crossCli.subprocess.test.ts +745 -0
  545. package/src/capabilities/create/cwdJail.test.ts +24 -5
  546. package/src/capabilities/create/generatorToVerbSpec.test.ts +186 -0
  547. package/src/capabilities/create/generatorToVerbSpec.ts +13 -11
  548. package/src/capabilities/create/index.ts +7 -4
  549. package/src/capabilities/create/messages.ts +18 -0
  550. package/src/capabilities/create/mount.ts +391 -0
  551. package/src/capabilities/create/pathJail.test.ts +90 -0
  552. package/src/capabilities/create/pathJail.ts +8 -5
  553. package/src/capabilities/create/pickGenerator.ts +23 -35
  554. package/src/capabilities/create/shippedCreate.subprocess.test.ts +164 -0
  555. package/src/capabilities/create/types.ts +20 -0
  556. package/src/capabilities/distribution.test.ts +3 -1
  557. package/src/capabilities/distribution.ts +10 -15
  558. package/src/capabilities/doctor/checks/checkKeStore.ts +7 -5
  559. package/src/capabilities/doctor/checks/checkPackageRefs.ts +6 -4
  560. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +2 -2
  561. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +72 -27
  562. package/src/capabilities/doctor/checks/checkShellCompletions.ts +59 -13
  563. package/src/capabilities/doctor/checks/index.ts +27 -0
  564. package/src/capabilities/doctor/checks/mcpCommand.test.ts +100 -0
  565. package/src/capabilities/doctor/checks/mcpCommand.ts +69 -0
  566. package/src/capabilities/doctor/checks/targetHealth.ts +274 -0
  567. package/src/capabilities/doctor/doctor.render.test.ts +18 -7
  568. package/src/capabilities/doctor/doctor.render.ts +43 -19
  569. package/src/capabilities/doctor/doctor.test.ts +123 -34
  570. package/src/capabilities/doctor/doctor.verb.ts +3 -3
  571. package/src/capabilities/doctor/runChecks.ts +62 -63
  572. package/src/capabilities/doctor/types.ts +20 -4
  573. package/src/capabilities/emptyRecovery.test.ts +13 -8
  574. package/src/capabilities/graph/examples.exec.test.ts +107 -0
  575. package/src/capabilities/graph/index.ts +1 -1
  576. package/src/capabilities/graph/inspect.render.ts +70 -22
  577. package/src/capabilities/graph/inspect.test.ts +260 -5
  578. package/src/capabilities/graph/inspect.verb.ts +18 -6
  579. package/src/capabilities/graph/query.render.ts +15 -3
  580. package/src/capabilities/graph/query.verb.ts +3 -3
  581. package/src/capabilities/graph/runQuery.ts +2 -3
  582. package/src/capabilities/index.ts +3 -1
  583. package/src/capabilities/info/collectInfo.ts +5 -4
  584. package/src/capabilities/info/info.render.ts +1 -1
  585. package/src/capabilities/info/info.verb.ts +1 -1
  586. package/src/capabilities/lazy.test.ts +32 -0
  587. package/src/capabilities/meta/complete.verb.ts +1 -1
  588. package/src/capabilities/meta/index.ts +1 -1
  589. package/src/capabilities/meta/mcp.verb.ts +10 -8
  590. package/src/capabilities/ontology/index.ts +15 -11
  591. package/src/capabilities/ontology/ontology.test.ts +6 -55
  592. package/src/capabilities/ontology/queries.ts +2 -2
  593. package/src/capabilities/ontology/render.ts +3 -4
  594. package/src/capabilities/ontology/verbs.ts +27 -68
  595. package/src/capabilities/prompt/index.ts +2 -2
  596. package/src/capabilities/prompt/prompt.render.ts +6 -2
  597. package/src/capabilities/prompt/types.ts +1 -1
  598. package/src/capabilities/prompt/verbs.ts +4 -5
  599. package/src/capabilities/reference.test.ts +63 -0
  600. package/src/capabilities/resources/provider.ts +342 -85
  601. package/src/capabilities/resources/resources.test.ts +355 -59
  602. package/src/capabilities/setup/buildPlan.ts +236 -0
  603. package/src/capabilities/setup/index.ts +7 -7
  604. package/src/capabilities/setup/mode.ts +74 -0
  605. package/src/capabilities/setup/operations/index.ts +74 -0
  606. package/src/capabilities/setup/operations/setupCompletions.ts +97 -24
  607. package/src/capabilities/setup/operations/setupConfig.ts +124 -0
  608. package/src/capabilities/setup/operations/setupGenerator.ts +396 -326
  609. package/src/capabilities/setup/operations/setupLsp.ts +329 -68
  610. package/src/capabilities/setup/operations/setupMcp.ts +137 -97
  611. package/src/capabilities/setup/operations/setupSkills.ts +336 -108
  612. package/src/capabilities/setup/plan.render.ts +241 -0
  613. package/src/capabilities/setup/plan.ts +236 -0
  614. package/src/capabilities/setup/setup.mcp.correctness.test.ts +432 -0
  615. package/src/capabilities/setup/setup.render.test.ts +281 -73
  616. package/src/capabilities/setup/setup.render.ts +45 -77
  617. package/src/capabilities/setup/setup.test.ts +972 -209
  618. package/src/capabilities/setup/setup.verb.ts +223 -71
  619. package/src/capabilities/setup/shell.test.ts +86 -0
  620. package/src/capabilities/setup/shell.ts +137 -11
  621. package/src/capabilities/setup/targets.ts +367 -0
  622. package/src/capabilities/setup/types.ts +18 -57
  623. package/src/capabilities/shared/assertExecOk.ts +68 -10
  624. package/src/capabilities/shared/index.ts +32 -0
  625. package/src/capabilities/shared/packageManager.test.ts +55 -0
  626. package/src/capabilities/shared/packageManager.ts +62 -6
  627. package/src/capabilities/skill/discover.ts +37 -5
  628. package/src/capabilities/skill/index.ts +1 -1
  629. package/src/capabilities/skill/render.ts +10 -9
  630. package/src/capabilities/skill/skill.test.ts +7 -5
  631. package/src/capabilities/skill/verbs.ts +3 -4
  632. package/src/capabilities/sources/collectStatus.ts +7 -2
  633. package/src/capabilities/sources/index.ts +1 -1
  634. package/src/capabilities/sources/installSkills.ts +84 -7
  635. package/src/capabilities/sources/runUpdate.ts +53 -21
  636. package/src/capabilities/sources/sources.test.ts +154 -2
  637. package/src/capabilities/sources/status.render.ts +1 -1
  638. package/src/capabilities/sources/status.verb.ts +1 -1
  639. package/src/capabilities/sources/update.render.ts +1 -1
  640. package/src/capabilities/sources/update.verb.ts +1 -1
  641. package/src/capabilities/surface.test.ts +134 -17
  642. package/src/capabilities/upgrade/runUpgrade.ts +8 -8
  643. package/src/capabilities/upgrade/upgrade.render.ts +4 -5
  644. package/src/capabilities/upgrade/upgrade.test.ts +3 -3
  645. package/src/capabilities/upgrade/upgrade.verb.ts +1 -1
  646. package/src/capabilities/version/index.ts +12 -0
  647. package/src/capabilities/version/version.test.ts +66 -0
  648. package/src/capabilities/version/version.verb.ts +39 -0
  649. package/src/constants.ts +31 -1
  650. package/src/identity.test.ts +40 -25
  651. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +15 -13
  652. package/src/kernel/completion/complete.test.ts +12 -2
  653. package/src/kernel/completion/complete.ts +1 -1
  654. package/src/kernel/completion/emitScripts.ts +1 -1
  655. package/src/kernel/completion/entitySource.test.ts +1 -1
  656. package/src/kernel/completion/entitySource.ts +21 -8
  657. package/src/kernel/completion/model.test.ts +164 -12
  658. package/src/kernel/completion/model.ts +94 -14
  659. package/src/kernel/completion/parse.test.ts +4 -7
  660. package/src/kernel/completion/parse.ts +15 -0
  661. package/src/kernel/completion/resolve.test.ts +0 -1
  662. package/src/kernel/completion/safety.test.ts +34 -26
  663. package/src/kernel/completion/shellDrive.test.ts +28 -9
  664. package/src/kernel/completion/templates/bash.ts +7 -2
  665. package/src/kernel/completion/templates/index.ts +23 -0
  666. package/src/kernel/completion/types.ts +7 -0
  667. package/src/kernel/config/defaults.test.ts +25 -2
  668. package/src/kernel/config/defaults.ts +4 -3
  669. package/src/kernel/config/evaluateProjectConfig.ts +31 -8
  670. package/src/kernel/config/firstRun.test.ts +44 -38
  671. package/src/kernel/config/firstRun.ts +24 -88
  672. package/src/kernel/config/index.ts +1 -1
  673. package/src/kernel/config/readConfig.test.ts +6 -3
  674. package/src/kernel/config/readConfig.ts +1 -1
  675. package/src/kernel/config/schema.ts +3 -1
  676. package/src/kernel/config/types.ts +3 -1
  677. package/src/kernel/copy.test.ts +34 -4
  678. package/src/kernel/copy.ts +54 -0
  679. package/src/kernel/error/PragmaError.test.ts +5 -2
  680. package/src/kernel/error/PragmaError.ts +4 -2
  681. package/src/kernel/error/constants.ts +7 -5
  682. package/src/kernel/error/fromTaskError.ts +28 -6
  683. package/src/kernel/error/recovery.ts +14 -0
  684. package/src/kernel/error/renderError.ts +42 -1
  685. package/src/kernel/error/types.ts +21 -1
  686. package/src/kernel/index.ts +26 -0
  687. package/src/kernel/packs/collect.ts +12 -16
  688. package/src/kernel/packs/compile.test.ts +130 -1
  689. package/src/kernel/packs/compile.ts +93 -3
  690. package/src/kernel/packs/disclosure.ts +2 -2
  691. package/src/kernel/packs/graphql/buildLookupDocument.ts +1 -1
  692. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +3 -4
  693. package/src/kernel/packs/graphql/index.ts +20 -0
  694. package/src/kernel/packs/index.ts +40 -0
  695. package/src/kernel/packs/iri.test.ts +73 -0
  696. package/src/kernel/packs/iri.ts +66 -14
  697. package/src/kernel/packs/renderPack.ts +24 -5
  698. package/src/kernel/packs/resolveEntity.test.ts +213 -0
  699. package/src/kernel/packs/resolveEntity.ts +112 -18
  700. package/src/kernel/packs/runBodies.ts +2 -3
  701. package/src/kernel/packs/sample.ts +1 -1
  702. package/src/kernel/packs/schema.ts +18 -1
  703. package/src/kernel/packs/sparql/applyFilters.ts +16 -17
  704. package/src/kernel/packs/sparql/buildLookupQuery.ts +75 -3
  705. package/src/kernel/packs/sparql/index.ts +37 -0
  706. package/src/kernel/packs/sparql/runSelect.test.ts +1 -1
  707. package/src/kernel/packs/sparql/runSelect.ts +3 -4
  708. package/src/kernel/packs/toolDescription.test.ts +42 -3
  709. package/src/kernel/packs/types.ts +13 -0
  710. package/src/kernel/packs/uniqueness.ts +1 -1
  711. package/src/kernel/project/cli/buildProgram.test.ts +147 -12
  712. package/src/kernel/project/cli/buildProgram.ts +77 -18
  713. package/src/kernel/project/cli/constants.ts +34 -0
  714. package/src/kernel/project/cli/dispatch.test.ts +160 -3
  715. package/src/kernel/project/cli/dispatch.ts +222 -42
  716. package/src/kernel/project/cli/exitCodes.ts +1 -1
  717. package/src/kernel/project/cli/globalFlags.test.ts +117 -1
  718. package/src/kernel/project/cli/globalFlags.ts +130 -30
  719. package/src/kernel/project/cli/helpFormat.ts +13 -0
  720. package/src/kernel/project/cli/rootHelp.ts +41 -12
  721. package/src/kernel/project/cli/suggest.test.ts +33 -1
  722. package/src/kernel/project/cli/suggest.ts +25 -1
  723. package/src/kernel/project/cli/verbHelp.test.ts +30 -0
  724. package/src/kernel/project/cli/verbHelp.ts +23 -7
  725. package/src/kernel/project/mcp/buildServer.ts +7 -4
  726. package/src/kernel/project/mcp/envelope.ts +2 -2
  727. package/src/kernel/project/mcp/instructions.ts +2 -2
  728. package/src/kernel/project/mcp/mcpError.ts +1 -1
  729. package/src/kernel/project/mcp/parity.test.ts +5 -2
  730. package/src/kernel/project/mcp/prompts/index.ts +37 -0
  731. package/src/kernel/project/mcp/prompts/source.ts +2 -2
  732. package/src/kernel/project/mcp/registerVerb.ts +35 -9
  733. package/src/kernel/project/mcp/serve.ts +2 -2
  734. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +7 -4
  735. package/src/kernel/render/contracts.ts +21 -0
  736. package/src/kernel/render/envelope.ts +2 -3
  737. package/src/kernel/render/formatters.ts +1 -1
  738. package/src/kernel/render/renderers.test.ts +243 -6
  739. package/src/kernel/render/renderers.ts +222 -20
  740. package/src/kernel/render/style.test.ts +75 -24
  741. package/src/kernel/render/style.ts +31 -1
  742. package/src/kernel/render/turtle.ts +222 -0
  743. package/src/kernel/runtime/graphpack/buildIndex.ts +1 -1
  744. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +3 -3
  745. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +1 -1
  746. package/src/kernel/runtime/graphpack/embedded.ts +3 -3
  747. package/src/kernel/runtime/graphpack/manifest.ts +1 -1
  748. package/src/kernel/runtime/graphpack/read.ts +1 -2
  749. package/src/kernel/runtime/loadSession.ts +1 -1
  750. package/src/kernel/runtime/probe.ts +6 -6
  751. package/src/kernel/runtime/readEntity.ts +472 -28
  752. package/src/kernel/runtime/refs/index.ts +39 -0
  753. package/src/kernel/runtime/refs/parseRef.ts +2 -2
  754. package/src/kernel/runtime/refs/resolve.ts +4 -4
  755. package/src/kernel/runtime/storeReadiness.ts +1 -2
  756. package/src/kernel/runtime/types.ts +15 -1
  757. package/src/kernel/runtime/wasmEmbed.test.ts +37 -39
  758. package/src/kernel/spec/emitReference.ts +105 -30
  759. package/src/kernel/spec/emitSurface.ts +48 -6
  760. package/src/kernel/spec/surfaceConformance.test.ts +4 -2
  761. package/src/kernel/spec/types.ts +248 -4
  762. package/src/testing/behavioral/docExamples.test.ts +14 -0
  763. package/src/testing/behavioral/errorMatrix.mcp.test.ts +2 -2
  764. package/src/testing/behavioral/firstRun.e2e.test.ts +24 -24
  765. package/src/testing/behavioral/journeys.cli.test.ts +1 -1
  766. package/src/testing/behavioral/journeys.defaultPack.test.ts +7 -7
  767. package/src/testing/behavioral/journeys.implementation.test.ts +206 -0
  768. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +2 -2
  769. package/src/testing/behavioral/journeys.packageStories.test.ts +4 -4
  770. package/src/testing/behavioral/mcpServe.e2e.test.ts +57 -2
  771. package/src/testing/behavioral/mcpSurface.test.ts +1 -1
  772. package/src/testing/behavioral/rootCli.e2e.test.ts +26 -2
  773. package/src/testing/eval/cases/effectful.ts +3 -2
  774. package/src/testing/fixtures/blockGraph.ts +79 -0
  775. package/src/testing/fixtures/graph/canonical.ts +88 -2
  776. package/src/testing/fixtures/graph/defaultPack.ts +1 -1
  777. package/src/testing/helpers/blankCanonicalRanges.ts +36 -0
  778. package/src/testing/helpers/projectMcp.ts +32 -6
  779. package/src/testing/helpers/runCli.ts +35 -18
  780. package/src/testing/perf/budgets.test.ts +20 -9
  781. package/src/testing/perf/budgets.ts +58 -9
  782. package/src/testing/perf/codegen.test.ts +126 -0
  783. package/src/testing/perf/globalSetup.test.ts +286 -0
  784. package/src/testing/perf/globalSetup.ts +505 -23
  785. package/src/testing/perf/measure.test.ts +38 -0
  786. package/src/testing/perf/measure.ts +23 -4
  787. package/src/testing/setupXdgIsolation.ts +81 -21
  788. package/src/testing/tempRoot.globalSetup.ts +122 -0
  789. package/dist/pragma +0 -0
  790. package/src/capabilities/create/compiledCreate.subprocess.test.ts +0 -189
  791. package/src/capabilities/create/templates.embedded.generated.ts +0 -28
  792. package/src/capabilities/doctor/checks/checkConfigFile.ts +0 -42
  793. package/src/capabilities/doctor/checks/checkMcpCommands.ts +0 -114
  794. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +0 -68
  795. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +0 -61
  796. package/src/capabilities/doctor/checks/deriveBand.test.ts +0 -42
  797. package/src/capabilities/doctor/checks/deriveBand.ts +0 -28
  798. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +0 -11
@@ -10,6 +10,7 @@
10
10
  import { compactUri } from "./compactUri.js";
11
11
  import type {
12
12
  ColumnDef,
13
+ RenderContext,
13
14
  RenderListOptions,
14
15
  RenderLookupOptions,
15
16
  SectionDef,
@@ -19,6 +20,56 @@ import { defaultStyle, type RenderStyle, styleFor } from "./style.js";
19
20
 
20
21
  type RenderMode = "plain" | "llm";
21
22
 
23
+ /**
24
+ * The widest a plain-table cell renders. Cells are records, not documents: a
25
+ * pack can ship arbitrary prose in a column (one shipped an 834-character
26
+ * multi-line description), and a single cell that wraps destroys the
27
+ * one-row-one-record model every field-splitting consumer relies on. Longer
28
+ * values are truncated with an ellipsis; the detail escape hatch is `lookup`.
29
+ */
30
+ export const MAX_PLAIN_CELL_WIDTH = 80;
31
+
32
+ /**
33
+ * The placeholder for an empty cell in a populated column. The grid stays
34
+ * rectangular: a value's absence must not shift its neighbours left, or
35
+ * `awk '{print $4}'` reads a different field on every row.
36
+ */
37
+ const EMPTY_CELL = "-";
38
+
39
+ /** The context assumed when a caller passes none: interactive, headers on. */
40
+ const DEFAULT_CONTEXT: RenderContext = { headers: true, stdoutIsTty: true };
41
+
42
+ /**
43
+ * The markdown heading level `renderLookupSections` gives a section in llm mode
44
+ * — the lookup title is `##`, so a section is `###`. Read, not re-typed, by
45
+ * {@link nestHeadings}: the renderer is the only party that knows its own
46
+ * nesting depth, and it must stay the only party that encodes it.
47
+ */
48
+ const SECTION_HEADING_LEVEL = 3;
49
+
50
+ /** Markdown's deepest heading. Demotion clamps here rather than overflowing. */
51
+ const MAX_HEADING_LEVEL = 6;
52
+
53
+ /**
54
+ * An ATX heading: up to three spaces of indent, 1–6 `#`, whitespace, text.
55
+ *
56
+ * The indent is CommonMark's — four spaces would make the line an indented
57
+ * code block, three or fewer leave it a heading. Missing it left
58
+ * ` ### Accessibility` un-nested while its unindented twin was demoted, so
59
+ * one body could come out with two conflicting hierarchies. The indent is
60
+ * captured so a rewrite preserves it.
61
+ */
62
+ const ATX_HEADING = /^( {0,3})(#{1,6})(\s+\S.*)$/;
63
+
64
+ /**
65
+ * A fenced code-block delimiter: up to three spaces of indent, then the run of
66
+ * markers, then whatever follows on the line (the info string).
67
+ *
68
+ * The RUN LENGTH and the info string both matter for closing, which is why
69
+ * they are captured rather than just recognised — see {@link nestHeadings}.
70
+ */
71
+ const CODE_FENCE = /^ {0,3}((`{3,})|(~{3,}))([^`]*)$/;
72
+
22
73
  /**
23
74
  * The empty-state body — the message plus its optional hint on a second line,
24
75
  * or "" when the caller declared no message (bare-empty behavior preserved).
@@ -30,37 +81,112 @@ function emptyBody<T>(options: RenderListOptions<T>): string {
30
81
  : options.emptyMessage;
31
82
  }
32
83
 
84
+ /**
85
+ * The empty-list notice a dispatcher routes to STDERR (exit 0): zero rows is
86
+ * a calm success, and stdout — the data stream — must not carry a human
87
+ * sentence a pipe would read as a record. Exported for the formatter seam's
88
+ * `emptyNotice`; the plain renderer itself no longer prints it.
89
+ */
90
+ export function renderListEmptyNotice<T>(
91
+ options: RenderListOptions<T>,
92
+ ): string {
93
+ return emptyBody(options);
94
+ }
95
+
96
+ /**
97
+ * One plain-table cell: single-line (embedded newlines collapse to a space)
98
+ * and at most {@link MAX_PLAIN_CELL_WIDTH} characters, truncated with an
99
+ * ellipsis — see the constant's rationale.
100
+ */
101
+ function disciplineCell(value: string): string {
102
+ const singleLine = value.replace(/\s*\n\s*/g, " ").trim();
103
+ if (singleLine.length <= MAX_PLAIN_CELL_WIDTH) return singleLine;
104
+ return `${singleLine.slice(0, MAX_PLAIN_CELL_WIDTH - 1).trimEnd()}…`;
105
+ }
106
+
107
+ /**
108
+ * Render a list as a plain table: a bold UPPERCASE header row (from
109
+ * `column.label`), then one padded row per item over a RECTANGULAR grid — a
110
+ * column is included when any row (or `showWhenEmpty`) populates it, and an
111
+ * empty cell in an included column renders `-` so fields never shift. An
112
+ * empty list renders nothing on a terminal (the notice is stderr's, see
113
+ * {@link renderListEmptyNotice}) and just the header row on a pipe, so a
114
+ * zero-record table stays well-formed for field-splitting consumers.
115
+ *
116
+ * @param items - The rows.
117
+ * @param options - Columns and empty-state copy.
118
+ * @param context - Header/TTY presentation facts (defaults to a terminal
119
+ * with headers on).
120
+ * @param style - TTY styling; off a TTY the styler is inert, so piped bytes
121
+ * carry no escape sequences.
122
+ * @returns The formatted table.
123
+ */
33
124
  export function renderListPlain<T>(
34
125
  items: readonly T[],
35
126
  options: RenderListOptions<T>,
127
+ context: RenderContext = DEFAULT_CONTEXT,
128
+ style: RenderStyle = defaultStyle(),
36
129
  ): string {
37
- if (items.length === 0) return emptyBody(options);
130
+ if (items.length === 0) {
131
+ // A piped zero-record table keeps its schema; a terminal needs nothing.
132
+ return context.headers && !context.stdoutIsTty
133
+ ? renderHeaderRow(options.columns, style)
134
+ : "";
135
+ }
38
136
 
39
137
  const prefixes = options.prefixes ?? DEFAULT_PREFIX_MAP;
40
- const rows = items.map((item) =>
41
- options.columns
42
- .map((column) => ({
43
- column,
44
- value: formatColumnValue(item, column, prefixes),
45
- }))
46
- .filter(({ column, value }) => shouldRenderColumn(column, value))
47
- .map(({ value }) => value),
138
+ const cells = items.map((item) =>
139
+ options.columns.map((column) =>
140
+ disciplineCell(formatColumnValue(item, column, prefixes)),
141
+ ),
142
+ );
143
+ const included = options.columns
144
+ .map((column, index) => ({ column, index }))
145
+ .filter(
146
+ ({ column, index }) =>
147
+ column.showWhenEmpty === true ||
148
+ cells.some((row) => (row[index] ?? "").length > 0),
149
+ );
150
+
151
+ const header = included.map(({ column }) => column.label.toUpperCase());
152
+ const rows = cells.map((row) =>
153
+ included.map(({ index }) => {
154
+ const value = row[index] ?? "";
155
+ return value.length > 0 ? value : EMPTY_CELL;
156
+ }),
48
157
  );
49
158
 
50
- const widths = rows.reduce<number[]>(
159
+ const layoutRows = context.headers ? [header, ...rows] : rows;
160
+ const widths = layoutRows.reduce<number[]>(
51
161
  (acc, row) =>
52
162
  row.map((value, index) => Math.max(acc[index] ?? 0, value.length)),
53
163
  [],
54
164
  );
165
+ const padded = layoutRows.map((row) =>
166
+ row
167
+ .map((value, index) => value.padEnd(widths[index] ?? value.length))
168
+ .join(" ")
169
+ .trimEnd(),
170
+ );
55
171
 
56
- return rows
57
- .map((row) =>
58
- row
59
- .map((value, index) => value.padEnd(widths[index] ?? value.length))
60
- .join(" ")
61
- .trimEnd(),
62
- )
63
- .join("\n");
172
+ if (!context.headers) return padded.join("\n");
173
+ const [headerLine, ...bodyLines] = padded;
174
+ const styledHeader = style.enabled
175
+ ? style.bold(headerLine ?? "")
176
+ : (headerLine ?? "");
177
+ return [styledHeader, ...bodyLines].join("\n");
178
+ }
179
+
180
+ /** The zero-record header row (every declared column, uppercase labels). */
181
+ function renderHeaderRow<T>(
182
+ columns: readonly ColumnDef<T>[],
183
+ style: RenderStyle,
184
+ ): string {
185
+ const line = columns
186
+ .map((column) => column.label.toUpperCase())
187
+ .join(" ")
188
+ .trimEnd();
189
+ return style.enabled ? style.bold(line) : line;
64
190
  }
65
191
 
66
192
  export function renderListLlm<T>(
@@ -196,7 +322,9 @@ function renderLookupSections<T>(
196
322
 
197
323
  sections.push("");
198
324
  sections.push(
199
- mode === "llm" ? `### ${section.heading}` : `${section.heading}:`,
325
+ mode === "llm"
326
+ ? `${"#".repeat(SECTION_HEADING_LEVEL)} ${section.heading}`
327
+ : `${section.heading}:`,
200
328
  );
201
329
  sections.push(body);
202
330
  }
@@ -238,7 +366,81 @@ function renderFieldValue(
238
366
  }
239
367
 
240
368
  const text = formatScalarValue(value, prefixes);
241
- return mode === "llm" ? text : indentBlock(text);
369
+ // Plain mode is not markdown — a `###` there is literal text, and rewriting
370
+ // it would corrupt the value. Only the llm mode's markdown has a hierarchy to
371
+ // collide with, so only it nests.
372
+ return mode === "llm"
373
+ ? nestHeadings(text, SECTION_HEADING_LEVEL)
374
+ : indentBlock(text);
375
+ }
376
+
377
+ /**
378
+ * Demote a section body's own ATX headings so they nest UNDER the heading the
379
+ * renderer gave the section.
380
+ *
381
+ * Authored markdown cannot know what level it will be rendered at; the renderer
382
+ * can, and so the renderer is the side that moves. A block whose shallowest
383
+ * heading is at or above `parentLevel` is shifted down as a whole — `###
384
+ * Accessibility` inside a `### Guidelines` section becomes `#### Accessibility`
385
+ * — which fixes the collision (a section heading immediately followed by a
386
+ * same-level heading reads as an empty section) while preserving the content's
387
+ * internal hierarchy exactly. Content already nested deeper is left alone.
388
+ *
389
+ * Headings inside a fenced code block are content, not structure — a `# ` in a
390
+ * shell sample is a comment — so fenced regions pass through untouched.
391
+ *
392
+ * @param text - The section body as authored.
393
+ * @param parentLevel - The heading level the section itself was rendered at.
394
+ * @returns The body with its headings nested below `parentLevel`.
395
+ */
396
+ function nestHeadings(text: string, parentLevel: number): string {
397
+ const lines = text.split("\n");
398
+ const headings = new Map<number, number>();
399
+ // A fence CLOSES only on the same marker character, a run at least as long
400
+ // as the opener's, and no info string — CommonMark's rule, and the reason
401
+ // the opener's length is remembered rather than just its character. Toggling
402
+ // on any same-character run let a ``` sample inside a ```` block read as the
403
+ // close, after which every `#` line in that code block was rewritten as a
404
+ // heading: the renderer editing someone's sample code.
405
+ let fence: { marker: string; length: number } | undefined;
406
+ for (const [index, line] of lines.entries()) {
407
+ const delimiter = CODE_FENCE.exec(line);
408
+ const run = delimiter?.[1];
409
+ if (run !== undefined) {
410
+ const marker = run.charAt(0);
411
+ const info = (delimiter?.[4] ?? "").trim();
412
+ if (fence === undefined) {
413
+ fence = { marker, length: run.length };
414
+ continue;
415
+ }
416
+ if (
417
+ marker === fence.marker &&
418
+ run.length >= fence.length &&
419
+ info === ""
420
+ ) {
421
+ fence = undefined;
422
+ }
423
+ continue;
424
+ }
425
+ if (fence !== undefined) continue;
426
+ const level = ATX_HEADING.exec(line)?.[2]?.length;
427
+ if (level !== undefined) headings.set(index, level);
428
+ }
429
+
430
+ if (headings.size === 0) return text;
431
+ const shift = parentLevel + 1 - Math.min(...headings.values());
432
+ if (shift <= 0) return text;
433
+
434
+ return lines
435
+ .map((line, index) => {
436
+ const level = headings.get(index);
437
+ if (level === undefined) return line;
438
+ const hashes = "#".repeat(Math.min(level + shift, MAX_HEADING_LEVEL));
439
+ // `$1` keeps the line's own indent: rewriting it away would turn a
440
+ // legally indented heading into an unindented one.
441
+ return line.replace(ATX_HEADING, `$1${hashes}$3`);
442
+ })
443
+ .join("\n");
242
444
  }
243
445
 
244
446
  function renderCodeValue<T>(
@@ -1,31 +1,82 @@
1
- import { describe, expect, it } from "vitest";
2
- import { defaultStyle, styleFor } from "./style.js";
3
-
4
- describe("styleFor", () => {
5
- it("passes every color through unchanged when disabled", () => {
6
- const style = styleFor(false);
7
- expect(style.enabled).toBe(false);
8
- expect(style.bold("x")).toBe("x");
9
- expect(style.dim("x")).toBe("x");
10
- expect(style.cyan("x")).toBe("x");
11
- expect(style.green("x")).toBe("x");
12
- expect(style.yellow("x")).toBe("x");
1
+ /**
2
+ * The color gate.
3
+ *
4
+ * `forbidsColor` is tested directly because it encodes a convention with two
5
+ * counter-intuitive edges — an empty assignment does NOT disable, and any
6
+ * non-empty value DOES, including `0`. The zero-escape guarantee is asserted
7
+ * against the shared chalk instance, which is what the four modules that bypass
8
+ * `RenderStyle` actually reach for.
9
+ */
10
+
11
+ import chalk from "chalk";
12
+ import { afterEach, describe, expect, it, vi } from "vitest";
13
+ import { forbidsColor, styleFor } from "./style.js";
14
+
15
+ /** The ANSI escape introducer, written as an escape so no control byte
16
+ * sits in the source. Assertions read "does not contain this". */
17
+ const ANSI_ESCAPE = "\u001B[";
18
+
19
+ afterEach(() => {
20
+ vi.unstubAllEnvs();
21
+ });
22
+
23
+ describe("forbidsColor", () => {
24
+ it("disables for any non-empty value, whatever it says", () => {
25
+ expect(forbidsColor({ NO_COLOR: "1" })).toBe(true);
26
+ // Counter-intuitive and deliberate: the value is never parsed.
27
+ expect(forbidsColor({ NO_COLOR: "0" })).toBe(true);
28
+ expect(forbidsColor({ NO_COLOR: "false" })).toBe(true);
13
29
  });
14
30
 
15
- it("reports enabled and drives chalk when enabled", () => {
16
- const style = styleFor(true);
17
- expect(style.enabled).toBe(true);
18
- // A non-TTY test process leaves chalk at level 0, so the text survives
19
- // verbatim; what the beautified renderers gate on is `enabled`.
20
- expect(style.cyan("x")).toContain("x");
31
+ it("does NOT disable for an absent or empty variable", () => {
32
+ expect(forbidsColor({})).toBe(false);
33
+ expect(forbidsColor({ NO_COLOR: "" })).toBe(false);
21
34
  });
22
35
  });
23
36
 
24
- describe("defaultStyle", () => {
25
- it("is disabled when stdout is not a TTY (keeps piped output byte-stable)", () => {
26
- // The vitest runner's stdout is never a TTY, so the beautify seam is inert
27
- // here — the guarantee that piped / agent output is unstyled and stable.
28
- expect(process.stdout.isTTY).not.toBe(true);
29
- expect(defaultStyle().enabled).toBe(false);
37
+ describe("the plain style emits no escapes (PROTECTED)", () => {
38
+ it("returns its input untouched for every role", () => {
39
+ const plain = styleFor(false);
40
+ // `enabled` rides alongside the roles, so select the callables rather than
41
+ // assuming the shape — a role added later is then covered automatically.
42
+ const roles = Object.values(plain).filter(
43
+ (value): value is (text: string) => string => typeof value === "function",
44
+ );
45
+ expect(roles.length).toBeGreaterThan(0);
46
+ for (const role of roles) {
47
+ expect(role("text")).toBe("text");
48
+ expect(role("text")).not.toContain(ANSI_ESCAPE);
49
+ }
50
+ });
51
+ });
52
+
53
+ describe("NO_COLOR reaches the shared chalk instance (PROTECTED)", () => {
54
+ // The defect this pins: the gate delegated to chalk, and the vendored
55
+ // `supports-color` it ships has no NO_COLOR branch at all — so the flag did
56
+ // nothing while the code asserted it worked. Re-importing under a stubbed env
57
+ // exercises the module-load check that now zeroes the level.
58
+ it("zeroes chalk's level, so even direct chalk callers go plain", async () => {
59
+ const level = chalk.level;
60
+ try {
61
+ // FORCE a color-capable level first. Under vitest there is no TTY, so
62
+ // chalk already reports 0 and the assertion below would hold whether or
63
+ // not the module does anything — the test would pass with the fix
64
+ // deleted, which is no test at all. Starting from 3 makes the zeroing the
65
+ // only thing that can satisfy it.
66
+ chalk.level = 3;
67
+ expect(chalk.cyan("text")).toContain(ANSI_ESCAPE);
68
+
69
+ vi.stubEnv("NO_COLOR", "1");
70
+ vi.resetModules();
71
+ await import("./style.js");
72
+
73
+ expect(chalk.level).toBe(0);
74
+ // The four modules that bypass RenderStyle call chalk exactly like this.
75
+ expect(chalk.cyan("text")).toBe("text");
76
+ expect(chalk.bold("text")).not.toContain(ANSI_ESCAPE);
77
+ } finally {
78
+ chalk.level = level;
79
+ vi.resetModules();
80
+ }
30
81
  });
31
82
  });
@@ -58,13 +58,43 @@ export function styleFor(enabled: boolean): RenderStyle {
58
58
  };
59
59
  }
60
60
 
61
+ /**
62
+ * Whether the environment forbids color outright.
63
+ *
64
+ * `NO_COLOR` is honored when PRESENT AND NON-EMPTY, whatever its value — an
65
+ * empty assignment is explicitly not a request to disable (no-color.org). The
66
+ * value is never parsed: `NO_COLOR=0` still disables, which surprises people
67
+ * and is nonetheless what the convention says.
68
+ *
69
+ * @param env - The environment to read.
70
+ * @returns True when color must not be emitted.
71
+ */
72
+ export function forbidsColor(env: NodeJS.ProcessEnv): boolean {
73
+ const value = env.NO_COLOR;
74
+ return value !== undefined && value !== "";
75
+ }
76
+
77
+ // Applied to the SHARED chalk instance at module load, not inside
78
+ // `defaultStyle()`, because four modules reach for `chalk` directly rather than
79
+ // through `RenderStyle` — help formatting, doctor, upgrade and the colophon's
80
+ // Markdown renderer. Gating only the style seam would leave every one of them
81
+ // still emitting escapes. Zeroing the level once covers them by construction,
82
+ // including any site added later.
83
+ //
84
+ // This used to be delegated to chalk, and the delegation was silent: the
85
+ // vendored `supports-color` this version ships handles `FORCE_COLOR` and has no
86
+ // `NO_COLOR` branch at all, so the flag did nothing while the code asserted it
87
+ // worked.
88
+ if (forbidsColor(process.env)) chalk.level = 0;
89
+
61
90
  /**
62
91
  * The active style for this process's stdout.
63
92
  *
64
93
  * Gated on BOTH signals: stdout must be an attended TTY, so piped / redirected /
65
94
  * MCP output stays byte-stable even where `supports-color` fires off a TTY (CI
66
95
  * sets `GITHUB_ACTIONS`, which chalk honors); AND chalk must report a usable
67
- * color level, so `NO_COLOR` on a real terminal still yields the plain form.
96
+ * color level, which the module-load check above forces to zero under
97
+ * `NO_COLOR`.
68
98
  *
69
99
  * @returns A colorizing style on a color-capable TTY, else the identity styler.
70
100
  * @note Impure — reads `process.stdout.isTTY` and chalk's color level.
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Serialize an entity's neighbourhood as Turtle — the dense form of the read.
3
+ *
4
+ * The JSON projection is faithful but expensive: one named node costs about 95
5
+ * bytes of wrapper to convey thirteen characters, and that overhead is paid per
6
+ * term. Measured on one button, structure alone was ~6.1 KB of a 15.8 KB read.
7
+ * Turtle spends the prefixes ONCE and then writes each term as itself.
8
+ *
9
+ * It is not merely shorter — it is the shape this data already has:
10
+ *
11
+ * - IRI versus literal is SYNTAX (`ds:Foo` against `"Foo"`), which is the whole
12
+ * thing the typed-term projection had to carry a `termType` field to say.
13
+ * - A blank node is `[ … ]` inline, which is exactly the record the reader
14
+ * assembles by hand for the JSON form.
15
+ * - Datatypes and language tags are native (`"x"@en`, `"2026-02-20"^^xsd:date`).
16
+ * - An inbound edge is just a triple written the other way round. The whole
17
+ * `InboundGroup` structure exists only because JSON cannot point an arrow
18
+ * backwards.
19
+ *
20
+ * Counts, samples and truncations ride as `#` comments. That is not a fallback:
21
+ * a comment is the one place a serialization can say something ABOUT the data
22
+ * without asserting it as data, and a reader — human or model — takes it the
23
+ * same way.
24
+ *
25
+ * Pure: it reads only the projection it is handed, so the same neighbourhood
26
+ * always renders the same bytes.
27
+ */
28
+
29
+ import type {
30
+ InboundGroup,
31
+ InspectResult,
32
+ NestedRecord,
33
+ ReadTerm,
34
+ } from "../runtime/readEntity.js";
35
+
36
+ /** Characters that must be escaped inside a single-line Turtle literal. */
37
+ const ESCAPES: Readonly<Record<string, string>> = {
38
+ "\\": "\\\\",
39
+ '"': '\\"',
40
+ "\n": "\\n",
41
+ "\r": "\\r",
42
+ "\t": "\\t",
43
+ };
44
+
45
+ /** Whether a literal is better served by a triple-quoted long string. */
46
+ function isMultiline(value: string): boolean {
47
+ return value.includes("\n");
48
+ }
49
+
50
+ /** Escape a literal for the single-line `"…"` form. */
51
+ function escapeShort(value: string): string {
52
+ return value.replace(/[\\"\n\r\t]/g, (char) => ESCAPES[char] ?? char);
53
+ }
54
+
55
+ /**
56
+ * Escape a literal for the `"""…"""` form.
57
+ *
58
+ * Only backslashes and a trailing/tripled quote need attention there — newlines
59
+ * are the entire point of the form and must survive untouched, which is what
60
+ * keeps an embedded YAML or Markdown body readable rather than turning it into
61
+ * one `\n`-riddled line.
62
+ */
63
+ function escapeLong(value: string): string {
64
+ return (
65
+ value
66
+ .replace(/\\/g, "\\\\")
67
+ .replace(/"""/g, '\\"\\"\\"')
68
+ // A value ENDING in a quote would run straight into the closing delimiter
69
+ // and produce four quotes, which no parser reads as intended. Truncation
70
+ // makes this reachable on ordinary prose, not just on hostile input.
71
+ .replace(/"$/, '\\"')
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Write a name that may or may not have compacted.
77
+ *
78
+ * `compactUri` returns its input UNCHANGED when no namespace matches, so a
79
+ * datatype or predicate outside the prefix map arrived here as a bare absolute
80
+ * IRI and was emitted raw — producing `"x"^^http://example.com/type`, which no
81
+ * parser accepts. A prefixed name goes through as-is; anything else is wrapped.
82
+ */
83
+ function asName(value: string): string {
84
+ return /^[A-Za-z][\w.-]*:[^/]/.test(value) && !value.includes("://")
85
+ ? value
86
+ : `<${value}>`;
87
+ }
88
+
89
+ /** Render one term in Turtle: a prefixed name, an `<iri>`, or a literal. */
90
+ function renderTerm(term: ReadTerm): string {
91
+ if (term.termType === "NamedNode") {
92
+ return term.prefixed ?? `<${term.value}>`;
93
+ }
94
+ if (term.termType === "BlankNode") {
95
+ // A bare `[]` — the label is store-local and re-minted on every load, so
96
+ // writing it would publish an identifier that means nothing on the next read.
97
+ return "[]";
98
+ }
99
+ const body = isMultiline(term.value)
100
+ ? `"""${escapeLong(term.value)}"""`
101
+ : `"${escapeShort(term.value)}"`;
102
+ // Direction is RDF 1.2's `@lang--dir`; it only ever accompanies a language.
103
+ if (term.language) {
104
+ return `${body}@${term.language}${term.direction ? `--${term.direction}` : ""}`;
105
+ }
106
+ if (term.datatype) return `${body}^^${asName(term.datatype)}`;
107
+ return body;
108
+ }
109
+
110
+ /**
111
+ * `# ds:guidelines — 5,814 chars, showing 400` — states a preview as a preview.
112
+ *
113
+ * On its OWN line ABOVE the triple, never trailing it: a Turtle comment runs to
114
+ * end of line, so a note placed after the object swallows the `;` or `.` that
115
+ * terminates the statement and silently breaks the document.
116
+ */
117
+ function truncationNote(predicate: string, term: ReadTerm): string | undefined {
118
+ if (!term.truncated || term.length === undefined) return undefined;
119
+ const total = term.length.toLocaleString("en-US");
120
+ return ` # ${predicate} — ${total} chars, showing ${term.value.length}`;
121
+ }
122
+
123
+ /** Render one inlined blank node as a Turtle `[ … ]` record. */
124
+ function renderNested(record: NestedRecord): string {
125
+ const fields = Object.entries(record).map(([field, value]) => {
126
+ // `type` was hoisted out of the record body on the way in; `a` is Turtle's
127
+ // own shorthand for it, so it goes back exactly where it came from.
128
+ const predicate = field === "type" ? "a" : asName(field);
129
+ return `${predicate} ${renderTerm(value)}`;
130
+ });
131
+ return `[ ${fields.join(" ; ")} ]`;
132
+ }
133
+
134
+ /** The prefixes a rendering actually uses, so the header declares no more. */
135
+ function usedPrefixes(
136
+ text: string,
137
+ prefixes: Readonly<Record<string, string>>,
138
+ ): string[] {
139
+ return Object.entries(prefixes)
140
+ .filter(([prefix]) => new RegExp(`\\b${prefix}:`).test(text))
141
+ .sort(([a], [b]) => a.localeCompare(b))
142
+ .map(([prefix, namespace]) => `@prefix ${prefix}: <${namespace}> .`);
143
+ }
144
+
145
+ /** `# rdf:type — 330 total, sample of 5` and the triples under it. */
146
+ function renderInbound(subject: string, group: InboundGroup): string[] {
147
+ const predicate = renderTerm(group.predicate);
148
+ const total = group.count.toLocaleString("en-US");
149
+ // An empty `subjects` means two different things, and conflating them told a
150
+ // lie: at `summary` EVERY group is empty because the level exhibits none, so
151
+ // claiming "none individually addressable" there libelled perfectly nameable
152
+ // subjects. Only a level that WOULD have shown exemplars can conclude that
153
+ // none exist.
154
+ const exhibits = group.exhibits ?? 0;
155
+ const note =
156
+ exhibits > 0 && group.subjects.length === 0 && group.count > 0
157
+ ? `# ${predicate} — ${total} total, none individually addressable; use the noun's list verb`
158
+ : group.sampled
159
+ ? `# ${predicate} — ${total} total, sample of ${group.subjects.length}; use the noun's list verb for the full set`
160
+ : group.truncated
161
+ ? `# ${predicate} — ${total} total, showing ${group.subjects.length}`
162
+ : `# ${predicate} — ${total}`;
163
+ return [
164
+ note,
165
+ ...group.subjects.map((s) => `${renderTerm(s)} ${predicate} ${subject} .`),
166
+ ];
167
+ }
168
+
169
+ /**
170
+ * Render an entity's neighbourhood as a Turtle document.
171
+ *
172
+ * @param result - The neighbourhood projection to serialize.
173
+ * @param prefixes - The store's merged prefix map, for the `@prefix` header.
174
+ * @returns A Turtle document: header, the subject's own triples, its inlined
175
+ * blank nodes, then the edges pointing at it.
176
+ */
177
+ export function toTurtle(
178
+ result: InspectResult,
179
+ prefixes: Readonly<Record<string, string>>,
180
+ ): string {
181
+ const subject = result.prefixed ?? `<${result.uri}>`;
182
+ const body: string[] = [];
183
+
184
+ // The subject's own triples, one predicate per line.
185
+ const predicates: string[] = [];
186
+ for (const group of result.groups) {
187
+ const predicate = renderTerm(group.predicate);
188
+ // Blank objects are written as their inlined records instead, so they are
189
+ // skipped here — emitting both would assert the same edge twice.
190
+ const objects = group.objects.filter((o) => o.termType !== "BlankNode");
191
+ if (objects.length === 0) continue;
192
+ const keyword = predicate === "rdf:type" ? "a" : predicate;
193
+ // Notes are folded INTO the element, above its statement, so the `;` the
194
+ // join appends always lands on the statement line. Pushed as siblings they
195
+ // would each take a separator of their own — into a comment, which runs to
196
+ // end of line and eats it.
197
+ const notes = objects
198
+ .map((o) => truncationNote(keyword, o))
199
+ .filter((n): n is string => n !== undefined);
200
+ const rendered = objects.map(renderTerm).join(", ");
201
+ predicates.push([...notes, ` ${keyword} ${rendered}`].join("\n"));
202
+ }
203
+ for (const [via, records] of Object.entries(result.nested)) {
204
+ predicates.push(
205
+ ` ${via}\n ${records.map(renderNested).join(",\n ")}`,
206
+ );
207
+ }
208
+ if (predicates.length > 0) {
209
+ body.push(`${subject}\n${predicates.join(" ;\n")} .`);
210
+ }
211
+
212
+ if (result.inbound.length > 0) {
213
+ body.push("", "# ── referenced by ──");
214
+ for (const group of result.inbound) {
215
+ body.push(...renderInbound(subject, group));
216
+ }
217
+ }
218
+
219
+ const text = body.join("\n");
220
+ const header = usedPrefixes(text, prefixes);
221
+ return [...header, "", text].join("\n").trimEnd();
222
+ }
@@ -29,7 +29,7 @@
29
29
  * stays completable instead of vanishing behind the tbox facet.
30
30
  */
31
31
 
32
- import { compactUri } from "../../render/compactUri.js";
32
+ import { compactUri } from "../../render/index.js";
33
33
  import { VOCABULARY } from "../../vocabulary.js";
34
34
  import type { PackIndex, PackIndexEntity } from "./types.js";
35
35