@canonical/pragma-cli 0.31.0 → 0.33.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 (1091) hide show
  1. package/README.md +35 -421
  2. package/dist/pragma +0 -0
  3. package/package.json +28 -42
  4. package/src/bin.ts +292 -11
  5. package/src/capabilities/block/blockList.test.ts +79 -0
  6. package/src/capabilities/block/blockList.verb.ts +163 -0
  7. package/src/capabilities/block/index.ts +25 -0
  8. package/src/capabilities/block/pack.ts +166 -0
  9. package/src/capabilities/block/parity.test.ts +187 -0
  10. package/src/capabilities/block/tierChain.ts +78 -0
  11. package/src/capabilities/capabilities/capabilities.render.ts +89 -0
  12. package/src/capabilities/capabilities/capabilities.test.ts +140 -0
  13. package/src/capabilities/capabilities/capabilities.verb.ts +48 -0
  14. package/src/capabilities/capabilities/catalog.ts +148 -0
  15. package/src/capabilities/capabilities/hints.ts +212 -0
  16. package/src/capabilities/capabilities/index.ts +13 -0
  17. package/src/capabilities/capabilities/types.ts +60 -0
  18. package/src/capabilities/colophon/collectColophon.ts +68 -0
  19. package/src/capabilities/colophon/colophon.render.test.ts +114 -0
  20. package/src/capabilities/colophon/colophon.render.ts +47 -0
  21. package/src/capabilities/colophon/colophon.test.ts +241 -0
  22. package/src/capabilities/colophon/colophon.verb.ts +44 -0
  23. package/src/capabilities/colophon/index.ts +6 -0
  24. package/src/capabilities/colophon/markdownTerminal.test.ts +50 -0
  25. package/src/capabilities/colophon/markdownTerminal.ts +104 -0
  26. package/src/capabilities/colophon/pragmaColophon.ts +66 -0
  27. package/src/capabilities/colophon/types.ts +29 -0
  28. package/src/capabilities/config/collectConfigShow.ts +32 -0
  29. package/src/capabilities/config/field.render.ts +28 -0
  30. package/src/capabilities/config/fields.ts +81 -0
  31. package/src/capabilities/config/index.ts +6 -0
  32. package/src/capabilities/config/runField.ts +59 -0
  33. package/src/capabilities/config/runSet.ts +38 -0
  34. package/src/capabilities/config/set.test.ts +207 -0
  35. package/src/capabilities/config/set.verb.ts +70 -0
  36. package/src/capabilities/config/show.render.test.ts +65 -0
  37. package/src/capabilities/config/show.render.ts +107 -0
  38. package/src/capabilities/config/show.verb.ts +45 -0
  39. package/src/capabilities/config/types.ts +27 -0
  40. package/src/capabilities/create/byteEquality.subprocess.test.ts +88 -0
  41. package/src/capabilities/create/byteEquality.test.ts +225 -0
  42. package/src/capabilities/create/compiledCreate.subprocess.test.ts +152 -0
  43. package/src/capabilities/create/create.mcp.test.ts +139 -0
  44. package/src/capabilities/create/create.render.ts +50 -0
  45. package/src/capabilities/create/create.test.ts +432 -0
  46. package/src/capabilities/create/create.verb.ts +493 -0
  47. package/src/capabilities/create/cwdJail.test.ts +129 -0
  48. package/src/capabilities/create/generatorToVerbSpec.ts +111 -0
  49. package/src/capabilities/create/index.ts +25 -0
  50. package/src/capabilities/create/pathJail.ts +73 -0
  51. package/src/capabilities/create/pickGenerator.ts +63 -0
  52. package/src/capabilities/create/templates.embedded.generated.ts +53 -0
  53. package/src/capabilities/create/types.ts +8 -0
  54. package/src/capabilities/doctor/checks/checkConfigFile.ts +41 -0
  55. package/src/capabilities/doctor/checks/checkKeStore.ts +39 -0
  56. package/src/capabilities/doctor/checks/checkMcpCommands.ts +114 -0
  57. package/src/capabilities/doctor/checks/checkMcpConfigured.ts +67 -0
  58. package/src/capabilities/doctor/checks/checkNodeVersion.ts +25 -0
  59. package/src/capabilities/doctor/checks/checkPackageRefs.ts +73 -0
  60. package/src/capabilities/doctor/checks/checkPragmaVersion.ts +22 -0
  61. package/src/capabilities/doctor/checks/checkShellCompletions.test.ts +111 -0
  62. package/src/capabilities/doctor/checks/checkShellCompletions.ts +131 -0
  63. package/src/capabilities/doctor/checks/checkSkillsSymlinked.ts +60 -0
  64. package/src/capabilities/doctor/checks/deriveBand.test.ts +42 -0
  65. package/src/capabilities/doctor/checks/deriveBand.ts +28 -0
  66. package/src/capabilities/doctor/doctor.render.test.ts +170 -0
  67. package/src/capabilities/doctor/doctor.render.ts +198 -0
  68. package/src/capabilities/doctor/doctor.test.ts +209 -0
  69. package/src/capabilities/doctor/doctor.verb.ts +46 -0
  70. package/src/capabilities/doctor/index.ts +6 -0
  71. package/src/capabilities/doctor/runChecks.ts +100 -0
  72. package/src/capabilities/doctor/types.ts +56 -0
  73. package/src/capabilities/emptyRecovery.test.ts +112 -0
  74. package/src/capabilities/graph/index.ts +21 -0
  75. package/src/capabilities/graph/inspect.render.ts +38 -0
  76. package/src/capabilities/graph/inspect.test.ts +80 -0
  77. package/src/capabilities/graph/inspect.verb.ts +51 -0
  78. package/src/capabilities/graph/query.render.ts +77 -0
  79. package/src/capabilities/graph/query.test.ts +156 -0
  80. package/src/capabilities/graph/query.verb.ts +58 -0
  81. package/src/capabilities/graph/runQuery.ts +49 -0
  82. package/src/capabilities/index.ts +54 -0
  83. package/src/capabilities/info/collectInfo.ts +76 -0
  84. package/src/capabilities/info/index.ts +6 -0
  85. package/src/capabilities/info/info.render.ts +72 -0
  86. package/src/capabilities/info/info.test.ts +127 -0
  87. package/src/capabilities/info/info.verb.ts +46 -0
  88. package/src/capabilities/info/types.ts +42 -0
  89. package/src/capabilities/lazy.test.ts +89 -0
  90. package/src/capabilities/meta/complete.verb.ts +52 -0
  91. package/src/capabilities/meta/index.ts +15 -0
  92. package/src/capabilities/meta/mcp.verb.ts +35 -0
  93. package/src/capabilities/modifier/index.ts +15 -0
  94. package/src/capabilities/modifier/pack.ts +64 -0
  95. package/src/capabilities/ontology/index.ts +19 -0
  96. package/src/capabilities/ontology/ontology.test.ts +246 -0
  97. package/src/capabilities/ontology/queries.ts +197 -0
  98. package/src/capabilities/ontology/render.ts +87 -0
  99. package/src/capabilities/ontology/verbs.ts +269 -0
  100. package/src/capabilities/prompt/index.ts +18 -0
  101. package/src/capabilities/prompt/prompt.render.test.ts +94 -0
  102. package/src/capabilities/prompt/prompt.render.ts +87 -0
  103. package/src/capabilities/prompt/prompt.test.ts +180 -0
  104. package/src/capabilities/prompt/types.ts +30 -0
  105. package/src/capabilities/prompt/verbs.ts +93 -0
  106. package/src/capabilities/reference.test.ts +32 -0
  107. package/src/capabilities/resources/index.ts +15 -0
  108. package/src/capabilities/resources/provider.ts +245 -0
  109. package/src/capabilities/resources/resources.test.ts +213 -0
  110. package/src/capabilities/roundtrip.test.ts +107 -0
  111. package/src/capabilities/scopeTypeSync.test.ts +37 -0
  112. package/src/capabilities/setup/index.ts +12 -0
  113. package/src/capabilities/setup/operations/setupCompletions.ts +141 -0
  114. package/src/capabilities/setup/operations/setupGenerator.ts +403 -0
  115. package/src/capabilities/setup/operations/setupLsp.ts +105 -0
  116. package/src/capabilities/setup/operations/setupMcp.ts +262 -0
  117. package/src/capabilities/setup/operations/setupSkills.ts +205 -0
  118. package/src/capabilities/setup/setup.render.test.ts +109 -0
  119. package/src/capabilities/setup/setup.render.ts +96 -0
  120. package/src/capabilities/setup/setup.test.ts +702 -0
  121. package/src/capabilities/setup/setup.verb.ts +261 -0
  122. package/src/capabilities/setup/shell.ts +85 -0
  123. package/src/capabilities/setup/types.ts +99 -0
  124. package/src/capabilities/shared/assertExecOk.ts +106 -0
  125. package/src/capabilities/shared/bands.ts +16 -0
  126. package/src/capabilities/shared/packageManager.ts +62 -0
  127. package/src/capabilities/shared/registry.ts +70 -0
  128. package/src/capabilities/skill/discover.ts +178 -0
  129. package/src/capabilities/skill/index.ts +12 -0
  130. package/src/capabilities/skill/render.ts +60 -0
  131. package/src/capabilities/skill/skill.test.ts +142 -0
  132. package/src/capabilities/skill/verbs.ts +100 -0
  133. package/src/capabilities/sources/collectStatus.ts +102 -0
  134. package/src/capabilities/sources/index.ts +15 -0
  135. package/src/capabilities/sources/installSkills.ts +124 -0
  136. package/src/capabilities/sources/runUpdate.ts +464 -0
  137. package/src/capabilities/sources/sources.test.ts +828 -0
  138. package/src/capabilities/sources/status.render.test.ts +65 -0
  139. package/src/capabilities/sources/status.render.ts +83 -0
  140. package/src/capabilities/sources/status.verb.ts +42 -0
  141. package/src/capabilities/sources/types.ts +51 -0
  142. package/src/capabilities/sources/update.render.ts +35 -0
  143. package/src/capabilities/sources/update.verb.ts +76 -0
  144. package/src/capabilities/standard/index.ts +18 -0
  145. package/src/capabilities/standard/pack.ts +128 -0
  146. package/src/capabilities/standard/parity.test.ts +208 -0
  147. package/src/capabilities/surface.test.ts +233 -0
  148. package/src/capabilities/tier/index.ts +19 -0
  149. package/src/capabilities/tier/lookup.render.test.ts +72 -0
  150. package/src/capabilities/tier/lookup.render.ts +59 -0
  151. package/src/capabilities/tier/lookup.test.ts +83 -0
  152. package/src/capabilities/tier/lookup.verb.ts +44 -0
  153. package/src/capabilities/tier/pack.ts +28 -0
  154. package/src/capabilities/tier/runLookup.ts +87 -0
  155. package/src/capabilities/token/addConfig.render.ts +27 -0
  156. package/src/capabilities/token/addConfig.test.ts +62 -0
  157. package/src/capabilities/token/addConfig.verb.ts +40 -0
  158. package/src/capabilities/token/index.ts +19 -0
  159. package/src/capabilities/token/pack.ts +58 -0
  160. package/src/capabilities/token/runAddConfig.ts +95 -0
  161. package/src/capabilities/upgrade/index.ts +6 -0
  162. package/src/capabilities/upgrade/runUpgrade.ts +119 -0
  163. package/src/capabilities/upgrade/types.ts +21 -0
  164. package/src/capabilities/upgrade/upgrade.render.ts +55 -0
  165. package/src/capabilities/upgrade/upgrade.test.ts +372 -0
  166. package/src/capabilities/upgrade/upgrade.verb.ts +56 -0
  167. package/src/constants.test.ts +33 -0
  168. package/src/constants.ts +38 -70
  169. package/src/index.ts +27 -122
  170. package/src/kernel/completion/__snapshots__/emitScripts.test.ts.snap +339 -0
  171. package/src/kernel/completion/bashDrive.test.ts +73 -0
  172. package/src/kernel/completion/complete.test.ts +99 -0
  173. package/src/kernel/completion/complete.ts +77 -0
  174. package/src/kernel/completion/emitScripts.test.ts +173 -0
  175. package/src/kernel/completion/emitScripts.ts +122 -0
  176. package/src/kernel/completion/entitySource.test.ts +198 -0
  177. package/src/kernel/completion/entitySource.ts +277 -0
  178. package/src/kernel/completion/index.ts +42 -0
  179. package/src/kernel/completion/model.test.ts +405 -0
  180. package/src/kernel/completion/model.ts +258 -0
  181. package/src/kernel/completion/parse.test.ts +336 -0
  182. package/src/kernel/completion/parse.ts +294 -0
  183. package/src/kernel/completion/rank.test.ts +100 -0
  184. package/src/kernel/completion/rank.ts +118 -0
  185. package/src/kernel/completion/resolve.test.ts +204 -0
  186. package/src/kernel/completion/resolve.ts +133 -0
  187. package/src/kernel/completion/safety.test.ts +374 -0
  188. package/src/kernel/completion/templates/bash.ts +249 -0
  189. package/src/kernel/completion/templates/fish.ts +245 -0
  190. package/src/kernel/completion/templates/shared.ts +134 -0
  191. package/src/kernel/completion/templates/zsh.ts +246 -0
  192. package/src/kernel/completion/types.ts +153 -0
  193. package/src/kernel/config/__snapshots__/firstRun.test.ts.snap +11 -0
  194. package/src/kernel/config/defaults.ts +28 -0
  195. package/src/kernel/config/evaluateProjectConfig.ts +119 -0
  196. package/src/kernel/config/findProjectConfig.ts +45 -0
  197. package/src/kernel/config/firstRun.test.ts +60 -0
  198. package/src/kernel/config/firstRun.ts +91 -0
  199. package/src/kernel/config/globalConfig.ts +94 -0
  200. package/src/kernel/config/index.ts +35 -0
  201. package/src/kernel/config/paths.ts +39 -0
  202. package/src/kernel/config/readConfig.test.ts +245 -0
  203. package/src/kernel/config/readConfig.ts +94 -0
  204. package/src/kernel/config/schema.ts +56 -0
  205. package/src/kernel/config/types.ts +106 -0
  206. package/src/kernel/config/writeConfigField.ts +82 -0
  207. package/src/kernel/error/PragmaError.test.ts +119 -0
  208. package/src/kernel/error/PragmaError.ts +182 -0
  209. package/src/kernel/error/constants.ts +38 -0
  210. package/src/kernel/error/fromTaskError.test.ts +83 -0
  211. package/src/kernel/error/fromTaskError.ts +80 -0
  212. package/src/kernel/error/index.ts +23 -0
  213. package/src/kernel/error/recovery.test.ts +60 -0
  214. package/src/kernel/error/recovery.ts +49 -0
  215. package/src/kernel/error/renderError.ts +101 -0
  216. package/src/kernel/error/serialize.ts +28 -0
  217. package/src/kernel/error/types.ts +62 -0
  218. package/src/kernel/packs/collect.test.ts +138 -0
  219. package/src/kernel/packs/collect.ts +108 -0
  220. package/src/kernel/packs/compile.test.ts +229 -0
  221. package/src/kernel/packs/compile.ts +315 -0
  222. package/src/kernel/packs/disclosure.test.ts +200 -0
  223. package/src/kernel/packs/disclosure.ts +98 -0
  224. package/src/kernel/packs/glob.ts +39 -0
  225. package/src/kernel/packs/graphql/buildLookupDocument.ts +397 -0
  226. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +217 -0
  227. package/src/kernel/packs/graphql/nameMap.ts +67 -0
  228. package/src/kernel/packs/graphqlSource.test.ts +383 -0
  229. package/src/kernel/packs/iri.ts +78 -0
  230. package/src/kernel/packs/renderPack.ts +196 -0
  231. package/src/kernel/packs/resolveEntity.ts +232 -0
  232. package/src/kernel/packs/runBodies.ts +157 -0
  233. package/src/kernel/packs/sample.ts +60 -0
  234. package/src/kernel/packs/schema.ts +328 -0
  235. package/src/kernel/packs/sparql/applyFilters.ts +83 -0
  236. package/src/kernel/packs/sparql/applySearch.ts +33 -0
  237. package/src/kernel/packs/sparql/buildLookupQuery.ts +180 -0
  238. package/src/kernel/packs/sparql/escape.ts +22 -0
  239. package/src/kernel/packs/sparql/runSelect.test.ts +80 -0
  240. package/src/kernel/packs/sparql/runSelect.ts +84 -0
  241. package/src/kernel/packs/toolDescription.test.ts +81 -0
  242. package/src/kernel/packs/types.ts +337 -0
  243. package/src/kernel/packs/uniqueness.ts +35 -0
  244. package/src/kernel/project/cli/buildProgram.test.ts +431 -0
  245. package/src/kernel/project/cli/buildProgram.ts +291 -0
  246. package/src/kernel/project/cli/dispatch.test.ts +288 -0
  247. package/src/kernel/project/cli/dispatch.ts +334 -0
  248. package/src/kernel/project/cli/exitCodes.test.ts +59 -0
  249. package/src/kernel/project/cli/exitCodes.ts +68 -0
  250. package/src/kernel/project/cli/globalFlags.test.ts +107 -0
  251. package/src/kernel/project/cli/globalFlags.ts +149 -0
  252. package/src/kernel/project/cli/helpFormat.ts +58 -0
  253. package/src/kernel/project/cli/index.ts +21 -0
  254. package/src/kernel/project/cli/interactionSeam.test.ts +99 -0
  255. package/src/kernel/project/cli/rootHelp.ts +220 -0
  256. package/src/kernel/project/cli/suggest.test.ts +54 -0
  257. package/src/kernel/project/cli/suggest.ts +67 -0
  258. package/src/kernel/project/cli/suggestNames.ts +122 -0
  259. package/src/kernel/project/cli/verbHelp.test.ts +138 -0
  260. package/src/kernel/project/cli/verbHelp.ts +144 -0
  261. package/src/kernel/project/mcp/buildServer.ts +70 -0
  262. package/src/kernel/project/mcp/envelope.ts +44 -0
  263. package/src/kernel/project/mcp/index.ts +8 -0
  264. package/src/kernel/project/mcp/instructions.ts +48 -0
  265. package/src/kernel/project/mcp/mcpError.ts +52 -0
  266. package/src/kernel/project/mcp/parity.test.ts +72 -0
  267. package/src/kernel/project/mcp/prompts/prompts.test.ts +104 -0
  268. package/src/kernel/project/mcp/prompts/provider.ts +104 -0
  269. package/src/kernel/project/mcp/prompts/source.ts +194 -0
  270. package/src/kernel/project/mcp/registerVerb.test.ts +238 -0
  271. package/src/kernel/project/mcp/registerVerb.ts +296 -0
  272. package/src/kernel/project/mcp/serve.ts +34 -0
  273. package/src/kernel/project/mcp/toolDescriptions.test.ts +80 -0
  274. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +127 -0
  275. package/src/kernel/render/compactUri.ts +25 -0
  276. package/src/kernel/render/contracts.ts +72 -0
  277. package/src/kernel/render/disclosure.ts +44 -0
  278. package/src/kernel/render/envelope.ts +50 -0
  279. package/src/kernel/render/formatters.ts +31 -0
  280. package/src/kernel/render/index.ts +30 -0
  281. package/src/kernel/render/prefixes.ts +21 -0
  282. package/src/kernel/render/renderers.test.ts +205 -0
  283. package/src/kernel/render/renderers.ts +447 -0
  284. package/src/kernel/render/style.test.ts +31 -0
  285. package/src/kernel/render/style.ts +74 -0
  286. package/src/kernel/render/writeStdout.test.ts +43 -0
  287. package/src/kernel/render/writeStdout.ts +49 -0
  288. package/src/kernel/runtime/boot.test.ts +69 -0
  289. package/src/kernel/runtime/boot.ts +59 -0
  290. package/src/kernel/runtime/facade.test.ts +125 -0
  291. package/src/kernel/runtime/facade.ts +47 -0
  292. package/src/kernel/runtime/graphpack/build.ts +176 -0
  293. package/src/kernel/runtime/graphpack/buildIndex.test.ts +103 -0
  294. package/src/kernel/runtime/graphpack/buildIndex.ts +317 -0
  295. package/src/kernel/runtime/graphpack/embedded/pack.generated.ts +5 -0
  296. package/src/kernel/runtime/graphpack/embedded/pack.index.generated.ts +3 -0
  297. package/src/kernel/runtime/graphpack/embedded/sample.ttl +39 -0
  298. package/src/kernel/runtime/graphpack/embedded.ts +70 -0
  299. package/src/kernel/runtime/graphpack/graphpack.test.ts +221 -0
  300. package/src/kernel/runtime/graphpack/hash.ts +46 -0
  301. package/src/kernel/runtime/graphpack/index.ts +21 -0
  302. package/src/kernel/runtime/graphpack/manifest.ts +55 -0
  303. package/src/kernel/runtime/graphpack/read.ts +117 -0
  304. package/src/kernel/runtime/graphpack/types.ts +125 -0
  305. package/src/kernel/runtime/index.ts +15 -0
  306. package/src/kernel/runtime/loadSession.ts +48 -0
  307. package/src/kernel/runtime/lock.ts +90 -0
  308. package/src/kernel/runtime/paths.ts +37 -0
  309. package/src/kernel/runtime/probe.test.ts +16 -0
  310. package/src/kernel/runtime/probe.ts +39 -0
  311. package/src/kernel/runtime/readEntity.ts +83 -0
  312. package/src/kernel/runtime/refs/gitOps.ts +88 -0
  313. package/src/kernel/runtime/refs/parseRef.test.ts +34 -0
  314. package/src/kernel/runtime/refs/parseRef.ts +103 -0
  315. package/src/kernel/runtime/refs/resolve.ts +380 -0
  316. package/src/kernel/runtime/resolveSources.test.ts +154 -0
  317. package/src/kernel/runtime/resolveSources.ts +66 -0
  318. package/src/kernel/runtime/store.test.ts +94 -0
  319. package/src/kernel/runtime/store.ts +90 -0
  320. package/src/kernel/runtime/storeReadiness.ts +61 -0
  321. package/src/kernel/runtime/storeless.test.ts +86 -0
  322. package/src/kernel/runtime/types.ts +210 -0
  323. package/src/kernel/runtime/wasmEmbed.test.ts +144 -0
  324. package/src/kernel/spec/asVerb.ts +23 -0
  325. package/src/kernel/spec/emitReference.test.ts +196 -0
  326. package/src/kernel/spec/emitReference.ts +491 -0
  327. package/src/kernel/spec/emitSurface.test.ts +65 -0
  328. package/src/kernel/spec/emitSurface.ts +225 -0
  329. package/src/kernel/spec/index.ts +36 -0
  330. package/src/kernel/spec/surfaceConformance.test.ts +94 -0
  331. package/src/kernel/spec/surfaceConformance.ts +135 -0
  332. package/src/kernel/spec/types.ts +233 -0
  333. package/src/kernel/spec/validate.test.ts +81 -0
  334. package/src/kernel/spec/validate.ts +125 -0
  335. package/src/testing/PARITY_GAPS.test.ts +32 -0
  336. package/src/testing/PARITY_GAPS.ts +179 -0
  337. package/src/testing/behavioral/README.md +164 -0
  338. package/src/testing/behavioral/agentSession.mcp.test.ts +160 -0
  339. package/src/testing/behavioral/autoLlm.e2e.test.ts +54 -0
  340. package/src/testing/behavioral/completion.test.ts +132 -0
  341. package/src/testing/behavioral/disclosure.test.ts +115 -0
  342. package/src/testing/behavioral/docExamples.test.ts +283 -0
  343. package/src/testing/behavioral/errorMatrix.mcp.test.ts +120 -0
  344. package/src/testing/behavioral/errorMatrix.storeless.test.ts +124 -0
  345. package/src/testing/behavioral/exitCodes.e2e.test.ts +53 -0
  346. package/src/testing/behavioral/firstRun.e2e.test.ts +40 -0
  347. package/src/testing/behavioral/harness.foundation.test.ts +136 -0
  348. package/src/testing/behavioral/journeys.cli.test.ts +131 -0
  349. package/src/testing/behavioral/journeys.defaultPack.test.ts +571 -0
  350. package/src/testing/behavioral/journeys.interactiveTty.e2e.test.ts +66 -0
  351. package/src/testing/behavioral/journeys.livePack.e2e.test.ts +129 -0
  352. package/src/testing/behavioral/journeys.mcpLifecycle.mcp.test.ts +176 -0
  353. package/src/testing/behavioral/liveReadSurface.ts +80 -0
  354. package/src/testing/behavioral/mcpServe.e2e.test.ts +21 -0
  355. package/src/testing/behavioral/mcpSurface.test.ts +139 -0
  356. package/src/testing/behavioral/parity.test.ts +224 -0
  357. package/src/testing/behavioral/rootCli.e2e.test.ts +62 -0
  358. package/src/testing/behavioral/staleCommands.test.ts +76 -0
  359. package/src/testing/eval/__snapshots__/eval.test.ts.snap +201 -0
  360. package/src/testing/eval/cases/assembly.ts +195 -0
  361. package/src/testing/eval/cases/effectful.ts +248 -0
  362. package/src/testing/eval/cases/readNouns.ts +235 -0
  363. package/src/testing/eval/cases/stable.ts +163 -0
  364. package/src/testing/eval/eval.test.ts +74 -0
  365. package/src/testing/eval/harness.ts +91 -0
  366. package/src/testing/eval/report.ts +58 -0
  367. package/src/testing/fixtures/blockGraph.ts +112 -0
  368. package/src/testing/fixtures/completionFixture.ts +239 -0
  369. package/src/testing/fixtures/fixtureCapability.ts +331 -0
  370. package/src/testing/fixtures/graph/canonical.ts +184 -0
  371. package/src/testing/fixtures/graph/defaultPack.ts +178 -0
  372. package/src/testing/fixtures/graph/owlExport.ts +95 -0
  373. package/src/testing/fixtures/packs/recipe.ts +78 -0
  374. package/src/testing/helpers/extractSnippets.ts +29 -0
  375. package/src/testing/helpers/fixtureGraph.ts +148 -0
  376. package/src/testing/helpers/golden.ts +45 -0
  377. package/src/testing/helpers/packRuntime.ts +118 -0
  378. package/src/testing/helpers/parity.ts +86 -0
  379. package/src/testing/helpers/projectCli.ts +35 -0
  380. package/src/testing/helpers/projectMcp.ts +145 -0
  381. package/src/testing/helpers/runCli.ts +128 -0
  382. package/src/testing/perf/budgets.test.ts +164 -0
  383. package/src/testing/perf/budgets.ts +37 -0
  384. package/src/testing/perf/globalSetup.ts +30 -0
  385. package/src/testing/perf/measure.ts +97 -0
  386. package/src/testing/setupXdgIsolation.ts +13 -12
  387. package/src/types.ts +42 -0
  388. package/src/bin.test.ts +0 -54
  389. package/src/compile-validation.runner.ts +0 -137
  390. package/src/compile-validation.ts +0 -191
  391. package/src/completions/computeSocketPath.test.ts +0 -26
  392. package/src/completions/computeSocketPath.ts +0 -16
  393. package/src/completions/constants.ts +0 -25
  394. package/src/completions/handleQuery.test.ts +0 -125
  395. package/src/completions/handleQuery.ts +0 -49
  396. package/src/completions/index.ts +0 -14
  397. package/src/completions/queryCompletions.test.ts +0 -105
  398. package/src/completions/queryCompletions.ts +0 -75
  399. package/src/completions/querySocket.test.ts +0 -101
  400. package/src/completions/querySocket.ts +0 -71
  401. package/src/completions/startCompletionsServer.test.ts +0 -74
  402. package/src/completions/startCompletionsServer.ts +0 -75
  403. package/src/completions/startCompletionsServer.unit.test.ts +0 -131
  404. package/src/completions/waitForSocket.test.ts +0 -27
  405. package/src/completions/waitForSocket.ts +0 -27
  406. package/src/config/configExists.ts +0 -14
  407. package/src/config/defaultConfig.test.ts +0 -33
  408. package/src/config/defaultConfig.ts +0 -59
  409. package/src/config/defaults.json +0 -17
  410. package/src/config/findProjectConfigPath.test.ts +0 -53
  411. package/src/config/findProjectConfigPath.ts +0 -36
  412. package/src/config/index.ts +0 -21
  413. package/src/config/mergeConfigFileUpdate.ts +0 -58
  414. package/src/config/parseConfigValues.ts +0 -217
  415. package/src/config/readConfig.test.ts +0 -395
  416. package/src/config/readConfig.ts +0 -21
  417. package/src/config/readConfigLayers.test.ts +0 -109
  418. package/src/config/readConfigLayers.ts +0 -118
  419. package/src/config/resolveConfigPath.test.ts +0 -20
  420. package/src/config/resolveConfigPath.ts +0 -11
  421. package/src/config/resolveGlobalConfigPath.ts +0 -13
  422. package/src/config/resolveWriteConfigPath.test.ts +0 -53
  423. package/src/config/resolveWriteConfigPath.ts +0 -31
  424. package/src/config/types.ts +0 -128
  425. package/src/config/writeConfig.ts +0 -37
  426. package/src/domains/block/blockConfig.ts +0 -97
  427. package/src/domains/block/commands/index.ts +0 -5
  428. package/src/domains/block/commands/list.test.ts +0 -111
  429. package/src/domains/block/commands/list.ts +0 -11
  430. package/src/domains/block/commands/lookup.test.ts +0 -187
  431. package/src/domains/block/commands/lookup.ts +0 -14
  432. package/src/domains/block/commands/sample.ts +0 -56
  433. package/src/domains/block/formatters/index.ts +0 -5
  434. package/src/domains/block/formatters/list.test.ts +0 -107
  435. package/src/domains/block/formatters/list.ts +0 -50
  436. package/src/domains/block/formatters/lookup.test.ts +0 -318
  437. package/src/domains/block/formatters/lookup.ts +0 -149
  438. package/src/domains/block/formatters/sample.ts +0 -21
  439. package/src/domains/block/formatters/types.ts +0 -16
  440. package/src/domains/block/helpers/index.ts +0 -4
  441. package/src/domains/block/helpers/resolveAspects.test.ts +0 -64
  442. package/src/domains/block/helpers/resolveAspects.ts +0 -35
  443. package/src/domains/block/index.ts +0 -25
  444. package/src/domains/block/mcp/index.ts +0 -2
  445. package/src/domains/block/mcp/specs.ts +0 -67
  446. package/src/domains/block/operations/index.ts +0 -5
  447. package/src/domains/block/operations/list.test.ts +0 -80
  448. package/src/domains/block/operations/list.ts +0 -72
  449. package/src/domains/block/operations/lookup.test.ts +0 -129
  450. package/src/domains/block/operations/lookup.ts +0 -446
  451. package/src/domains/block/operations/sample.ts +0 -41
  452. package/src/domains/block/orchestration/blockEmptyError.test.ts +0 -26
  453. package/src/domains/block/orchestration/blockEmptyError.ts +0 -19
  454. package/src/domains/block/orchestration/buildBlockFilters.ts +0 -12
  455. package/src/domains/block/orchestration/enrichBlocks.ts +0 -44
  456. package/src/domains/block/orchestration/index.ts +0 -5
  457. package/src/domains/block/orchestration/resolveBlockList.ts +0 -39
  458. package/src/domains/block/orchestration/resolveBlockLookup.ts +0 -35
  459. package/src/domains/block/stories.test.ts +0 -28
  460. package/src/domains/block/stories.ts +0 -260
  461. package/src/domains/block/types.ts +0 -30
  462. package/src/domains/config/commands/channel.test.ts +0 -128
  463. package/src/domains/config/commands/channel.ts +0 -99
  464. package/src/domains/config/commands/configScope.ts +0 -46
  465. package/src/domains/config/commands/framework.test.ts +0 -119
  466. package/src/domains/config/commands/framework.ts +0 -103
  467. package/src/domains/config/commands/index.ts +0 -6
  468. package/src/domains/config/commands/show.test.ts +0 -61
  469. package/src/domains/config/commands/show.ts +0 -11
  470. package/src/domains/config/commands/tier.test.ts +0 -102
  471. package/src/domains/config/commands/tier.ts +0 -97
  472. package/src/domains/config/commands/trace.test.ts +0 -165
  473. package/src/domains/config/commands/trace.ts +0 -83
  474. package/src/domains/config/formatters/channel.test.ts +0 -70
  475. package/src/domains/config/formatters/channel.ts +0 -37
  476. package/src/domains/config/formatters/framework.ts +0 -37
  477. package/src/domains/config/formatters/index.ts +0 -6
  478. package/src/domains/config/formatters/show.test.ts +0 -153
  479. package/src/domains/config/formatters/show.ts +0 -89
  480. package/src/domains/config/formatters/tier.test.ts +0 -86
  481. package/src/domains/config/formatters/tier.ts +0 -48
  482. package/src/domains/config/formatters/trace.ts +0 -28
  483. package/src/domains/config/index.ts +0 -36
  484. package/src/domains/config/mcp/index.ts +0 -2
  485. package/src/domains/config/mcp/specs.ts +0 -100
  486. package/src/domains/config/operations/index.ts +0 -6
  487. package/src/domains/config/operations/show.test.ts +0 -78
  488. package/src/domains/config/operations/show.ts +0 -48
  489. package/src/domains/config/operations/types.ts +0 -20
  490. package/src/domains/config/operations/validateChannel.test.ts +0 -36
  491. package/src/domains/config/operations/validateChannel.ts +0 -24
  492. package/src/domains/config/operations/validateFramework.ts +0 -24
  493. package/src/domains/config/operations/validateTier.test.ts +0 -65
  494. package/src/domains/config/operations/validateTier.ts +0 -43
  495. package/src/domains/config/stories.ts +0 -42
  496. package/src/domains/config/tasks/index.ts +0 -6
  497. package/src/domains/config/tasks/setChannel.ts +0 -21
  498. package/src/domains/config/tasks/setFramework.ts +0 -21
  499. package/src/domains/config/tasks/setTier.ts +0 -20
  500. package/src/domains/config/tasks/setTrace.ts +0 -20
  501. package/src/domains/config/tasks/writeConfigField.ts +0 -41
  502. package/src/domains/create/generatorPack/bundled.ts +0 -49
  503. package/src/domains/create/generatorPack/compileGeneratorPack.test.ts +0 -159
  504. package/src/domains/create/generatorPack/compileGeneratorPack.ts +0 -312
  505. package/src/domains/create/index.ts +0 -21
  506. package/src/domains/create/mcp/index.ts +0 -2
  507. package/src/domains/create/mcp/specs.ts +0 -13
  508. package/src/domains/create/renderGeneratorUi.test.ts +0 -103
  509. package/src/domains/create/renderGeneratorUi.ts +0 -65
  510. package/src/domains/doctor/commands/doctor.test.ts +0 -75
  511. package/src/domains/doctor/commands/doctor.ts +0 -43
  512. package/src/domains/doctor/commands/index.ts +0 -2
  513. package/src/domains/doctor/formatters/doctor.test.ts +0 -165
  514. package/src/domains/doctor/formatters/doctor.ts +0 -136
  515. package/src/domains/doctor/formatters/index.ts +0 -2
  516. package/src/domains/doctor/index.ts +0 -9
  517. package/src/domains/doctor/mcp/index.ts +0 -2
  518. package/src/domains/doctor/mcp/specs.ts +0 -41
  519. package/src/domains/doctor/operations/checks/checkConfigFile.ts +0 -42
  520. package/src/domains/doctor/operations/checks/checkKeStore.ts +0 -38
  521. package/src/domains/doctor/operations/checks/checkMcpCommands.ts +0 -133
  522. package/src/domains/doctor/operations/checks/checkMcpConfigured.ts +0 -65
  523. package/src/domains/doctor/operations/checks/checkNodeVersion.ts +0 -25
  524. package/src/domains/doctor/operations/checks/checkPackageRefs.ts +0 -76
  525. package/src/domains/doctor/operations/checks/checkPragmaVersion.ts +0 -20
  526. package/src/domains/doctor/operations/checks/checkShellCompletions.ts +0 -42
  527. package/src/domains/doctor/operations/checks/checkSkillsSymlinked.ts +0 -64
  528. package/src/domains/doctor/operations/checks/index.ts +0 -10
  529. package/src/domains/doctor/operations/checks.test.ts +0 -307
  530. package/src/domains/doctor/operations/index.ts +0 -3
  531. package/src/domains/doctor/operations/runChecks.test.ts +0 -176
  532. package/src/domains/doctor/operations/runChecks.ts +0 -78
  533. package/src/domains/doctor/operations/types.ts +0 -42
  534. package/src/domains/graph/commands/index.ts +0 -4
  535. package/src/domains/graph/commands/inspect.test.ts +0 -94
  536. package/src/domains/graph/commands/inspect.ts +0 -63
  537. package/src/domains/graph/commands/query.test.ts +0 -94
  538. package/src/domains/graph/commands/query.ts +0 -60
  539. package/src/domains/graph/formatters/index.ts +0 -4
  540. package/src/domains/graph/formatters/inspect.ts +0 -50
  541. package/src/domains/graph/formatters/query.test.ts +0 -87
  542. package/src/domains/graph/formatters/query.ts +0 -74
  543. package/src/domains/graph/helpers/index.ts +0 -3
  544. package/src/domains/graph/helpers/resolveUri.test.ts +0 -50
  545. package/src/domains/graph/helpers/resolveUri.ts +0 -77
  546. package/src/domains/graph/index.ts +0 -22
  547. package/src/domains/graph/mcp/index.ts +0 -2
  548. package/src/domains/graph/mcp/specs.ts +0 -82
  549. package/src/domains/graph/operations/executeQuery.test.ts +0 -68
  550. package/src/domains/graph/operations/executeQuery.ts +0 -32
  551. package/src/domains/graph/operations/index.ts +0 -4
  552. package/src/domains/graph/operations/inspectUri.test.ts +0 -101
  553. package/src/domains/graph/operations/inspectUri.ts +0 -64
  554. package/src/domains/graphql/commands/build.test.ts +0 -196
  555. package/src/domains/graphql/commands/build.ts +0 -117
  556. package/src/domains/graphql/commands/check.test.ts +0 -141
  557. package/src/domains/graphql/commands/check.ts +0 -81
  558. package/src/domains/graphql/commands/index.ts +0 -5
  559. package/src/domains/graphql/commands/serve.test.ts +0 -46
  560. package/src/domains/graphql/commands/serve.ts +0 -141
  561. package/src/domains/graphql/constants.ts +0 -10
  562. package/src/domains/graphql/formatters/index.ts +0 -3
  563. package/src/domains/graphql/formatters/report.ts +0 -78
  564. package/src/domains/graphql/helpers/gatherSources.test.ts +0 -92
  565. package/src/domains/graphql/helpers/gatherSources.ts +0 -58
  566. package/src/domains/graphql/helpers/index.ts +0 -6
  567. package/src/domains/graphql/helpers/parsePrefixes.test.ts +0 -44
  568. package/src/domains/graphql/helpers/parsePrefixes.ts +0 -38
  569. package/src/domains/graphql/helpers/resolveSourceFiles.test.ts +0 -65
  570. package/src/domains/graphql/helpers/resolveSourceFiles.ts +0 -66
  571. package/src/domains/graphql/helpers/routeGraphql.test.ts +0 -43
  572. package/src/domains/graphql/helpers/routeGraphql.ts +0 -28
  573. package/src/domains/graphql/index.ts +0 -24
  574. package/src/domains/graphql/operations/compileSchema.test.ts +0 -95
  575. package/src/domains/graphql/operations/compileSchema.ts +0 -107
  576. package/src/domains/graphql/operations/createSchemaServer.test.ts +0 -50
  577. package/src/domains/graphql/operations/createSchemaServer.ts +0 -75
  578. package/src/domains/graphql/operations/ensureSchemaArtifact.test.ts +0 -167
  579. package/src/domains/graphql/operations/ensureSchemaArtifact.ts +0 -178
  580. package/src/domains/graphql/operations/index.ts +0 -17
  581. package/src/domains/graphql/types.ts +0 -29
  582. package/src/domains/info/commands/index.ts +0 -4
  583. package/src/domains/info/commands/info.test.ts +0 -88
  584. package/src/domains/info/commands/info.ts +0 -47
  585. package/src/domains/info/commands/upgrade.test.ts +0 -183
  586. package/src/domains/info/commands/upgrade.ts +0 -153
  587. package/src/domains/info/constants.test.ts +0 -22
  588. package/src/domains/info/constants.ts +0 -15
  589. package/src/domains/info/formatters/index.ts +0 -8
  590. package/src/domains/info/formatters/info.test.ts +0 -207
  591. package/src/domains/info/formatters/info.ts +0 -131
  592. package/src/domains/info/formatters/upgrade.test.ts +0 -136
  593. package/src/domains/info/formatters/upgrade.ts +0 -70
  594. package/src/domains/info/index.ts +0 -9
  595. package/src/domains/info/mcp/index.ts +0 -2
  596. package/src/domains/info/mcp/specs.ts +0 -65
  597. package/src/domains/info/operations/checkRegistryVersion.test.ts +0 -124
  598. package/src/domains/info/operations/checkRegistryVersion.ts +0 -45
  599. package/src/domains/info/operations/collectEntityCounts.test.ts +0 -156
  600. package/src/domains/info/operations/collectEntityCounts.ts +0 -123
  601. package/src/domains/info/operations/collectInfo.test.ts +0 -122
  602. package/src/domains/info/operations/collectInfo.ts +0 -94
  603. package/src/domains/info/operations/collectStoreSummary.test.ts +0 -61
  604. package/src/domains/info/operations/collectStoreSummary.ts +0 -42
  605. package/src/domains/info/operations/index.ts +0 -6
  606. package/src/domains/info/types.test-d.ts +0 -35
  607. package/src/domains/info/types.ts +0 -67
  608. package/src/domains/llm/capabilities.test.ts +0 -111
  609. package/src/domains/llm/commands/capabilities.ts +0 -37
  610. package/src/domains/llm/commands/index.ts +0 -4
  611. package/src/domains/llm/commands/llm.ts +0 -41
  612. package/src/domains/llm/data/commandReference.ts +0 -106
  613. package/src/domains/llm/data/decisionTrees.ts +0 -55
  614. package/src/domains/llm/data/index.ts +0 -6
  615. package/src/domains/llm/data/toolCatalog.ts +0 -221
  616. package/src/domains/llm/formatters/capabilities.ts +0 -50
  617. package/src/domains/llm/formatters/index.ts +0 -4
  618. package/src/domains/llm/formatters/orientation.ts +0 -57
  619. package/src/domains/llm/index.ts +0 -9
  620. package/src/domains/llm/llmCommand.test.ts +0 -101
  621. package/src/domains/llm/mcp/index.ts +0 -2
  622. package/src/domains/llm/mcp/specs.ts +0 -93
  623. package/src/domains/llm/operations/collectContext.test.ts +0 -64
  624. package/src/domains/llm/operations/collectContext.ts +0 -37
  625. package/src/domains/llm/operations/index.ts +0 -3
  626. package/src/domains/llm/types.ts +0 -72
  627. package/src/domains/modifier/commands/index.ts +0 -5
  628. package/src/domains/modifier/commands/list.test.ts +0 -57
  629. package/src/domains/modifier/commands/list.ts +0 -9
  630. package/src/domains/modifier/commands/lookup.test.ts +0 -91
  631. package/src/domains/modifier/commands/lookup.ts +0 -14
  632. package/src/domains/modifier/commands/sample.ts +0 -54
  633. package/src/domains/modifier/formatters/index.ts +0 -8
  634. package/src/domains/modifier/formatters/list.test.ts +0 -38
  635. package/src/domains/modifier/formatters/list.ts +0 -22
  636. package/src/domains/modifier/formatters/lookup.test.ts +0 -33
  637. package/src/domains/modifier/formatters/lookup.ts +0 -50
  638. package/src/domains/modifier/formatters/sample.ts +0 -15
  639. package/src/domains/modifier/index.ts +0 -27
  640. package/src/domains/modifier/mcp/index.ts +0 -2
  641. package/src/domains/modifier/mcp/specs.ts +0 -65
  642. package/src/domains/modifier/modifierConfig.ts +0 -36
  643. package/src/domains/modifier/operations/index.ts +0 -5
  644. package/src/domains/modifier/operations/list.test.ts +0 -39
  645. package/src/domains/modifier/operations/list.ts +0 -41
  646. package/src/domains/modifier/operations/lookup.test.ts +0 -37
  647. package/src/domains/modifier/operations/lookup.ts +0 -69
  648. package/src/domains/modifier/operations/sample.ts +0 -32
  649. package/src/domains/modifier/orchestration/index.ts +0 -3
  650. package/src/domains/modifier/orchestration/modifierEmptyError.test.ts +0 -26
  651. package/src/domains/modifier/orchestration/modifierEmptyError.ts +0 -15
  652. package/src/domains/modifier/orchestration/resolveModifierList.ts +0 -16
  653. package/src/domains/modifier/orchestration/resolveModifierLookup.ts +0 -33
  654. package/src/domains/modifier/stories.test.ts +0 -20
  655. package/src/domains/modifier/stories.ts +0 -86
  656. package/src/domains/modifier/types.ts +0 -5
  657. package/src/domains/ontology/commands/index.ts +0 -4
  658. package/src/domains/ontology/commands/list.test.ts +0 -84
  659. package/src/domains/ontology/commands/list.ts +0 -11
  660. package/src/domains/ontology/commands/show.test.ts +0 -179
  661. package/src/domains/ontology/commands/show.ts +0 -14
  662. package/src/domains/ontology/formatters/index.ts +0 -5
  663. package/src/domains/ontology/formatters/list.ts +0 -64
  664. package/src/domains/ontology/formatters/show.ts +0 -396
  665. package/src/domains/ontology/helpers/buildClassTree.ts +0 -89
  666. package/src/domains/ontology/helpers/completeClassNames.ts +0 -43
  667. package/src/domains/ontology/helpers/expandOntologyIris.ts +0 -79
  668. package/src/domains/ontology/helpers/findNamespace.ts +0 -23
  669. package/src/domains/ontology/helpers/index.ts +0 -21
  670. package/src/domains/ontology/helpers/queryClasses.ts +0 -66
  671. package/src/domains/ontology/helpers/queryProperties.ts +0 -90
  672. package/src/domains/ontology/helpers/queryTboxFacts.ts +0 -160
  673. package/src/domains/ontology/helpers/resolvePrefix.ts +0 -45
  674. package/src/domains/ontology/index.ts +0 -26
  675. package/src/domains/ontology/mcp/index.ts +0 -2
  676. package/src/domains/ontology/mcp/specs.ts +0 -16
  677. package/src/domains/ontology/operations/index.ts +0 -5
  678. package/src/domains/ontology/operations/listOntologies.test.ts +0 -122
  679. package/src/domains/ontology/operations/listOntologies.ts +0 -197
  680. package/src/domains/ontology/operations/showOntology.test.ts +0 -184
  681. package/src/domains/ontology/operations/showOntology.ts +0 -323
  682. package/src/domains/ontology/operations/showOntologyRaw.test.ts +0 -41
  683. package/src/domains/ontology/operations/showOntologyRaw.ts +0 -50
  684. package/src/domains/ontology/stories.test.ts +0 -36
  685. package/src/domains/ontology/stories.ts +0 -153
  686. package/src/domains/refs/commands/updateRefs.ts +0 -52
  687. package/src/domains/refs/formatters/updateRefs.ts +0 -27
  688. package/src/domains/refs/index.ts +0 -27
  689. package/src/domains/refs/operations/gitOps.test.ts +0 -155
  690. package/src/domains/refs/operations/gitOps.ts +0 -92
  691. package/src/domains/refs/operations/index.ts +0 -10
  692. package/src/domains/refs/operations/parseRef.test.ts +0 -157
  693. package/src/domains/refs/operations/parseRef.ts +0 -114
  694. package/src/domains/refs/operations/paths.test.ts +0 -98
  695. package/src/domains/refs/operations/paths.ts +0 -91
  696. package/src/domains/refs/operations/readGlobalRefs.test.ts +0 -63
  697. package/src/domains/refs/operations/readGlobalRefs.ts +0 -37
  698. package/src/domains/refs/operations/updateRefs.test.ts +0 -167
  699. package/src/domains/refs/operations/updateRefs.ts +0 -180
  700. package/src/domains/setup/commands/all.ts +0 -58
  701. package/src/domains/setup/commands/completions.ts +0 -85
  702. package/src/domains/setup/commands/entrypoints.test.ts +0 -170
  703. package/src/domains/setup/commands/index.ts +0 -7
  704. package/src/domains/setup/commands/lsp.ts +0 -49
  705. package/src/domains/setup/commands/mcp.ts +0 -119
  706. package/src/domains/setup/commands/setup.ts +0 -70
  707. package/src/domains/setup/commands/skills.test.ts +0 -68
  708. package/src/domains/setup/commands/skills.ts +0 -110
  709. package/src/domains/setup/formatters/index.ts +0 -2
  710. package/src/domains/setup/formatters/skills.test.ts +0 -103
  711. package/src/domains/setup/formatters/skills.ts +0 -112
  712. package/src/domains/setup/formatters/types.ts +0 -7
  713. package/src/domains/setup/helpers/completionScripts.test.ts +0 -58
  714. package/src/domains/setup/helpers/completionScripts.ts +0 -92
  715. package/src/domains/setup/helpers/constants.ts +0 -2
  716. package/src/domains/setup/helpers/detectShell.test.ts +0 -48
  717. package/src/domains/setup/helpers/detectShell.ts +0 -20
  718. package/src/domains/setup/helpers/index.ts +0 -12
  719. package/src/domains/setup/helpers/runSetupTask.test.ts +0 -277
  720. package/src/domains/setup/helpers/runSetupTask.ts +0 -221
  721. package/src/domains/setup/index.ts +0 -37
  722. package/src/domains/setup/operations/index.ts +0 -6
  723. package/src/domains/setup/operations/setupAll.test.ts +0 -48
  724. package/src/domains/setup/operations/setupAll.ts +0 -41
  725. package/src/domains/setup/operations/setupCompletions.test.ts +0 -94
  726. package/src/domains/setup/operations/setupCompletions.ts +0 -54
  727. package/src/domains/setup/operations/setupLsp.test.ts +0 -30
  728. package/src/domains/setup/operations/setupLsp.ts +0 -22
  729. package/src/domains/setup/operations/setupMcp.test.ts +0 -120
  730. package/src/domains/setup/operations/setupMcp.ts +0 -108
  731. package/src/domains/setup/operations/setupSkills.test.ts +0 -191
  732. package/src/domains/setup/operations/setupSkills.ts +0 -160
  733. package/src/domains/setup/types.ts +0 -18
  734. package/src/domains/shared/ToolSpec.ts +0 -49
  735. package/src/domains/shared/bootStore.bareCore.test.ts +0 -63
  736. package/src/domains/shared/bootStore.test.ts +0 -82
  737. package/src/domains/shared/bootStore.ts +0 -171
  738. package/src/domains/shared/buildQuery.ts +0 -18
  739. package/src/domains/shared/compactUri.test.ts +0 -32
  740. package/src/domains/shared/compactUri.ts +0 -21
  741. package/src/domains/shared/context.ts +0 -16
  742. package/src/domains/shared/contracts.ts +0 -164
  743. package/src/domains/shared/createInteractivePromptSession.test.ts +0 -439
  744. package/src/domains/shared/createInteractivePromptSession.ts +0 -236
  745. package/src/domains/shared/emptyErrorRecovery.test.ts +0 -106
  746. package/src/domains/shared/extractLocalName.test.ts +0 -21
  747. package/src/domains/shared/extractLocalName.ts +0 -14
  748. package/src/domains/shared/filters/buildChannelFilter.test.ts +0 -52
  749. package/src/domains/shared/filters/buildChannelFilter.ts +0 -41
  750. package/src/domains/shared/filters/buildFilterConfig.ts +0 -15
  751. package/src/domains/shared/filters/buildFilters.test.ts +0 -33
  752. package/src/domains/shared/filters/buildFilters.ts +0 -30
  753. package/src/domains/shared/filters/buildTierFilter.test.ts +0 -78
  754. package/src/domains/shared/filters/buildTierFilter.ts +0 -69
  755. package/src/domains/shared/filters/describeFilters.ts +0 -14
  756. package/src/domains/shared/filters/index.ts +0 -10
  757. package/src/domains/shared/formatters.ts +0 -103
  758. package/src/domains/shared/listTiers.ts +0 -40
  759. package/src/domains/shared/loaders/bundledLoader.test.ts +0 -248
  760. package/src/domains/shared/loaders/bundledLoader.ts +0 -254
  761. package/src/domains/shared/loaders/gitLoader.ts +0 -30
  762. package/src/domains/shared/loaders/index.ts +0 -9
  763. package/src/domains/shared/loaders/localLoader.ts +0 -71
  764. package/src/domains/shared/loaders/readPackageDir.test.ts +0 -58
  765. package/src/domains/shared/loaders/readPackageDir.ts +0 -185
  766. package/src/domains/shared/loaders/storyAssetsPlugin.test.ts +0 -84
  767. package/src/domains/shared/loaders/storyAssetsPlugin.ts +0 -46
  768. package/src/domains/shared/lookupMany.test.ts +0 -135
  769. package/src/domains/shared/lookupMany.ts +0 -101
  770. package/src/domains/shared/mergeAndParseRefs.test.ts +0 -89
  771. package/src/domains/shared/mergeAndParseRefs.ts +0 -44
  772. package/src/domains/shared/namespaces.ts +0 -26
  773. package/src/domains/shared/packages.ts +0 -20
  774. package/src/domains/shared/parseSampleCount.test.ts +0 -47
  775. package/src/domains/shared/parseSampleCount.ts +0 -45
  776. package/src/domains/shared/pickRandom.ts +0 -22
  777. package/src/domains/shared/prefixes.test.ts +0 -211
  778. package/src/domains/shared/prefixes.ts +0 -204
  779. package/src/domains/shared/renderers.ts +0 -410
  780. package/src/domains/shared/resolveConfiguredGraphs.test.ts +0 -27
  781. package/src/domains/shared/resolveConfiguredGraphs.ts +0 -41
  782. package/src/domains/shared/resolveLookupExitCode.test.ts +0 -48
  783. package/src/domains/shared/resolveLookupExitCode.ts +0 -42
  784. package/src/domains/shared/runtime.ts +0 -61
  785. package/src/domains/shared/sampleFormatters.ts +0 -47
  786. package/src/domains/shared/semanticPackage.test.ts +0 -89
  787. package/src/domains/shared/semanticPackage.ts +0 -127
  788. package/src/domains/shared/stories/compileLookupCommand.test.ts +0 -145
  789. package/src/domains/shared/stories/compileLookupCommand.ts +0 -102
  790. package/src/domains/shared/stories/compileLookupTool.test.ts +0 -105
  791. package/src/domains/shared/stories/compileLookupTool.ts +0 -96
  792. package/src/domains/shared/stories/compileReadCommand.test.ts +0 -121
  793. package/src/domains/shared/stories/compileReadCommand.ts +0 -48
  794. package/src/domains/shared/stories/compileReadTool.test.ts +0 -64
  795. package/src/domains/shared/stories/compileReadTool.ts +0 -38
  796. package/src/domains/shared/stories/condense.test.ts +0 -18
  797. package/src/domains/shared/stories/condense.ts +0 -15
  798. package/src/domains/shared/stories/index.ts +0 -20
  799. package/src/domains/shared/stories/normalizeNames.test.ts +0 -20
  800. package/src/domains/shared/stories/normalizeNames.ts +0 -22
  801. package/src/domains/shared/stories/pack/applyPackFilters.test.ts +0 -151
  802. package/src/domains/shared/stories/pack/applyPackFilters.ts +0 -111
  803. package/src/domains/shared/stories/pack/applyPackSearch.test.ts +0 -57
  804. package/src/domains/shared/stories/pack/applyPackSearch.ts +0 -41
  805. package/src/domains/shared/stories/pack/buildLookupQuery.test.ts +0 -81
  806. package/src/domains/shared/stories/pack/buildLookupQuery.ts +0 -154
  807. package/src/domains/shared/stories/pack/bundled/index.ts +0 -23
  808. package/src/domains/shared/stories/pack/bundled/standardPack.ts +0 -164
  809. package/src/domains/shared/stories/pack/bundled/tierPack.ts +0 -50
  810. package/src/domains/shared/stories/pack/collectPackStories.test.ts +0 -406
  811. package/src/domains/shared/stories/pack/collectPackStories.ts +0 -158
  812. package/src/domains/shared/stories/pack/compilePackCommands.ts +0 -50
  813. package/src/domains/shared/stories/pack/compilePackStories.test.ts +0 -751
  814. package/src/domains/shared/stories/pack/compilePackStories.ts +0 -724
  815. package/src/domains/shared/stories/pack/compilePackToolSpecs.ts +0 -55
  816. package/src/domains/shared/stories/pack/index.ts +0 -42
  817. package/src/domains/shared/stories/pack/reservedVerbs.test.ts +0 -213
  818. package/src/domains/shared/stories/pack/reservedVerbs.ts +0 -170
  819. package/src/domains/shared/stories/pack/runSelectQuery.ts +0 -31
  820. package/src/domains/shared/stories/pack/standardParity.test.ts +0 -381
  821. package/src/domains/shared/stories/pack/types.ts +0 -224
  822. package/src/domains/shared/stories/pack/validateStoryPackDefinition.test.ts +0 -742
  823. package/src/domains/shared/stories/pack/validateStoryPackDefinition.ts +0 -859
  824. package/src/domains/shared/stories/projectCliParameters.test.ts +0 -59
  825. package/src/domains/shared/stories/projectCliParameters.ts +0 -57
  826. package/src/domains/shared/stories/projectToolParams.test.ts +0 -50
  827. package/src/domains/shared/stories/projectToolParams.ts +0 -32
  828. package/src/domains/shared/stories/requirePragmaContext.test.ts +0 -23
  829. package/src/domains/shared/stories/requirePragmaContext.ts +0 -23
  830. package/src/domains/shared/stories/resolveLookupDetailed.test.ts +0 -57
  831. package/src/domains/shared/stories/resolveLookupDetailed.ts +0 -27
  832. package/src/domains/shared/stories/types.ts +0 -179
  833. package/src/domains/shared/suggestions/detectCrossDomain.test.ts +0 -43
  834. package/src/domains/shared/suggestions/detectCrossDomain.ts +0 -116
  835. package/src/domains/shared/suggestions/expandGlob.test.ts +0 -92
  836. package/src/domains/shared/suggestions/expandGlob.ts +0 -52
  837. package/src/domains/shared/suggestions/expandLookupQueries.ts +0 -57
  838. package/src/domains/shared/suggestions/index.ts +0 -7
  839. package/src/domains/shared/suggestions/listDomainNames.ts +0 -61
  840. package/src/domains/shared/suggestions/suggestNames.test.ts +0 -70
  841. package/src/domains/shared/suggestions/suggestNames.ts +0 -130
  842. package/src/domains/shared/types/block.ts +0 -107
  843. package/src/domains/shared/types/common.ts +0 -33
  844. package/src/domains/shared/types/graph.ts +0 -17
  845. package/src/domains/shared/types/index.ts +0 -46
  846. package/src/domains/shared/types/modifier.ts +0 -22
  847. package/src/domains/shared/types/ontology.ts +0 -145
  848. package/src/domains/shared/types/runtime.ts +0 -24
  849. package/src/domains/shared/types/sample.ts +0 -17
  850. package/src/domains/shared/types/standard.ts +0 -21
  851. package/src/domains/shared/types/tier.ts +0 -15
  852. package/src/domains/shared/types/token.ts +0 -30
  853. package/src/domains/skill/commands/index.ts +0 -4
  854. package/src/domains/skill/commands/list.test.ts +0 -115
  855. package/src/domains/skill/commands/list.ts +0 -11
  856. package/src/domains/skill/commands/lookup.test.ts +0 -118
  857. package/src/domains/skill/commands/lookup.ts +0 -14
  858. package/src/domains/skill/formatters/index.ts +0 -3
  859. package/src/domains/skill/formatters/list.test.ts +0 -140
  860. package/src/domains/skill/formatters/list.ts +0 -119
  861. package/src/domains/skill/formatters/lookup.test.ts +0 -46
  862. package/src/domains/skill/formatters/lookup.ts +0 -57
  863. package/src/domains/skill/formatters/types.ts +0 -8
  864. package/src/domains/skill/helpers/index.ts +0 -6
  865. package/src/domains/skill/helpers/parseFrontmatter.test.ts +0 -122
  866. package/src/domains/skill/helpers/parseFrontmatter.ts +0 -112
  867. package/src/domains/skill/helpers/resolveSkillSources.ts +0 -70
  868. package/src/domains/skill/index.ts +0 -23
  869. package/src/domains/skill/mcp/index.ts +0 -2
  870. package/src/domains/skill/mcp/specs.ts +0 -19
  871. package/src/domains/skill/operations/discover.test.ts +0 -176
  872. package/src/domains/skill/operations/discover.ts +0 -59
  873. package/src/domains/skill/operations/index.ts +0 -5
  874. package/src/domains/skill/operations/list.test.ts +0 -76
  875. package/src/domains/skill/operations/list.ts +0 -47
  876. package/src/domains/skill/operations/lookup.test.ts +0 -91
  877. package/src/domains/skill/operations/lookup.ts +0 -70
  878. package/src/domains/skill/stories.test.ts +0 -43
  879. package/src/domains/skill/stories.ts +0 -103
  880. package/src/domains/skill/types.ts +0 -33
  881. package/src/domains/token/commands/add-config.test.ts +0 -68
  882. package/src/domains/token/commands/add-config.ts +0 -62
  883. package/src/domains/token/commands/index.ts +0 -6
  884. package/src/domains/token/commands/list.test.ts +0 -82
  885. package/src/domains/token/commands/list.ts +0 -54
  886. package/src/domains/token/commands/lookup.test.ts +0 -133
  887. package/src/domains/token/commands/lookup.ts +0 -107
  888. package/src/domains/token/commands/sample.ts +0 -54
  889. package/src/domains/token/featureFlag.ts +0 -17
  890. package/src/domains/token/formatters/index.ts +0 -8
  891. package/src/domains/token/formatters/list.test.ts +0 -37
  892. package/src/domains/token/formatters/list.ts +0 -24
  893. package/src/domains/token/formatters/lookup.test.ts +0 -61
  894. package/src/domains/token/formatters/lookup.ts +0 -107
  895. package/src/domains/token/formatters/sample.ts +0 -16
  896. package/src/domains/token/index.ts +0 -45
  897. package/src/domains/token/mcp/index.ts +0 -2
  898. package/src/domains/token/mcp/specs.ts +0 -207
  899. package/src/domains/token/operations/add-config.test.ts +0 -68
  900. package/src/domains/token/operations/add-config.ts +0 -61
  901. package/src/domains/token/operations/index.ts +0 -8
  902. package/src/domains/token/operations/list.test.ts +0 -50
  903. package/src/domains/token/operations/list.ts +0 -52
  904. package/src/domains/token/operations/lookup.test.ts +0 -42
  905. package/src/domains/token/operations/lookup.ts +0 -75
  906. package/src/domains/token/operations/sample.ts +0 -32
  907. package/src/domains/token/orchestration/index.ts +0 -3
  908. package/src/domains/token/orchestration/resolveTokenList.ts +0 -17
  909. package/src/domains/token/orchestration/resolveTokenLookup.ts +0 -33
  910. package/src/domains/token/orchestration/tokenEmptyError.test.ts +0 -33
  911. package/src/domains/token/orchestration/tokenEmptyError.ts +0 -20
  912. package/src/domains/token/tokenConfig.ts +0 -38
  913. package/src/domains/token/types.ts +0 -6
  914. package/src/domains/trace/commands/clear.ts +0 -71
  915. package/src/domains/trace/commands/index.ts +0 -5
  916. package/src/domains/trace/commands/resolveTraceLimit.test.ts +0 -31
  917. package/src/domains/trace/commands/sessions.ts +0 -32
  918. package/src/domains/trace/commands/show.ts +0 -171
  919. package/src/domains/trace/formatters/index.ts +0 -9
  920. package/src/domains/trace/formatters/sessions.ts +0 -80
  921. package/src/domains/trace/formatters/show.ts +0 -122
  922. package/src/domains/trace/index.ts +0 -17
  923. package/src/domains/trace/operations/index.ts +0 -8
  924. package/src/domains/trace/operations/listSessions.test.ts +0 -55
  925. package/src/domains/trace/operations/listSessions.ts +0 -52
  926. package/src/domains/trace/operations/readTraceLog.test.ts +0 -100
  927. package/src/domains/trace/operations/readTraceLog.ts +0 -104
  928. package/src/domains/trace/tracePlugin.test.ts +0 -171
  929. package/src/domains/trace/tracePlugin.ts +0 -159
  930. package/src/domains/trace/types.ts +0 -65
  931. package/src/embedWasm.ts +0 -42
  932. package/src/error/PragmaError.test.ts +0 -121
  933. package/src/error/PragmaError.ts +0 -177
  934. package/src/error/constants.ts +0 -12
  935. package/src/error/index.ts +0 -4
  936. package/src/error/types.ts +0 -55
  937. package/src/mcp/createMcpServer.test.ts +0 -41
  938. package/src/mcp/createMcpServer.ts +0 -53
  939. package/src/mcp/error/buildRecovery.test.ts +0 -37
  940. package/src/mcp/error/buildRecovery.ts +0 -17
  941. package/src/mcp/error/index.ts +0 -12
  942. package/src/mcp/error/serializeError.test.ts +0 -121
  943. package/src/mcp/error/serializeError.ts +0 -31
  944. package/src/mcp/error/serializeErrorPayload.test.ts +0 -38
  945. package/src/mcp/error/serializeErrorPayload.ts +0 -34
  946. package/src/mcp/error/types.ts +0 -59
  947. package/src/mcp/index.ts +0 -15
  948. package/src/mcp/registerResources.test.ts +0 -566
  949. package/src/mcp/registerResources.ts +0 -9
  950. package/src/mcp/resources/buildGraphIndex.ts +0 -167
  951. package/src/mcp/resources/buildResourceList.test.ts +0 -97
  952. package/src/mcp/resources/buildResourceList.ts +0 -176
  953. package/src/mcp/resources/classifyEntity.test.ts +0 -40
  954. package/src/mcp/resources/classifyEntity.ts +0 -27
  955. package/src/mcp/resources/constants.ts +0 -105
  956. package/src/mcp/resources/displayPredicates.ts +0 -62
  957. package/src/mcp/resources/pickFirstValue.test.ts +0 -29
  958. package/src/mcp/resources/pickFirstValue.ts +0 -26
  959. package/src/mcp/resources/pickPrimaryType.test.ts +0 -41
  960. package/src/mcp/resources/pickPrimaryType.ts +0 -26
  961. package/src/mcp/resources/rankUriCompletions.test.ts +0 -52
  962. package/src/mcp/resources/rankUriCompletions.ts +0 -64
  963. package/src/mcp/resources/readEntity.ts +0 -169
  964. package/src/mcp/resources/registerResources.ts +0 -126
  965. package/src/mcp/resources/types.ts +0 -128
  966. package/src/mcp/runMcpServer.test.ts +0 -66
  967. package/src/mcp/runMcpServer.ts +0 -24
  968. package/src/mcp/tools/index.ts +0 -74
  969. package/src/mcp/tools/registerFromSpec.ts +0 -97
  970. package/src/mcp/tools/registerTools.test.ts +0 -1277
  971. package/src/mcp/types.ts +0 -66
  972. package/src/mcp/utils/estimateTokens.test.ts +0 -14
  973. package/src/mcp/utils/estimateTokens.ts +0 -9
  974. package/src/mcp/utils/index.ts +0 -11
  975. package/src/mcp/utils/wrapTool.test.ts +0 -109
  976. package/src/mcp/utils/wrapTool.ts +0 -81
  977. package/src/package-manager/constants.ts +0 -29
  978. package/src/package-manager/detectInstallSource.test.ts +0 -23
  979. package/src/package-manager/detectInstallSource.ts +0 -111
  980. package/src/package-manager/detectLocalInstall.test.ts +0 -16
  981. package/src/package-manager/detectLocalInstall.ts +0 -43
  982. package/src/package-manager/detectPackageManager.test.ts +0 -81
  983. package/src/package-manager/detectPackageManager.ts +0 -30
  984. package/src/package-manager/index.ts +0 -6
  985. package/src/package-manager/types.ts +0 -10
  986. package/src/pipeline/collectCommands.test.ts +0 -187
  987. package/src/pipeline/collectCommands.ts +0 -75
  988. package/src/pipeline/constants.ts +0 -14
  989. package/src/pipeline/createProgram.test.ts +0 -116
  990. package/src/pipeline/createProgram.ts +0 -89
  991. package/src/pipeline/firstRun.test.ts +0 -80
  992. package/src/pipeline/firstRun.ts +0 -99
  993. package/src/pipeline/formatTerminal.test.ts +0 -43
  994. package/src/pipeline/formatTerminal.ts +0 -53
  995. package/src/pipeline/index.ts +0 -22
  996. package/src/pipeline/mapExitCode.test.ts +0 -41
  997. package/src/pipeline/mapExitCode.ts +0 -12
  998. package/src/pipeline/parseGlobalFlags.test.ts +0 -193
  999. package/src/pipeline/parseGlobalFlags.ts +0 -135
  1000. package/src/pipeline/renderError.test.ts +0 -151
  1001. package/src/pipeline/renderError.ts +0 -129
  1002. package/src/pipeline/resolveCommandKind.test.ts +0 -80
  1003. package/src/pipeline/resolveCommandKind.ts +0 -82
  1004. package/src/pipeline/rootHelp.test.ts +0 -87
  1005. package/src/pipeline/rootHelp.ts +0 -265
  1006. package/src/pipeline/runCli.orchestration.test.ts +0 -435
  1007. package/src/pipeline/runCli.test.ts +0 -83
  1008. package/src/pipeline/runCli.ts +0 -411
  1009. package/src/pipeline/types.ts +0 -17
  1010. package/src/testing/cli.ts +0 -71
  1011. package/src/testing/createTestMcpClient.ts +0 -68
  1012. package/src/testing/dsFixtures.ts +0 -523
  1013. package/src/testing/fixtures/canonical-config.json +0 -4
  1014. package/src/testing/fixtures/canonical.ttl +0 -437
  1015. package/src/testing/fixtures/filtered-config.json +0 -4
  1016. package/src/testing/fixtures.ts +0 -34
  1017. package/src/testing/graphqlFixtures.ts +0 -72
  1018. package/src/testing/helpers/assertParity.ts +0 -28
  1019. package/src/testing/helpers/createTestMcpClient.ts +0 -40
  1020. package/src/testing/helpers/createTestRuntime.ts +0 -67
  1021. package/src/testing/index.ts +0 -22
  1022. package/src/testing/integration/__snapshots__/executor-golden.test.ts.snap +0 -1207
  1023. package/src/testing/integration/agent-session.test.ts +0 -148
  1024. package/src/testing/integration/boot.test.ts +0 -105
  1025. package/src/testing/integration/cli-user-stories.test.ts +0 -261
  1026. package/src/testing/integration/cross-binary-byte-equality.test.ts +0 -129
  1027. package/src/testing/integration/edge-cases.test.ts +0 -275
  1028. package/src/testing/integration/executor-execution.test.ts +0 -103
  1029. package/src/testing/integration/executor-golden.test.ts +0 -145
  1030. package/src/testing/integration/mcp-surface.test.ts +0 -605
  1031. package/src/testing/integration/parity.test.ts +0 -596
  1032. package/src/testing/regression/0001-skill-discovery-granularity.test.ts +0 -71
  1033. package/src/testing/standardParityFixtures.ts +0 -35
  1034. package/src/testing/store.ts +0 -39
  1035. package/src/testing/storyFixtures.ts +0 -63
  1036. package/src/testing/types.ts +0 -20
  1037. package/src/tui/components/BulletList/BulletList.tsx +0 -46
  1038. package/src/tui/components/BulletList/index.ts +0 -2
  1039. package/src/tui/components/BulletList/types.ts +0 -6
  1040. package/src/tui/components/Card/Card.tsx +0 -73
  1041. package/src/tui/components/Card/index.ts +0 -1
  1042. package/src/tui/components/Card/types.ts +0 -12
  1043. package/src/tui/components/CodeBlock/CodeBlock.tsx +0 -37
  1044. package/src/tui/components/CodeBlock/index.ts +0 -2
  1045. package/src/tui/components/CodeBlock/types.ts +0 -6
  1046. package/src/tui/components/DataRow/DataRow.tsx +0 -80
  1047. package/src/tui/components/DataRow/index.ts +0 -2
  1048. package/src/tui/components/DataRow/types.ts +0 -14
  1049. package/src/tui/components/FieldRow/FieldRow.tsx +0 -24
  1050. package/src/tui/components/FieldRow/index.ts +0 -2
  1051. package/src/tui/components/FieldRow/types.ts +0 -10
  1052. package/src/tui/components/HeaderRow/HeaderRow.tsx +0 -32
  1053. package/src/tui/components/HeaderRow/index.ts +0 -2
  1054. package/src/tui/components/HeaderRow/types.ts +0 -8
  1055. package/src/tui/components/MarkdownText/MarkdownText.tsx +0 -19
  1056. package/src/tui/components/MarkdownText/index.ts +0 -2
  1057. package/src/tui/components/MarkdownText/types.ts +0 -4
  1058. package/src/tui/components/MiniTable/MiniTable.tsx +0 -82
  1059. package/src/tui/components/MiniTable/index.ts +0 -2
  1060. package/src/tui/components/MiniTable/types.ts +0 -6
  1061. package/src/tui/components/SectionRenderer/SectionRenderer.tsx +0 -91
  1062. package/src/tui/components/SectionRenderer/index.ts +0 -2
  1063. package/src/tui/components/SectionRenderer/types.ts +0 -15
  1064. package/src/tui/components/TreeView/TreeView.tsx +0 -84
  1065. package/src/tui/components/TreeView/index.ts +0 -2
  1066. package/src/tui/components/TreeView/types.ts +0 -6
  1067. package/src/tui/components/index.ts +0 -19
  1068. package/src/tui/constants.ts +0 -39
  1069. package/src/tui/createListView.ts +0 -23
  1070. package/src/tui/createLookupView.ts +0 -26
  1071. package/src/tui/helpers/computeWidths.ts +0 -53
  1072. package/src/tui/helpers/fitColumns.ts +0 -33
  1073. package/src/tui/helpers/formatMarkdown.ts +0 -19
  1074. package/src/tui/helpers/getTerminalSize.ts +0 -16
  1075. package/src/tui/helpers/index.ts +0 -6
  1076. package/src/tui/helpers/syntaxColor.ts +0 -67
  1077. package/src/tui/helpers/truncateText.ts +0 -12
  1078. package/src/tui/hooks/index.ts +0 -3
  1079. package/src/tui/hooks/types.ts +0 -7
  1080. package/src/tui/hooks/useAutoExit.ts +0 -17
  1081. package/src/tui/hooks/useTerminalSize.ts +0 -19
  1082. package/src/tui/index.ts +0 -15
  1083. package/src/tui/renderInk.tsx +0 -18
  1084. package/src/tui/types.ts +0 -12
  1085. package/src/tui/views/ListView/ListView.tsx +0 -104
  1086. package/src/tui/views/ListView/index.ts +0 -2
  1087. package/src/tui/views/ListView/types.ts +0 -14
  1088. package/src/tui/views/LookupView/LookupView.tsx +0 -244
  1089. package/src/tui/views/LookupView/index.ts +0 -2
  1090. package/src/tui/views/LookupView/types.ts +0 -16
  1091. package/src/tui/views/index.ts +0 -4
@@ -0,0 +1,111 @@
1
+ /**
2
+ * The generator→grammar adapter: map a summon {@link PromptDefinition} onto the
3
+ * one grammar's {@link ParamSpec}, mirroring the v1 cli-core
4
+ * `convertGenerator.promptToParameter`.
5
+ *
6
+ * text → { kind: "string" } (+ positional; `complete: files` for paths)
7
+ * confirm → { kind: "boolean" }
8
+ * select → { kind: "enum", values: choices.map(value) }
9
+ * multiselect → { kind: "string[]", complete: values }
10
+ *
11
+ * `name→name`, `message→doc`, `default→default`, `positional→positional`;
12
+ * `required = default === undefined && !when`. A prompt's `validate` and a
13
+ * `select`'s choice set have NO ParamSpec slot: they are enforced by summon's
14
+ * `validateAnswers` inside `execute`, so a flag/MCP-arg run rejects the same bad
15
+ * input a wizard would. A `when` condition is honoured by `collectAnswers` at
16
+ * prompt time. `generate` is reached through the verb's `run` → `execute`.
17
+ *
18
+ * This adapter runs over STATIC prompt mirrors (see `create.verb.ts`), never the
19
+ * live generators — importing a generator runs a top-level `await loadTemplate`,
20
+ * which must stay behind `create`'s lazy dispatch (R9). A parity test loads the
21
+ * real generators and asserts the mirrors match.
22
+ */
23
+
24
+ import type { PromptDefinition } from "@canonical/summon-core";
25
+ import type { ParamSpec } from "../../kernel/spec/types.js";
26
+
27
+ /** A path-like text prompt gets file completion. */
28
+ const looksLikePath = (name: string): boolean => /(path|dir)$/i.test(name);
29
+
30
+ /**
31
+ * Derive a declarative param `doc` from a generator prompt's `message`.
32
+ *
33
+ * A prompt `message` is a wizard QUESTION (`Include styles?`, `Package name:`),
34
+ * but a {@link ParamSpec.doc} is help text shown in CLI `--help` and the MCP
35
+ * arg schema, where every other param reads as a declarative statement. We
36
+ * DERIVE the doc rather than editing the mirrors' `message` — the generator
37
+ * parity test couples `message` to the live generators, so the question must
38
+ * stay verbatim for the interactive wizard while the flag/MCP doc reads well.
39
+ * Strip the trailing `?`/`:` and end with a period.
40
+ */
41
+ export function declarativeDoc(message: string): string {
42
+ const trimmed = message
43
+ .trim()
44
+ .replace(/\s*[?:]+$/, "")
45
+ .trim();
46
+ if (trimmed === "") return trimmed;
47
+ return /[.!]$/.test(trimmed) ? trimmed : `${trimmed}.`;
48
+ }
49
+
50
+ /**
51
+ * Convert one generator prompt to a grammar param.
52
+ *
53
+ * @param prompt - The generator's prompt definition.
54
+ * @returns The equivalent {@link ParamSpec}.
55
+ */
56
+ export function promptToParam(prompt: PromptDefinition): ParamSpec {
57
+ const required = prompt.default === undefined && !prompt.when;
58
+ const positional = prompt.positional === true;
59
+
60
+ switch (prompt.type) {
61
+ case "confirm":
62
+ return {
63
+ kind: "boolean",
64
+ name: prompt.name,
65
+ doc: declarativeDoc(prompt.message),
66
+ required,
67
+ positional,
68
+ ...(prompt.default !== undefined
69
+ ? { default: prompt.default as boolean }
70
+ : {}),
71
+ };
72
+ case "select":
73
+ return {
74
+ kind: "enum",
75
+ name: prompt.name,
76
+ doc: declarativeDoc(prompt.message),
77
+ values: (prompt.choices ?? []).map((choice) => choice.value),
78
+ required,
79
+ positional,
80
+ ...(prompt.default !== undefined
81
+ ? { default: String(prompt.default) }
82
+ : {}),
83
+ };
84
+ case "multiselect":
85
+ return {
86
+ kind: "string[]",
87
+ name: prompt.name,
88
+ doc: declarativeDoc(prompt.message),
89
+ required,
90
+ positional,
91
+ complete: { kind: "values" },
92
+ };
93
+ default:
94
+ return {
95
+ kind: "string",
96
+ name: prompt.name,
97
+ doc: declarativeDoc(prompt.message),
98
+ required,
99
+ positional,
100
+ ...(prompt.default !== undefined ? { default: prompt.default } : {}),
101
+ ...(looksLikePath(prompt.name) ? { complete: { kind: "files" } } : {}),
102
+ };
103
+ }
104
+ }
105
+
106
+ /** Map a generator's whole prompt list to grammar params, in order. */
107
+ export function generatorToParams(
108
+ prompts: readonly PromptDefinition[],
109
+ ): ParamSpec[] {
110
+ return prompts.map(promptToParam);
111
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The `create` capability barrel — component / package / application scaffolds.
3
+ *
4
+ * Importing this pulls only the verb specs (static params + formatters); every
5
+ * generator load and the summon-core runtime stay behind each verb's lazy
6
+ * `run` dispatch, so the command tree builds without touching summon-core.
7
+ */
8
+
9
+ import { asVerb } from "../../kernel/spec/asVerb.js";
10
+ import type { CapabilityModule } from "../../kernel/spec/types.js";
11
+ import {
12
+ createApplicationVerb,
13
+ createComponentVerb,
14
+ createPackageVerb,
15
+ } from "./create.verb.js";
16
+
17
+ /** The `create` capability module. */
18
+ export const createModule: CapabilityModule = {
19
+ name: "create",
20
+ verbs: [
21
+ asVerb(createComponentVerb),
22
+ asVerb(createPackageVerb),
23
+ asVerb(createApplicationVerb),
24
+ ],
25
+ };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * SEC-2 path jail: an independent guard that a `create` output path stays inside
3
+ * the workspace, run BEFORE any effect. It rejects an absolute path, a `..`
4
+ * escape, and — via `realpath` on the nearest existing ancestor — a symlink that
5
+ * points out of the tree. This is defence in depth: the generators' own
6
+ * `validateComponentPath` already rejects absolute/`..`, but the jail is the
7
+ * kernel-level backstop that also catches symlink escapes and covers every
8
+ * create noun uniformly.
9
+ */
10
+
11
+ import { existsSync, realpathSync } from "node:fs";
12
+ import * as path from "node:path";
13
+ import { PragmaError } from "../../kernel/error/PragmaError.js";
14
+
15
+ /** Walk up from `p` to the nearest ancestor that exists on disk. */
16
+ function nearestExisting(p: string): string {
17
+ let current = p;
18
+ while (!existsSync(current)) {
19
+ const parent = path.dirname(current);
20
+ if (parent === current) return current; // filesystem root
21
+ current = parent;
22
+ }
23
+ return current;
24
+ }
25
+
26
+ /** Whether `rel` (a `path.relative` result) points at or above its base. */
27
+ const escapes = (rel: string): boolean =>
28
+ rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel);
29
+
30
+ /**
31
+ * Reject a create output path that would escape the workspace root (`cwd`).
32
+ *
33
+ * @param field - The param name being jailed (for the error message).
34
+ * @param value - The path value (skipped when absent — the generator's own safe
35
+ * default is used instead).
36
+ * @param cwd - The workspace root the path must stay within.
37
+ * @throws PragmaError INVALID_INPUT when the path escapes the workspace.
38
+ * @note Impure — reads the filesystem (`existsSync`/`realpathSync`).
39
+ */
40
+ export function assertInsideWorkspace(
41
+ field: string,
42
+ value: unknown,
43
+ cwd: string,
44
+ ): void {
45
+ if (typeof value !== "string" || value === "") return;
46
+
47
+ if (path.isAbsolute(value)) {
48
+ throw PragmaError.invalidInput(field, value, {
49
+ recovery: { message: "Use a path relative to the current directory." },
50
+ });
51
+ }
52
+
53
+ const root = path.resolve(cwd);
54
+ const resolved = path.resolve(root, value);
55
+ if (escapes(path.relative(root, resolved))) {
56
+ throw PragmaError.invalidInput(field, value, {
57
+ recovery: { message: "The path must stay inside the workspace." },
58
+ });
59
+ }
60
+
61
+ // Symlink escape: the nearest existing ancestor, resolved through symlinks,
62
+ // must still sit within the resolved workspace root.
63
+ const realRoot = realpathSync(root);
64
+ const realAncestor = realpathSync(nearestExisting(resolved));
65
+ if (
66
+ realAncestor !== realRoot &&
67
+ escapes(path.relative(realRoot, realAncestor))
68
+ ) {
69
+ throw PragmaError.invalidInput(field, value, {
70
+ recovery: { message: "The path resolves outside the workspace." },
71
+ });
72
+ }
73
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Select the summon generator for a `create` invocation.
3
+ *
4
+ * This module statically imports the summon generator packages' `generators`
5
+ * maps — and importing them runs a top-level `await loadTemplate` that reads
6
+ * every template file from disk. So this module MUST stay behind `create`'s
7
+ * lazy `import()` (R9): the fast paths (`buildProgram` / `__complete` / `--help`
8
+ * / reads) never load it, and `create --yes` never loads React either (the
9
+ * generators pull summon-core, whose Ink UI is dynamic-only).
10
+ */
11
+
12
+ import { generators as applicationGenerators } from "@canonical/summon-application";
13
+ import { generators as componentGenerators } from "@canonical/summon-component";
14
+ import type { GeneratorDefinition } from "@canonical/summon-core";
15
+ import { generators as packageGenerators } from "@canonical/summon-package";
16
+ import { PragmaError } from "../../kernel/error/PragmaError.js";
17
+ import type { CreateKind } from "./types.js";
18
+
19
+ /** The component frameworks that collapse to one `create component` verb. */
20
+ export const FRAMEWORKS = ["react", "svelte", "lit"] as const;
21
+
22
+ /**
23
+ * The generators' `generate` is invariant in its (specific) answer type, so the
24
+ * strongly-typed maps are erased to the base definition via `unknown`. This is
25
+ * runtime-safe: `execute` calls `generate(answers)` with the resolved answers,
26
+ * which carry the fields the specific generator reads.
27
+ */
28
+ type GeneratorMap = Record<string, GeneratorDefinition | undefined>;
29
+ const componentMap = componentGenerators as unknown as GeneratorMap;
30
+ const packageMap = packageGenerators as unknown as GeneratorMap;
31
+ const applicationMap = applicationGenerators as unknown as GeneratorMap;
32
+
33
+ /**
34
+ * Pick the generator for a `create <kind>` run.
35
+ *
36
+ * @param kind - The create noun.
37
+ * @param params - The coerced params (used for `--framework` on `component`).
38
+ * @returns The selected generator definition.
39
+ * @throws PragmaError INVALID_INPUT for an unknown component framework.
40
+ */
41
+ export function pickGenerator(
42
+ kind: CreateKind,
43
+ params: Readonly<Record<string, unknown>>,
44
+ ): GeneratorDefinition {
45
+ if (kind === "component") {
46
+ const framework = String(params.framework ?? "react");
47
+ const generator = componentMap[`component/${framework}`];
48
+ if (!generator) {
49
+ throw PragmaError.invalidInput("framework", framework, {
50
+ validOptions: [...FRAMEWORKS],
51
+ });
52
+ }
53
+ return generator;
54
+ }
55
+ const generator =
56
+ kind === "package"
57
+ ? packageMap.package
58
+ : applicationMap["application/react"];
59
+ if (!generator) {
60
+ throw PragmaError.internalError(`missing ${kind} generator`);
61
+ }
62
+ return generator;
63
+ }
@@ -0,0 +1,53 @@
1
+ // AUTO-GENERATED by scripts/build.ts — do not edit by hand.
2
+ // Regenerate: `bun run scripts/build.ts`. Inlines the summon generators' .ejs
3
+ // templates as strings so `pragma create` works from the standalone --compile
4
+ // binary (the .ejs files are absent from the binary's virtual filesystem).
5
+ /** Directory-qualified template path → file contents. */
6
+ export const TEMPLATES: Record<string, string> = {
7
+ "application/.storybook/main.ts.ejs": "import { createConfig } from \"@canonical/storybook-config\";\n\nexport default createConfig(\"react\", {\n staticDirs: [\"../src/assets\", \"../public\"],\n<% if (relay) { -%>\n // Wraps stories that declare `parameters.relay` in a relay-test-utils mock\n // environment, so components using Relay hooks render without a server.\n extraAddons: [\"@canonical/storybook-addon-relay\"],\n<% } -%>\n});\n",
8
+ "application/README.md.ejs": "# <%= name %>\n\nA React application with server-side rendering and routing, generated by\n`@canonical/summon`. It is built on Canonical's shared design system, router, and\nSSR packages, and ships SSR on two runtimes (Bun and Node), file-based routing, a\ncomponent library wired to design tokens, and Storybook.\n\n## Quick start\n\n```bash\nbun install\nbun run dev:bun # SSR dev server with HMR, on http://localhost:5174\n```\n\nEdit anything under `src/` and the page hot-reloads. To check the production\nbuild before shipping, run `bun run preview:bun` instead.\n\n## Running the app\n\nThe server scripts form a **2×3 matrix** — two modes (development and preview)\nacross three targets (a client-only SPA, SSR on Bun, SSR on Node/Express):\n\n| | `dev` — transform, HMR | `preview` — compiled, production-faithful |\n| ---------------- | ---------------------- | ----------------------------------------- |\n| **SPA** (no SSR) | `bun run dev` | `bun run preview` |\n| **SSR · Bun** | `bun run dev:bun` | `bun run preview:bun` |\n| **SSR · Node** | `bun run dev:express` | `bun run preview:express` |\n\nThe naming is systematic: the bare name is the **SPA**, the `:bun` / `:express`\nsuffix selects the **SSR runtime**, and the `dev` / `preview` prefix selects the\n**mode**. Reach for `dev:*` while building — it is the fast inner loop, with HMR\nand no build step — and for `preview:*` when verifying that the production bundle\nbehaves before a deploy: `preview:*` builds the client and runs a compiled\nrenderer over the built assets, the same artifact that deploys.\n\n```bash\nbun run storybook # component workshop\n```\n<% if (relay) { -%>\n\nRelay's compiler artifacts are committed, not rebuilt on the fly:\n\n```bash\nbun run relay # regenerate src/relay/__generated__ after schema/query edits\nbun run relay:watch # the same, re-running on change — pair with dev:*\n```\n<% } -%>\n\n## Adding routes\n\n`summon` scaffolds the building blocks of the app so new features follow the\nestablished structure rather than diverging from it.\n\n```bash\nsummon domain billing # a new feature domain (routes + pages)\nsummon route billing/invoices # a route within a domain\nsummon wrapper sidebar # a layout wrapper\n```\n\n## Testing\n\n```bash\nbun run test # unit + component tests (Vitest, jsdom)\nbun run test:coverage # the same, with a coverage report\nbun run test:e2e # boots all six matrix servers and asserts each serves\n```\n\n`test:e2e` is an end-to-end test *of the build*: it runs each of the six server\nscripts — including the production builds that `preview:*` performs — and asserts\nthat every server returns a rendered document and serves its client assets with\nthe correct content type.\n\n## Project structure\n\n```\nsrc/\n├── client/ Client entry (hydration)\n├── server/ Server entry, compiled renderer, dev servers, sitemap\n├── domains/ Feature domains (each owns its routes and pages)\n├── lib/ Shared components\n<% if (relay) { -%>\n├── relay/ Relay environment factory, executable mock schema,\n│ and generated artifacts (__generated__/)\n<% } -%>\n├── styles/ Application CSS\n├── assets/ Assets imported in code (bundled and hashed by Vite)\n└── routes.tsx Root route map\npublic/ Files served verbatim at a fixed URL (favicon, robots.txt)\ntest/e2e/ The 2×3 server-matrix end-to-end suite\n```\n\nDomains are the unit of feature organisation: each owns its routes and pages, so\nadding a feature is adding a domain rather than threading changes through shared\nfiles. This app ships both `src/assets/` (assets imported in code) and `public/`\n(files served by fixed URL); either may be removed if the app uses only one.\n<% if (relay) { -%>\n\n## Data layer (Relay)\n\nThe `catalog` domain demonstrates the app's [Relay](https://relay.dev) data\nlayer: `ProductList` fetches a page of products with `useLazyLoadQuery`, and\neach `ProductCard` reads its own colocated `useFragment` — the component owns\nits field selection, the parent query just spreads it.\n\n**By default the app needs no backend.** `createEnvironment`\n(`src/relay/environment.ts`) resolves every GraphQL operation in-process\nagainst an executable mock schema (`src/relay/schema.ts`, built from the SDL\nin `src/relay/schema.graphql`) backed by a small deterministic catalog. Set\n`VITE_GRAPHQL_URL` (or pass `graphqlUrl` to `createEnvironment`) to switch the\nenvironment to posting operations to a real GraphQL endpoint instead — no code\nchanges needed.\n\n**Generated artifacts are committed.** The Vite plugin runs with\n`codegen: false`, so `src/relay/__generated__/` is not rebuilt on the fly:\nafter editing a `graphql` tag or the schema, run `bun run relay` (or keep\n`bun run relay:watch` running) to regenerate the artifacts, and commit them.\n\n**SSR ships no data yet.** `useLazyLoadQuery` fetches (and suspends) while\nrendering, and the server cannot serialize the fetched store for the client\nyet, so the catalog page wraps its query subtree in `ClientOnly`\n(`src/lib/ClientOnly/`): the server streams the fallback and the browser\nfetches after hydration.\n\n<% if (standalone) { -%>\n**Patched dependencies.** `patches/` carries three package patches applied via\n`patchedDependencies` in `package.json` (a bun feature — with another package\nmanager, apply the equivalent mechanism): `react-relay@21.0.1` needs a\ncjs-module-lexer export hint so named imports survive Node SSR,\n`relay-runtime@21.0.1` needs real runtime bindings for type-only names its\ncompiler artifacts import as values (`ConcreteRequest`, `ReaderFragment`,\n`FragmentRefs`), and `relay-runtime-network@0.1.0` ships a broken `imports`\nmap. The last patch is temporary until the fixed upstream release lands\n([advl/lit-relay#32](https://github.com/advl/lit-relay/pull/32)); drop it and\nits `patchedDependencies` entry once a fixed version is published.\n<% } else { -%>\n**Patched dependencies.** This app was scaffolded inside a bun workspace, so\ndependency patching is owned by the workspace root — bun resolves\n`patchedDependencies` paths from the root, which is why the scaffold emitted\nno app-local `patches/` directory or `patchedDependencies` block. The root's\n`patches/` must carry the `react-relay@21.0.1`, `relay-runtime@21.0.1` and\n`relay-runtime-network@0.1.0` patches (named imports under Node SSR, runtime\nbindings for type-only artifact imports, and a broken `imports` map,\nrespectively).\n<% } -%>\n\n**Not yet on npm.** `@canonical/storybook-addon-relay` and the fixed\n`relay-runtime-network` release have not been published yet, so a fresh\ninstall of this app will not fully resolve until they land on npm.\n<% } -%>\n",
9
+ "application/biome.json.ejs": "{\n \"extends\": [\"@canonical/biome-config\"],\n \"files\": {\n \"includes\": [\"src\", \"*.json\", \"vite.config.ts\"<% if (relay) { %>, \"!src/relay/__generated__\"<% } %>]\n }\n}\n",
10
+ "application/index.html.ejs": "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <meta name=\"description\" content=\"<%= name %> — a React application built with the Canonical design system, router, and SSR packages.\" />\n <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"https://assets.ubuntu.com/v1/be7e4cc6-COF-favicon-32x32.png\">\n <title><%= name %></title>\n </head>\n <body>\n <div id=\"root\"></div>\n <script type=\"module\" src=\"/src/client/entry.tsx\"></script>\n </body>\n</html>\n",
11
+ "application/package.json.ejs": "{\n \"name\": \"<%= name %>\",\n \"private\": true,\n \"version\": \"0.0.0\",\n \"type\": \"module\",\n \"license\": \"GPL-3.0-only\",\n \"imports\": {\n \"#lib/*\": \"./src/lib/*\",\n \"#domains/*\": \"./src/domains/*\",\n<% if (relay) { -%>\n \"#relay/*\": \"./src/relay/*\",\n<% } -%>\n \"#styles/*\": \"./src/styles/*\"\n },\n \"scripts\": {\n \"dev\": \"vite\",\n \"dev:express\": \"node --import tsx src/server/server.express.ts\",\n \"dev:bun\": \"bun src/server/server.bun.ts\",\n \"preview\": \"bun run build:client && vite preview --outDir dist/client\",\n \"preview:bun\": \"bun run build:client && bun run build:server && bun src/server/preview.bun.ts\",\n \"preview:express\": \"bun run build:client && bun run build:server && node --import tsx src/server/preview.express.ts\",\n \"build\": \"bun run build:client\",\n \"build:all\": \"bun run build:client && bun run build:storybook\",\n \"build:client\": \"vite build --ssrManifest --outDir dist/client\",\n \"build:server\": \"vite build --mode server\",\n \"build:storybook\": \"storybook build\",\n \"check\": \"bun run check:biome && bun run check:ts\",\n \"check:fix\": \"bun run check:biome:fix && bun run check:ts\",\n \"check:biome\": \"biome check\",\n \"check:biome:fix\": \"biome check --write\",\n \"check:ts\": \"tsc --noEmit\",\n<% if (relay) { -%>\n \"relay\": \"relay-compiler\",\n \"relay:watch\": \"relay-compiler --watch\",\n<% } -%>\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"test:e2e\": \"vitest run --config vitest.e2e.config.ts\",\n \"storybook\": \"storybook dev -p 6010 --no-open --host 0.0.0.0\"\n },\n \"dependencies\": {\n \"@canonical/react-ds-global\": \"<%= pragmaVersion %>\",\n<% if (forms) { -%>\n \"@canonical/react-ds-global-form\": \"<%= pragmaVersion %>\",\n<% } -%>\n \"@canonical/react-head\": \"<%= pragmaVersion %>\",\n \"@canonical/react-hooks\": \"<%= pragmaVersion %>\",\n \"@canonical/react-ssr\": \"<%= pragmaVersion %>\",\n \"@canonical/router-core\": \"<%= pragmaVersion %>\",\n \"@canonical/router-react\": \"<%= pragmaVersion %>\",\n<% if (relay) { -%>\n \"@canonical/storybook-addon-relay\": \"<%= pragmaVersion %>\",\n<% } -%>\n \"@canonical/storybook-config\": \"<%= pragmaVersion %>\",\n \"@canonical/styles\": \"<%= pragmaVersion %>\",\n \"express\": \"^5.2.1\",\n<% if (relay) { -%>\n \"graphql\": \"^16.11.0\",\n<% } -%>\n \"react\": \"^19.2.4\",\n \"react-dom\": \"^19.2.4\"<% if (relay) { %>,\n \"react-relay\": \"^21.0.1\",\n \"relay-runtime\": \"^21.0.1\",\n \"relay-runtime-network\": \"^0.1.0\"<% } %>\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"2.4.9\",\n \"@canonical/biome-config\": \"<%= pragmaVersion %>\",\n \"@canonical/typescript-config-react\": \"<%= pragmaVersion %>\",\n \"@storybook/react-vite\": \"^10.3.1\",\n \"@testing-library/jest-dom\": \"^6.9.1\",\n \"@testing-library/react\": \"^16.3.2\",\n \"@types/express\": \"^5.0.6\",\n \"@types/node\": \"^24.12.0\",\n \"@types/react\": \"^19.2.14\",\n \"@types/react-dom\": \"^19.2.3\",\n<% if (relay) { -%>\n \"@types/react-relay\": \"^18.2.1\",\n \"@types/relay-runtime\": \"^20.1.1\",\n \"@types/relay-test-utils\": \"^19.0.0\",\n<% } -%>\n \"@vitejs/plugin-react\": \"^6.0.0\",\n \"@vitest/coverage-v8\": \"^4.0.18\",\n \"browserslist\": \"^4.28.1\",\n \"bun-types\": \"^1.3.9\",\n \"jsdom\": \"^28.1.0\",\n \"lightningcss\": \"^1.32.0\",\n<% if (relay) { -%>\n \"relay-compiler\": \"^21.0.1\",\n \"relay-test-utils\": \"^21.0.1\",\n<% } -%>\n \"storybook\": \"^10.3.1\",\n \"tsx\": \"^4.19.0\",\n \"typescript\": \"^5.9.3\",\n \"vite\": \"^8.0.1\",\n<% if (relay) { -%>\n \"vite-plugin-relay-lite\": \"^0.12.0\",\n<% } -%>\n \"vitest\": \"^4.0.18\"\n }<% if (relay && standalone) { %>,\n \"patchedDependencies\": {\n \"react-relay@21.0.1\": \"patches/react-relay@21.0.1.patch\",\n \"relay-runtime@21.0.1\": \"patches/relay-runtime@21.0.1.patch\",\n \"relay-runtime-network@0.1.0\": \"patches/relay-runtime-network@0.1.0.patch\"\n }<% } %>\n}\n",
12
+ "application/src/client/entry.tsx.ejs": "import { HeadProvider } from \"@canonical/react-head\";\nimport { createBrowserRouter } from \"@canonical/router-core\";\nimport { Outlet, RouterProvider } from \"@canonical/router-react\";\nimport { hydrateRoot } from \"react-dom/client\";\n<% if (relay) { -%>\nimport { RelayEnvironmentProvider } from \"react-relay\";\nimport { createEnvironment } from \"#relay/environment.js\";\n<% } -%>\nimport { appRoutes, middleware, notFoundRoute } from \"../routes.js\";\nimport \"#styles/index.css\";\n\nconst router = createBrowserRouter(appRoutes, {\n middleware: [...middleware],\n notFound: notFoundRoute,\n});\n<% if (relay) { -%>\n\n// One Relay environment (network + normalized store) for the whole browser\n// session — module scope, so client-side navigations share the cache.\nconst relayEnvironment = createEnvironment();\n<% } -%>\n\nconst root = document.getElementById(\"root\");\nif (!root) {\n throw new Error('Root element \"#root\" not found');\n}\n\n<% if (relay) { -%>\nhydrateRoot(\n root,\n <HeadProvider>\n <RelayEnvironmentProvider environment={relayEnvironment}>\n <RouterProvider router={router}>\n <Outlet fallback={<p>Loading…</p>} />\n </RouterProvider>\n </RelayEnvironmentProvider>\n </HeadProvider>,\n);\n<% } else { -%>\nhydrateRoot(\n root,\n <HeadProvider>\n <RouterProvider router={router}>\n <Outlet fallback={<p>Loading…</p>} />\n </RouterProvider>\n </HeadProvider>,\n);\n<% } -%>\n",
13
+ "application/src/lib/Navigation/Navigation.tsx.ejs": "import { Link } from \"@canonical/router-react\";\nimport type { ReactElement } from \"react\";\nimport ThemeSelector from \"../ThemeSelector/index.js\";\n\nexport default function Navigation(): ReactElement {\n return (\n <nav aria-label=\"Main\">\n <Link to=\"home\">Home</Link>\n <Link params={{ slug: \"router-core\" }} to=\"guide\">\n Guide\n </Link>\n<% if (relay) { -%>\n <Link to=\"catalog\">Catalog</Link>\n<% } -%>\n<% if (forms) { -%>\n <Link to=\"contact\">Contact</Link>\n<% } -%>\n <Link search={{ auth: \"1\" }} to=\"account\">\n Demo sign-in\n </Link>\n <ThemeSelector />\n </nav>\n );\n}\n",
14
+ "application/src/lib/index.ts.ejs": "<% if (relay) { -%>\nexport { default as ClientOnly } from \"./ClientOnly/index.js\";\n<% } -%>\nexport { ExampleComponent } from \"./ExampleComponent/index.js\";\nexport { default as LazyComponent } from \"./LazyComponent/index.js\";\nexport { default as Navigation } from \"./Navigation/index.js\";\nexport { default as ThemeSelector } from \"./ThemeSelector/index.js\";\n",
15
+ "application/src/routes.tsx.ejs": "import {\n type AnyRoute,\n group,\n type NavigationContext,\n type RouteMiddleware,\n type RouteParamValues,\n redirect,\n route,\n wrapper,\n} from \"@canonical/router-core\";\nimport type { ReactElement, ReactNode } from \"react\";\nimport accountRoutes from \"#domains/account/routes.js\";\n<% if (relay) { -%>\nimport catalogRoutes from \"#domains/catalog/routes.js\";\n<% } -%>\n<% if (forms) { -%>\nimport contactRoutes from \"#domains/contact/routes.js\";\n<% } -%>\nimport marketingRoutes from \"#domains/marketing/routes.js\";\nimport Navigation from \"#lib/Navigation/index.js\";\n\nconst protectedPaths = new Set([\"/account\"]);\n\nfunction hasDemoAuth(search: unknown): boolean {\n const authValue = (search as Record<string, unknown>)?.auth;\n\n return authValue === \"1\";\n}\n\nexport function getAuthRedirectHref(input: string | URL): string | null {\n // Absolute URLs are used as-is; relative paths resolve against a dummy base.\n const url =\n input instanceof URL ? input : new URL(input, \"https://router.local\");\n\n if (\n !protectedPaths.has(url.pathname) ||\n hasDemoAuth({ auth: url.searchParams.get(\"auth\") })\n ) {\n return null;\n }\n\n return `/login?from=${encodeURIComponent(url.pathname)}`;\n}\n\nexport function withAuth(loginPath: string): RouteMiddleware {\n return ((currentRoute: AnyRoute) => {\n if (!protectedPaths.has(currentRoute.url)) {\n return currentRoute;\n }\n\n const currentPrefetch = currentRoute.prefetch;\n\n return {\n ...currentRoute,\n prefetch: (\n params: unknown,\n search: unknown,\n context: NavigationContext,\n ) => {\n if (!hasDemoAuth(search)) {\n const from = currentRoute.render(\n (params ?? {}) as RouteParamValues | Record<string, never>,\n );\n\n redirect(`${loginPath}?from=${encodeURIComponent(from)}`, 302);\n }\n\n if (currentPrefetch) {\n return currentPrefetch(params, search, context);\n }\n },\n };\n }) as RouteMiddleware;\n}\n\nconst publicLayout = wrapper<ReactElement>({\n id: \"public-layout\",\n component: ({ children }: { children: ReactNode }) => (\n <div className=\"subgrid app-shell\">\n <header className=\"subgrid shell-header\">\n <Navigation />\n </header>\n <main className=\"subgrid\">{children}</main>\n </div>\n ),\n});\n\nconst notFoundRoute = route({\n url: \"/not-found\",\n content: () => (\n <section>\n <h1>Page not found</h1>\n <p>The page you are looking for does not exist.</p>\n </section>\n ),\n});\n\nconst [guide, home] = group(publicLayout, [\n marketingRoutes.guide,\n marketingRoutes.home,\n] as const);\n\nconst [account, login] = group(publicLayout, [\n accountRoutes.account,\n accountRoutes.login,\n] as const);\n\n<% if (forms) { -%>\nconst [contact] = group(publicLayout, [contactRoutes.contact] as const);\n\n<% } -%>\n<% if (relay) { -%>\nconst [catalog] = group(publicLayout, [catalogRoutes.catalog] as const);\n\n<% } -%>\nconst appRoutes = {\n guide,\n home,\n account,\n login,\n<% if (forms) { -%>\n contact,\n<% } -%>\n<% if (relay) { -%>\n catalog,\n<% } -%>\n} as const;\n\nexport type AppRoutes = typeof appRoutes;\n\ndeclare module \"@canonical/router-react\" {\n interface RouterRegister {\n routes: AppRoutes;\n }\n}\n\nexport const middleware = [withAuth(\"/login\")] as const;\n\nexport { appRoutes, notFoundRoute };\n",
16
+ "application/src/server/entry.tsx.ejs": "import { HeadProvider } from \"@canonical/react-head\";\nimport type { ServerEntrypointProps } from \"@canonical/react-ssr/renderer\";\nimport { createStaticRouter } from \"@canonical/router-core\";\nimport { Outlet, RouterProvider } from \"@canonical/router-react\";\n<% if (relay) { -%>\nimport { RelayEnvironmentProvider } from \"react-relay\";\nimport { createEnvironment } from \"#relay/environment.js\";\n<% } -%>\nimport { appRoutes, middleware, notFoundRoute } from \"../routes.js\";\nimport \"#styles/app.css\";\n\ninterface InitialData extends Record<string, unknown> {\n readonly url?: string;\n /** Colour-scheme preference resolved from the request cookie, if any. */\n readonly theme?: \"light\" | \"dark\";\n}\n\nexport default function EntryServer(props: ServerEntrypointProps<InitialData>) {\n const initialData = props.initialData ?? {};\n const url = initialData.url ?? \"/\";\n const router = createStaticRouter(appRoutes, url, {\n middleware: [...middleware],\n notFound: notFoundRoute,\n });\n<% if (relay) { -%>\n\n // A fresh Relay environment per server render, so no store state leaks\n // between requests. Nothing fetches through it yet: components that issue\n // queries are wrapped in `ClientOnly` (see CatalogPage) until data\n // serialization/hydration is supported; the provider is here so any\n // component touching Relay context renders without branching on runtime.\n const relayEnvironment = createEnvironment();\n<% } -%>\n\n // Paint the cookie-resolved theme on <html> for a flash-free first render —\n // the same element `usePreferredTheme` toggles on the client, and one React\n // does not hydrate (only `#root` is), so there is no mismatch to reconcile.\n<% if (relay) { -%>\n return (\n <html lang={props.lang} className={initialData.theme}>\n <head>\n {props.otherHeadElements}\n {props.scriptElements}\n {props.linkElements}\n </head>\n <body>\n <div id=\"root\">\n <HeadProvider>\n <RelayEnvironmentProvider environment={relayEnvironment}>\n <RouterProvider router={router}>\n <Outlet fallback={<p>Loading…</p>} />\n </RouterProvider>\n </RelayEnvironmentProvider>\n </HeadProvider>\n </div>\n </body>\n </html>\n );\n<% } else { -%>\n return (\n <html lang={props.lang} className={initialData.theme}>\n <head>\n {props.otherHeadElements}\n {props.scriptElements}\n {props.linkElements}\n </head>\n <body>\n <div id=\"root\">\n <HeadProvider>\n <RouterProvider router={router}>\n <Outlet fallback={<p>Loading…</p>} />\n </RouterProvider>\n </HeadProvider>\n </div>\n </body>\n </html>\n );\n<% } -%>\n}\n\nexport type { InitialData };\n",
17
+ "application/src/sitemap/getSitemapItems.ts.ejs": "import type { SitemapItem } from \"@canonical/react-ssr/renderer\";\n\n/**\n * Returns sitemap entries for all known routes.\n *\n * Update this list as you add domains and routes. For dynamic content\n * (blog posts, product pages), fetch entries from your data source.\n *\n * @example\n * const posts = await fetchPosts();\n * return [\n * ...staticEntries,\n * ...posts.map((post) => ({\n * loc: `/blog/${post.slug}`,\n * lastmod: post.updatedAt,\n * changefreq: \"weekly\" as const,\n * priority: 0.7,\n * })),\n * ];\n */\nexport default async function getSitemapItems(): Promise<SitemapItem[]> {\n return [\n { loc: \"/\", changefreq: \"weekly\", priority: 1.0 },\n { loc: \"/guides/router-core\", changefreq: \"monthly\", priority: 0.8 },\n<% if (relay) { -%>\n { loc: \"/catalog\", changefreq: \"weekly\", priority: 0.7 },\n<% } -%>\n<% if (forms) { -%>\n { loc: \"/contact\", changefreq: \"monthly\", priority: 0.7 },\n<% } -%>\n { loc: \"/account\", changefreq: \"monthly\", priority: 0.5 },\n { loc: \"/login\", changefreq: \"yearly\", priority: 0.3 },\n ];\n}\n",
18
+ "application/src/styles/index.css.ejs": "@import url(\"@canonical/styles\");\n<% if (forms) { -%>\n@import url(\"@canonical/react-ds-global-form/dist/esm/index.css\");\n<% } -%>\n@import url(\"./app.css\");\n",
19
+ "application/tsconfig.json.ejs": "{\n \"extends\": \"@canonical/typescript-config-react\",\n \"compilerOptions\": {\n \"baseUrl\": \"src\",\n \"skipLibCheck\": true,\n \"types\": [\n \"bun-types\",\n \"node\",\n \"react\",\n \"react-dom\",\n \"vitest/globals\",\n \"@testing-library/jest-dom\"\n ],\n \"noEmit\": true,\n \"paths\": {\n \"#lib/*\": [\"./lib/*\"],\n \"#domains/*\": [\"./domains/*\"],\n<% if (relay) { -%>\n \"#relay/*\": [\"./relay/*\"],\n<% } -%>\n \"#styles/*\": [\"./styles/*\"]\n }\n },\n \"include\": [\n \"src/**/*.ts\",\n \"src/**/*.tsx\",\n \".storybook/*.ts\",\n \".storybook/*.tsx\",\n \"vite.config.ts\",\n \"vitest.setup.ts\",\n \"vitest.config.ts\",\n \"vitest.e2e.config.ts\",\n \"test/**/*.ts\"\n ]\n}\n",
20
+ "application/vite.config.ts.ejs": "import react from \"@vitejs/plugin-react\";\nimport browserslist from \"browserslist\";\nimport { browserslistToTargets } from \"lightningcss\";\nimport { defineConfig } from \"vite\";\n<% if (relay) { -%>\nimport relay from \"vite-plugin-relay-lite\";\n<% } -%>\n\n// Path aliases (#lib, #domains, #styles) are declared as Node subpath imports\n// in package.json \"imports\" and resolved natively by Vite — no resolver plugin.\nconst PORT = Number(process.env.PORT) || undefined;\n\n// `build:server` runs `vite build --mode server` to compile the two server\n// renderers in a single pass. Each is a separate, individually-instantiated\n// Lego brick, so they are named Rollup inputs — the build emits\n// `dist/server/renderer.js` (the JSX app) + `dist/server/sitemap.js` (the XML\n// sitemap), which the preview servers import directly. Every other command\n// (`dev`, `build:client`, `preview`) uses the default mode and the SPA client\n// build (`--ssrManifest --outDir dist/client`).\nexport default defineConfig(({ mode }) => ({\n<% if (relay) { -%>\n // Relay's `graphql\\`...\\`` tags must be rewritten into imports of the\n // compiler-generated artifacts. `@vitejs/plugin-react` v6 is OXC-based (no\n // Babel), so the classic `babel-plugin-relay` route would need the\n // `@rolldown/plugin-babel` escape hatch; `vite-plugin-relay-lite` does the\n // same rewrite with its own parser and no Babel, and works on Vite 8 /\n // rolldown despite its peer range stopping at Vite 7 (bun installs it with\n // only a peer-version warning). Footgun: its tag scanner matches the word\n // \"graphql\" followed by a backtick even inside comments, so never\n // backtick-quote a graphql file name in a comment. `codegen: false` because\n // artifacts are committed and regenerated explicitly via the `relay` /\n // `relay:watch` scripts.\n plugins: [relay({ codegen: false }), react()],\n<% } else { -%>\n plugins: [react()],\n<% } -%>\n // Honour the PORT env var for `dev` (SPA) and `preview` so all server scripts\n // — including the SSR ones, which already read PORT — respond to it uniformly.\n server: { port: PORT },\n preview: { port: PORT },\n // CSS delivery is the app's job, not the libraries': @canonical/* packages\n // deliberately ship modern, uncompiled per-component CSS and take no stance\n // on browser support. Lightning CSS (already bundled with Vite 8) compiles\n // that CSS down to this app's declared browser floor — the browserslist\n // query in .browserslistrc, which is the one knob to turn when support\n // requirements change. Not everything can be downleveled: math functions\n // like `mod()` (used by the typography baseline grid) have no polyfillable\n // form, so that feature's effective Chromium ≥ 125 floor is unchanged.\n css: {\n transformer: \"lightningcss\",\n lightningcss: { targets: browserslistToTargets(browserslist()) },\n },\n build: {\n // Minify CSS with Lightning CSS too (instead of the esbuild default), so\n // a single tool owns both downleveling and minification — in the client\n // build and the server build alike.\n cssMinify: \"lightningcss\",\n ...(mode === \"server\"\n ? {\n ssr: true,\n outDir: \"dist/server\",\n rollupOptions: {\n input: {\n renderer: \"src/server/renderer.tsx\",\n sitemap: \"src/sitemap/renderer.ts\",\n },\n },\n }\n : undefined),\n },\n ssr: {\n // Bundle @canonical/* for SSR rather than externalising them, for two\n // reasons: (1) some packages declare only a \"module\" entry (no\n // \"main\"/\"exports\"), which Vite's SSR (Node-style) resolver ignores —\n // externalising them fails with ERR_RESOLVE_PACKAGE_ENTRY_FAIL; (2) their\n // built output imports CSS as a side effect (e.g. `import \"./x.css\"`),\n // which Node cannot load (ERR_UNKNOWN_FILE_EXTENSION) but Vite's SSR\n // transform no-ops. The regex covers the whole scope so any current or\n // future @canonical dependency is handled.\n<% if (relay) { -%>\n //\n // The Relay packages (react-relay, relay-runtime, relay-runtime-network,\n // graphql) stay externalised like react itself. Three packaging defects\n // made that possible and are fixed via `patchedDependencies` (app-local\n // patches/ for a standalone app; the workspace root's patches/ when the\n // app lives inside a bun workspace): react-relay's CJS exports are member\n // expressions cjs-module-lexer cannot detect (breaking named imports\n // under Node SSR and Vite's dev module runner), relay-runtime lacks\n // runtime bindings for type-only names its compiler artifacts import as\n // values (ConcreteRequest, ReaderFragment, FragmentRefs), and\n // relay-runtime-network@0.1.0 ships an `imports` map pointing at its\n // unpublished src/ directory.\n<% } -%>\n noExternal: [/^@canonical\\//],\n },\n}));\n",
21
+ "application/vitest.setup.ts.ejs": "import * as matchers from \"@testing-library/jest-dom/matchers\";\nimport { cleanup } from \"@testing-library/react\";\n<% if (relay) { -%>\nimport { afterEach, expect, vi } from \"vitest\";\n<% } else { -%>\nimport { afterEach, expect } from \"vitest\";\n<% } -%>\n\nexpect.extend(matchers as unknown as Parameters<typeof expect.extend>[0]);\n<% if (relay) { -%>\n\n// relay-test-utils' `createMockEnvironment` wraps environment methods in\n// `jest.fn` mocks whenever NODE_ENV === \"test\", reaching for a global `jest`\n// object. Vitest sets NODE_ENV=test but exposes `vi` instead, so alias it —\n// `vi.fn` is API-compatible with the `jest.fn` surface relay-test-utils uses\n// (`.mock`, `.mockClear`).\n(globalThis as { jest?: typeof vi }).jest = vi;\n<% } -%>\n\nafterEach(() => {\n cleanup();\n});\n",
22
+ "component/lit/component.ts.ejs": "import { html, LitElement } from \"lit\";\nimport { customElement } from \"lit/decorators.js\";\n<% if (withStyles) { -%>\nimport styles from \"./styles.css\";\n<% } -%>\nimport type { <%= name %>Props } from \"./types.js\";\n\nconst componentCssClassName = \"ds <%= kebabName %>\";\n\n/**\n * <%= name %> web component.\n *\n * @implements ds:global.component.<%= kebabName %>\n */\n@customElement(\"ds-<%= kebabName %>\")\nexport default class <%= name %> extends LitElement implements <%= name %>Props {\n<% if (withStyles) { -%>\n static styles = styles;\n\n<% } -%>\n render() {\n return html`\n <div class=\"${componentCssClassName}\">\n <slot></slot>\n </div>\n `;\n }\n}\n",
23
+ "component/lit/index.ts.ejs": "export { default as <%= name %> } from \"./<%= name %>.js\";\nexport type { <%= name %>Props } from \"./types.js\";\n",
24
+ "component/lit/stories.ts.ejs": "import type { Meta, StoryObj } from \"@storybook/web-components-vite\";\nimport { html } from \"lit\";\n\nimport \"./<%= name %>.js\";\nimport type <%= name %> from \"./<%= name %>.js\";\n\nconst meta = {\n title: \"Web Components/<%= name %>\",\n tags: [\"autodocs\"],\n} satisfies Meta<<%= name %>>;\n\nexport default meta;\ntype Story = StoryObj<<%= name %>>;\n\nexport const Default: Story = {\n render: () => html`<ds-<%= kebabName %>>Hello, <%= name %>!</ds-<%= kebabName %>>`,\n};\n",
25
+ "component/lit/styles.css.ejs": "/*\n * Lit Layout Primer\n * Delete this comment block when you're done implementing.\n *\n * Styles live in a shadow DOM, isolated from the page by default.\n *\n * Two layers:\n *\n * 1) :host — the outer shell, how this component presents to its parent layout.\n * display, width, height (always apply)\n * grid-column, grid-row, align-self, justify-self (parent must be grid/flex)\n *\n * 2) .ds.<%= kebabName %> — the inner shell, how this component arranges its shadow children.\n * display: grid/flex, gap, grid-template-columns, align-items, justify-content\n *\n * Subgrid pattern — use when the parent defines grid tracks you want to inherit:\n *\n * In the parent component:\n * .ds.parent { display: grid; grid-template-columns: repeat(4, 1fr); }\n *\n * In this component:\n * :host { display: grid; grid-column: span 2; }\n * .ds.<%= kebabName %> { display: grid; grid-template-columns: subgrid; }\n *\n * In this example, the parent establishes a 4-column grid.\n * This component claims 2 of those columns and inherits their widths via subgrid.\n *\n * Keep in mind:\n * - Custom elements are display: inline by default — always set display on :host.\n * - Flex/grid rules only affect direct children of the container, not deeper descendants.\n * - External CSS cannot pierce the shadow boundary — expose CSS custom properties for theming.\n */\n\n:host {\n /*\n * Host controls the outer layout role.\n * Declare component CSS variables here when needed.\n * Variables must be on :host to be accessible inside the shadow tree.\n *\n * Example:\n * --<%= kebabName %>-color-background: var(--color-background-default);\n * --<%= kebabName %>-color-text: var(--color-text-default);\n */\n display: inline-flex;\n}\n\n.ds.<%= kebabName %> {\n /* Inner layout and visual styles go here. */\n}\n",
26
+ "component/lit/tests.ts.ejs": "import { afterEach, beforeEach, describe, expect, it } from \"vitest\";\nimport \"./<%= name %>.js\";\nimport type <%= name %> from \"./<%= name %>.js\";\n\ndescribe(\"<%= name %> component\", () => {\n let elem: <%= name %>;\n\n beforeEach(() => {\n elem = document.createElement(\"ds-<%= kebabName %>\") as <%= name %>;\n document.body.appendChild(elem);\n });\n\n afterEach(() => {\n elem.remove();\n });\n\n it(\"should render component\", async () => {\n await customElements.whenDefined(\"ds-<%= kebabName %>\");\n\n const container = elem.shadowRoot?.querySelector(\".ds.<%= kebabName %>\");\n expect(container).toBeTruthy();\n });\n\n it(\"should have correct tag name\", () => {\n expect(elem.tagName.toLowerCase()).toBe(\"ds-<%= kebabName %>\");\n });\n});\n",
27
+ "component/lit/types.ts.ejs": "/**\n * Props for the <%= name %> component.\n */\nexport interface <%= name %>Props {\n // Define props specific to <%= name %> here\n}\n",
28
+ "component/react/component.tsx.ejs": "import type React from \"react\";\nimport type { <%= name %>Props } from \"./types.js\";\n<% if (withStyles) { -%>\nimport \"./styles.css\";\n<% } -%>\n\nconst componentCssClassName = \"ds <%= kebabName %>\";\n\n/**\n * <%= name %> component\n */\nconst <%= name %> = ({\n\tclassName,\n\tchildren,\n\t...props\n}: <%= name %>Props): React.ReactElement => {\n\treturn (\n\t\t<div\n\t\t\tclassName={[componentCssClassName, className].filter(Boolean).join(\" \")}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</div>\n\t);\n};\n\nexport default <%= name %>;\n",
29
+ "component/react/index.ts.ejs": "export { default as <%= name %> } from \"./<%= name %>.js\";\nexport type * from \"./types.js\";\n",
30
+ "component/react/ssr.test.tsx.ejs": "import { describe, expect, it } from \"vitest\";\nimport { renderToString } from \"react-dom/server\";\nimport <%= name %> from \"./<%= name %>.js\";\n\ndescribe(\"<%= name %> SSR\", () => {\n\tit(\"renders without hydration errors\", () => {\n\t\tconst html = renderToString(<<%= name %>>Test content</<%= name %>>);\n\t\texpect(html).toContain(\"Test content\");\n\t\texpect(html).toContain(\"ds <%= kebabName %>\");\n\t});\n});\n",
31
+ "component/react/stories.tsx.ejs": "import type { Meta, StoryObj } from \"@storybook/react-vite\";\nimport <%= name %> from \"./<%= name %>.js\";\n\nconst meta: Meta<typeof <%= name %>> = {\n\ttitle: \"Components/<%= name %>\",\n\tcomponent: <%= name %>,\n\ttags: [\"autodocs\"],\n};\n\nexport default meta;\ntype Story = StoryObj<typeof <%= name %>>;\n\nexport const Default: Story = {\n\targs: {\n\t\tchildren: \"Hello, <%= name %>!\",\n\t},\n};\n\nexport const WithCustomClass: Story = {\n\targs: {\n\t\tchildren: \"Custom styled\",\n\t\tclassName: \"custom-class\",\n\t},\n};\n",
32
+ "component/react/test.tsx.ejs": "import { describe, expect, it } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport <%= name %> from \"./<%= name %>.js\";\n\ndescribe(\"<%= name %>\", () => {\n\tit(\"renders children\", () => {\n\t\trender(<<%= name %>>Test content</<%= name %>>);\n\t\texpect(screen.getByText(\"Test content\")).toBeInTheDocument();\n\t});\n\n\tit(\"applies custom className\", () => {\n\t\trender(<<%= name %> className=\"custom-class\">Content</<%= name %>>);\n\t\tconst element = screen.getByText(\"Content\");\n\t\texpect(element.className).toContain(\"ds <%= kebabName %>\");\n\t\texpect(element.className).toContain(\"custom-class\");\n\t});\n\n\tit(\"passes through additional props\", () => {\n\t\trender(<<%= name %> data-testid=\"test-component\">Content</<%= name %>>);\n\t\texpect(screen.getByTestId(\"test-component\")).toBeInTheDocument();\n\t});\n});\n",
33
+ "component/react/types.ts.ejs": "import type { HTMLAttributes, ReactNode } from \"react\";\n\nexport interface <%= name %>Props extends HTMLAttributes<HTMLDivElement> {\n\t/** Content to render inside the component */\n\tchildren?: ReactNode;\n}\n",
34
+ "component/shared/styles.css.ejs": ".ds.<%= kebabName %> {\n\t/* Component styles */\n}\n",
35
+ "component/svelte/component.svelte.ejs": "<script lang=\"ts\">\n\timport type { <%= name %>Props } from \"./types.js\";\n<% if (withStyles) { -%>\n\timport \"./styles.css\";\n<% } -%>\n\n\tconst componentCssClassName = \"ds <%= kebabName %>\";\n\n\tlet {\n\t\tclass: className,\n\t\tchildren,\n\t\t...rest\n\t}: <%= name %>Props = $props();\n</script>\n\n<div\n\tclass={[componentCssClassName, className]}\n\t{...rest}\n>\n\t{@render children?.()}\n</div>\n",
36
+ "component/svelte/index.ts.ejs": "export { default as <%= name %> } from \"./<%= name %>.svelte\";\nexport type { <%= name %>Props } from \"./types.js\";\n",
37
+ "component/svelte/ssr.test.ts.ejs": "import { render } from \"@canonical/svelte-ssr-test\";\nimport type { RenderResult } from \"@canonical/svelte-ssr-test\";\nimport { createRawSnippet } from \"svelte\";\nimport type { ComponentProps } from \"svelte\";\nimport { describe, expect, it } from \"vitest\";\nimport Component from \"./<%= name %>.svelte\";\n\ndescribe(\"<%= name %> SSR\", () => {\n\tconst baseProps = {\n\t\tchildren: createRawSnippet(() => ({\n\t\t\trender: () => `<span><%= name %></span>`,\n\t\t})),\n\t} satisfies ComponentProps<typeof Component>;\n\n\tdescribe(\"basics\", () => {\n\t\tit(\"doesn't throw\", () => {\n\t\t\texpect(() => {\n\t\t\t\trender(Component, { props: { ...baseProps } });\n\t\t\t}).not.toThrow();\n\t\t});\n\n\t\tit(\"renders\", () => {\n\t\t\tconst page = render(Component, { props: { ...baseProps } });\n\t\t\texpect(componentLocator(page)).toBeInstanceOf(page.window.HTMLDivElement);\n\t\t});\n\t});\n\n\tdescribe(\"attributes\", () => {\n\t\tit.each([\n\t\t\t[\"id\", \"test-id\"],\n\t\t\t[\"aria-label\", \"test-aria-label\"],\n\t\t])(\"applies %s\", (attribute, expected) => {\n\t\t\tconst page = render(Component, {\n\t\t\t\tprops: { ...baseProps, [attribute]: expected },\n\t\t\t});\n\t\t\texpect(componentLocator(page).getAttribute(attribute)).toBe(expected);\n\t\t});\n\n\t\tit(\"applies classes\", () => {\n\t\t\tconst page = render(Component, {\n\t\t\t\tprops: { class: \"test-class\", ...baseProps },\n\t\t\t});\n\t\t\texpect(componentLocator(page).classList).toContain(\"test-class\");\n<% if (withStyles) { _%>\n\t\t\texpect(componentLocator(page).classList).toContain(\"ds\");\n\t\t\texpect(componentLocator(page).classList).toContain(\"<%= kebabName %>\");<% } %>\n\t\t});\n\n\t\tit(\"applies style\", () => {\n\t\t\tconst page = render(Component, {\n\t\t\t\tprops: { style: \"color: orange;\", ...baseProps },\n\t\t\t});\n\t\t\texpect(componentLocator(page).style.color).toBe(\"orange\");\n\t\t});\n\t});\n});\n\n// Note: Prefer role/semantics-oriented ways of selecting elements (e.g., by role, label, etc.) not only for component roots but for all elements to enhance accessibility and maintainability.\n// To select the component's root element, use one of the available [Queries](https://testing-library.com/docs/queries/about/#priority).\nfunction componentLocator(page: RenderResult): HTMLElement {\n\t// 1. SEMANTIC ROLES (PREFERRED) - These the most closely resemble how assistive technologies interact with your component\n\t// return page.getByRole(\"link\", { name: \"Learn more\" });\n\n\t// 2. LABELS - To test the association between labels and form controls\n\t// return page.getByLabelText(\"Email address\");\n\n\t// 3. PLACEHOLDER TEXT - Useful for input fields with placeholders\n\t// return page.getByPlaceholderText(\"Enter your email\");\n\n\t// 4. TEXT CONTENT - Good for testing the presence of unique texts and selecting non-interactive elements\n\t// return page.getByText(\"<%= name %>\");\n\n\t// 5. DISPLAY VALUE - For selecting form elements by their current value\n\t// return page.getByDisplayValue(\"test value\");\n\n\t// 6. ALT TEXT - For images and visual elements\n\t// return page.getByAltText(\"Company logo\");\n\n\t// 7. TITLE ATTRIBUTE - For elements with title tooltips\n\t// return page.getByTitle(\"Close dialog\");\n\n\t// 8. TEST IDS (LAST RESORT) - When semantic options aren't available\n\t// return page.getByTestId(\"<%= kebabName %>\");\n}\n",
38
+ "component/svelte/stories.svelte.ejs": "<script lang=\"ts\" module>\n\timport { defineMeta } from \"@storybook/addon-svelte-csf\";\n\timport <%= name %> from \"./<%= name %>.svelte\";\n\n\tconst { Story } = defineMeta({\n\t\ttitle: \"Components/<%= name %>\",\n\t\tcomponent: <%= name %>,\n\t\ttags: [\"autodocs\"],\n\t});\n</script>\n\n<Story name=\"Default\">\n\tHello, <%= name %>!\n</Story>\n\n<Story\n name=\"WithCustomClass\"\n args={{\n class: \"custom-class\",\n id: \"custom-id\",\n style: \"background-color: tomato;\",\n }}\n>\n\tCustom styled\n</Story>\n",
39
+ "component/svelte/stories.ts.ejs": "import type { Meta, StoryObj } from \"@storybook/svelte\";\nimport <%= name %> from \"./<%= name %>.svelte\";\n\nconst meta: Meta<typeof <%= name %>> = {\n\ttitle: \"Components/<%= name %>\",\n\tcomponent: <%= name %>,\n\ttags: [\"autodocs\"],\n};\n\nexport default meta;\ntype Story = StoryObj<typeof <%= name %>>;\n\nexport const Default: Story = {};\n\nexport const WithCustomClass: Story = {\n\targs: {\n\t\tclass: \"custom-class\",\n\t},\n};\n",
40
+ "component/svelte/test.ts.ejs": "import type { Locator } from \"@vitest/browser/context\";\nimport { createRawSnippet } from \"svelte\";\nimport type { ComponentProps } from \"svelte\";\nimport { describe, expect, it } from \"vitest\";\nimport { render } from \"vitest-browser-svelte\";\nimport type { RenderResult } from \"vitest-browser-svelte\";\nimport Component from \"./<%= name %>.svelte\";\n\ndescribe(\"<%= name %> component\", () => {\n\tconst baseProps = {\n\t\tchildren: createRawSnippet(() => ({\n\t\t\trender: () => `<span><%= name %></span>`,\n\t\t})),\n\t} satisfies ComponentProps<typeof Component>;\n\n\tit(\"renders\", async () => {\n\t\tconst page = render(Component, { ...baseProps });\n\t\tawait expect.element(componentLocator(page)).toBeInTheDocument();\n\t\tawait expect.element(page.getByText(\"<%= name %>\")).toBeVisible();\n\t});\n\n\tdescribe(\"attributes\", () => {\n\t\tit.each([\n\t\t\t[\"id\", \"test-id\"],\n\t\t\t[\"aria-label\", \"test-aria-label\"],\n\t\t])(\"applies %s\", async (attribute, expected) => {\n\t\t\tconst page = render(Component, { ...baseProps, [attribute]: expected });\n\t\t\tawait expect\n\t\t\t\t.element(componentLocator(page))\n\t\t\t\t.toHaveAttribute(attribute, expected);\n\t\t});\n\n\t\tit(\"applies classes\", async () => {\n\t\t\tconst page = render(Component, { ...baseProps, class: \"test-class\" });\n\t\t\tawait expect.element(componentLocator(page)).toHaveClass(\"test-class\");\n<% if (withStyles) { _%>\n\t\t\tawait expect.element(componentLocator(page)).toHaveClass(\"ds\");\n\t\t\tawait expect\n\t\t\t\t.element(componentLocator(page))\n\t\t\t\t.toHaveClass(\"<%= kebabName %>\");<% } %>\n\t\t});\n\n\t\tit(\"applies style\", async () => {\n\t\t\tconst page = render(Component, {\n\t\t\t\t...baseProps,\n\t\t\t\tstyle: \"color: orange;\",\n\t\t\t});\n\t\t\tawait expect\n\t\t\t\t.element(componentLocator(page))\n\t\t\t\t.toHaveStyle({ color: \"orange\" });\n\t\t});\n\t});\n});\n\n// Note: Prefer role/semantics-oriented ways of selecting elements (e.g., by role, label, etc.) not only for component roots but for all elements to enhance accessibility and maintainability.\n// To select the component's root element, use one of the available [Locators](https://vitest.dev/guide/browser/locators.html).\nfunction componentLocator(page: RenderResult<typeof Component>): Locator {\n\t// 1. SEMANTIC ROLES (PREFERRED) - These the most closely resemble how assistive technologies interact with your component\n\t// return page.getByRole(\"link\", { name: \"Learn more\" });\n\n\t// 2. LABELS - To test the association between labels and form controls\n\t// return page.getByLabel(\"Email address\");\n\n\t// 3. PLACEHOLDER TEXT - Useful for input fields with placeholders\n\t// return page.getByPlaceholder(\"Enter your email\");\n\n\t// 4. TEXT CONTENT - Good for testing the presence of unique texts and selecting non-interactive elements\n\t// return page.getByText(\"<%= name %>\");\n\n\t// 5. ALT TEXT - For images and visual elements\n\t// return page.getByAltText(\"Company logo\");\n\n\t// 6. TITLE ATTRIBUTE - For elements with title tooltips\n\t// return page.getByTitle(\"Close dialog\");\n\n\t// 7. TEST IDS (LAST RESORT) - When semantic options aren't available\n\t// return page.getByTestId(\"<%= kebabName %>\");\n}\n",
41
+ "component/svelte/types.ts.ejs": "import type { Snippet } from \"svelte\";\nimport type { SvelteHTMLElements } from \"svelte/elements\";\n\n/*\n\tFor components that render specific HTML elements with extended prop sets,\n\tmake sure to change `\"div\"` to the appropriate HTML element type.\n*/\ntype BaseProps = SvelteHTMLElements[\"div\"];\n\nexport interface <%= name %>Props extends BaseProps {\n\t/** Content to render inside the component */\n\tchildren?: Snippet;\n\t// Define additional props specific to <%= name %> here\n}\n\n/*\n\t...or consider using appropriate interfaces directly exported from `svelte/elements`.\n\n\tFor example:\n\t- `HTMLButtonAttributes` (provides `disabled`, `type`, etc.)\n\t- `HTMLAnchorAttributes` (provides `href`, `target`, etc.)\n\t- `HTMLInputAttributes` (provides `type`, `checked`, `value`, etc.)\n\t- `HTMLFormAttributes` (provides `action`, `method`, etc.)\n\n\t```typescript\n\timport type { HTMLButtonAttributes } from \"svelte/elements\";\n\n\texport interface MyButtonProps extends HTMLButtonAttributes {\n\t\t// Your custom props here\n\t}\n\t```\n\n\tSee Svelte documentation on typing wrapper components:\n\thttps://svelte.dev/docs/svelte/typescript#Typing-wrapper-components\n*/\n",
42
+ "package/PULL_REQUEST_TEMPLATE.md.ejs": "## Summary\n\n[What this PR does and why]\n\n## QA\n\n- [Add QA steps]\n\n### Checklist\n\n- [ ] PR title follows [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format\n- [ ] Code follows the [code standards](https://github.com/canonical/web-code-standards)\n- [ ] `check`, `test` pass locally\n",
43
+ "package/README.md.ejs": "# <%= name %>\n\n<%= description || 'TODO: Add description' %>\n\n## Installation\n\n```bash\nbun add <%= name %>\n```\n\n## Usage\n\n```typescript\nimport { } from \"<%= name %>\";\n```\n\n## Development\n\n```bash\n# Run checks\nbun run check\n\n# Run tests\nbun run test\n```\n\n## License\n\n<%= license %>\n",
44
+ "package/biome.json.ejs": "{\n \"extends\": [\"@canonical/biome-config\"],\n \"files\": {\n \"includes\": [\"src\", \"*.json\"]\n }\n}\n",
45
+ "package/cli.ts.ejs": "#!/usr/bin/env bun\n/**\n * <%= name %> CLI\n *\n * <%= description || 'TODO: Add description' %>\n */\n\nconsole.log(\"Hello from <%= shortName %>!\");\n",
46
+ "package/index.css.ejs": "/**\n * <%= name %>\n *\n * <%= description || 'TODO: Add description' %>\n */\n",
47
+ "package/index.ts.ejs": "/**\n * <%= name %>\n *\n * <%= description || 'TODO: Add description' %>\n */\n\nexport {};\n",
48
+ "package/package.json.ejs": "{\n \"name\": \"<%= name %>\",\n \"description\": \"<%= description %>\",\n \"version\": \"<%= version %>\",\n \"type\": \"module\",\n<% if (type === 'tool-ts') { -%>\n \"module\": \"src/index.ts\",\n \"types\": \"src/index.ts\",\n<% } else if (type === 'css') { -%>\n \"module\": \"src/index.css\",\n<% } else { -%>\n \"module\": \"dist/esm/index.js\",\n \"types\": \"dist/types/index.d.ts\",\n<% } -%>\n<% if (withCli && type !== 'css') { -%>\n \"bin\": {\n \"<%= shortName %>\": \"src/cli.ts\"\n },\n<% } -%>\n \"files\": [\n<% if (type === 'tool-ts' || type === 'css') { -%>\n \"src\"\n<% } else { -%>\n \"dist\"\n<% } -%>\n ],\n \"author\": {\n \"email\": \"webteam@canonical.com\",\n \"name\": \"Canonical Webteam\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/canonical/pragma\"\n },\n \"license\": \"<%= license %>\",\n \"bugs\": {\n \"url\": \"https://github.com/canonical/pragma/issues\"\n },\n \"homepage\": \"https://github.com/canonical/pragma#readme\",\n \"scripts\": {\n<% if (type === 'tool-ts' || type === 'css') { -%>\n \"build\": \"echo 'No build needed'\",\n<% } else { -%>\n \"build\": \"tsc -p tsconfig.build.json\",\n<% } -%>\n<% if (withStorybook) { -%>\n \"build:all\": \"bun run build && bun run build:storybook\",\n \"build:storybook\": \"storybook build\",\n<% } else { -%>\n \"build:all\": \"bun run build\",\n<% } -%>\n<% if (type === 'css') { -%>\n \"check\": \"bun run check:biome && bun run check:webarchitect\",\n \"check:fix\": \"bun run check:biome:fix\",\n<% } else { -%>\n \"check\": \"bun run check:biome && bun run check:ts && bun run check:webarchitect\",\n \"check:fix\": \"bun run check:biome:fix && bun run check:ts\",\n<% } -%>\n \"check:biome\": \"biome check\",\n \"check:biome:fix\": \"biome check --write\",\n<% if (type !== 'css') { -%>\n \"check:ts\": \"tsc --noEmit\",\n<% } -%>\n \"check:webarchitect\": \"webarchitect <%= ruleset %>\",\n<% if (withStorybook) { -%>\n \"storybook\": \"storybook dev -p 6006 --no-open --host 0.0.0.0\",\n<% } -%>\n<% if (type === 'css') { -%>\n \"test\": \"echo 'No tests for CSS package'\"\n<% } else { -%>\n \"test\": \"vitest run\"\n<% } -%>\n },\n<% if (type !== 'css') { -%>\n \"devDependencies\": {\n \"@biomejs/biome\": \"2.4.6\",\n \"@canonical/biome-config\": \"^<%= monorepoVersion || '0.1.0' %>\",\n<% if (withReact) { -%>\n \"@canonical/typescript-config-react\": \"^<%= monorepoVersion || '0.1.0' %>\",\n<% } else { -%>\n \"@canonical/typescript-config\": \"^<%= monorepoVersion || '0.1.0' %>\",\n<% } -%>\n<% if (withStorybook) { -%>\n \"@chromatic-com/storybook\": \"^5.0.0\",\n<% } -%>\n<% if (withReact) { -%>\n \"@types/react\": \"^19.0.0\",\n \"@types/react-dom\": \"^19.0.0\",\n<% } -%>\n \"bun-types\": \"^1.0.0\",\n<% if (withStorybook) { -%>\n \"storybook\": \"^10.1.11\",\n<% } -%>\n \"typescript\": \"^5.9.3\",\n \"vitest\": \"^3.2.4\"\n },\n \"dependencies\": {\n<% if (withStorybook) { -%>\n \"@canonical/storybook-config\": \"^<%= monorepoVersion || '0.1.0' %>\",\n<% } -%>\n<% if (withReact) { -%>\n \"react\": \"^19.0.0\",\n \"react-dom\": \"^19.0.0\"\n<% } -%>\n }\n<% } else { -%>\n \"devDependencies\": {\n \"@biomejs/biome\": \"2.4.6\",\n \"@canonical/biome-config\": \"^<%= monorepoVersion || '0.1.0' %>\"\n }\n<% } -%>\n}\n",
49
+ "package/storybook-main.ts.ejs": "import { createConfig } from \"@canonical/storybook-config\";\n\nexport default createConfig(\"react\", {\n staticDirs: [\"../src/assets\", \"../public\"],\n});\n",
50
+ "package/storybook-preview.ts.ejs": "import { withThemeByClassName } from \"@storybook/addon-themes\";\nimport type { Preview, ReactRenderer } from \"@storybook/react-vite\";\n\nimport \"index.css\";\nimport \"@canonical/styles-debug/baseline-grid\";\n\nconst preview: Preview = {\n tags: [\"autodocs\"],\n decorators: [\n withThemeByClassName<ReactRenderer>({\n themes: {\n light: \"is-light\",\n dark: \"dark\",\n paper: \"is-paper\",\n },\n defaultTheme: \"light\",\n }),\n ],\n parameters: {\n docs: {\n codePanel: true,\n },\n },\n};\n\nexport default preview;\n",
51
+ "package/tsconfig-react.json.ejs": "{\n \"extends\": \"@canonical/typescript-config-react\",\n \"compilerOptions\": {\n \"baseUrl\": \"src\",\n \"types\": [\"bun-types\"]\n },\n \"include\": [\"src/**/*.ts\", \"src/**/*.tsx\"]\n}\n",
52
+ "package/tsconfig.json.ejs": "{\n \"extends\": \"@canonical/typescript-config\",\n \"compilerOptions\": {\n \"baseUrl\": \"src\",\n \"types\": [\"bun-types\"]\n },\n \"include\": [\"src/**/*.ts\"]\n}\n",
53
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Create-capability types with NO summon-core / generator import, so a module
3
+ * that only needs `CreateKind` (e.g. `create.verb`) does not drag
4
+ * `pickGenerator` — and its heavy generator imports — into the static graph.
5
+ */
6
+
7
+ /** The three `create` nouns (path capped at two segments). */
8
+ export type CreateKind = "component" | "package" | "application";
@@ -0,0 +1,41 @@
1
+ import { readConfig } from "../../../kernel/config/readConfig.js";
2
+ import type { PragmaRuntime } from "../../../kernel/runtime/types.js";
3
+ import type { CheckResult } from "../types.js";
4
+
5
+ /**
6
+ * Check which config layer is active for the working directory.
7
+ *
8
+ * Passes when a project `pragma.config.ts` is found up the tree, or — pragma is
9
+ * global-first — when only the global XDG config exists. Fails only when
10
+ * neither layer is configured.
11
+ *
12
+ * @param rt - The per-invocation runtime (for `cwd`).
13
+ * @returns A CheckResult indicating the active layer, or fail with a remedy.
14
+ * @note Impure — reads the config layers from disk.
15
+ */
16
+ export async function checkConfigFile(rt: PragmaRuntime): Promise<CheckResult> {
17
+ const layers = await readConfig(rt.cwd);
18
+
19
+ if (layers.project.exists) {
20
+ return {
21
+ name: "pragma config",
22
+ status: "pass",
23
+ detail: `project config active (${layers.project.path})`,
24
+ };
25
+ }
26
+
27
+ if (layers.global.exists) {
28
+ return {
29
+ name: "pragma config",
30
+ status: "pass",
31
+ detail: `no project config — global config active (${layers.global.path})`,
32
+ };
33
+ }
34
+
35
+ return {
36
+ name: "pragma config",
37
+ status: "fail",
38
+ detail: "not found",
39
+ remedy: "pragma config set tier <path>",
40
+ };
41
+ }
@@ -0,0 +1,39 @@
1
+ import { entityTotal } from "../../../kernel/completion/entitySource.js";
2
+ import type { PragmaRuntime } from "../../../kernel/runtime/types.js";
3
+ import type { CheckResult } from "../types.js";
4
+
5
+ /**
6
+ * Check that the ke store boots, reporting the entity total and boot time.
7
+ *
8
+ * This is the ONE check that touches the store — it boots the shared lazy store
9
+ * inside a try/catch, so doctor stays storeless-by-default at the dispatch level
10
+ * (the verb declares `needsStore: false`; only this check pays the boot, only
11
+ * when reached). On success it reads the entity total from the session's
12
+ * storeless index rather than a fresh triple COUNT — cheaper, and the store is
13
+ * already booted.
14
+ *
15
+ * @param rt - The per-invocation runtime.
16
+ * @returns A CheckResult: pass with the entity total, or fail with a remedy.
17
+ * @note Impure — boots the store.
18
+ */
19
+ export async function checkKeStore(rt: PragmaRuntime): Promise<CheckResult> {
20
+ const start = performance.now();
21
+ try {
22
+ const session = await rt.store.get();
23
+ const total = entityTotal(session.index);
24
+ const elapsed = Math.round(performance.now() - start);
25
+ return {
26
+ name: "ke store",
27
+ status: "pass",
28
+ detail: `${total.toLocaleString()} entities in ${elapsed}ms`,
29
+ };
30
+ } catch {
31
+ return {
32
+ name: "ke store",
33
+ status: "fail",
34
+ detail: "failed to boot",
35
+ remedy:
36
+ "Ensure design-system packages are installed and run `pragma sources update`.",
37
+ };
38
+ }
39
+ }