@canonical/pragma-cli 0.38.0 → 0.40.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 (330) hide show
  1. package/README.md +1 -1
  2. package/dist/package.json +14 -14
  3. package/dist/pragma.conf.js +273 -176
  4. package/dist/pragma.conf.js.map +1 -1
  5. package/dist/src/capabilities/capabilities/capabilities.verb.js +2 -0
  6. package/dist/src/capabilities/capabilities/capabilities.verb.js.map +1 -1
  7. package/dist/src/capabilities/capabilities/catalog.js +47 -51
  8. package/dist/src/capabilities/capabilities/catalog.js.map +1 -1
  9. package/dist/src/capabilities/capabilities/index.js +2 -0
  10. package/dist/src/capabilities/capabilities/index.js.map +1 -1
  11. package/dist/src/capabilities/capabilities/types.js +5 -5
  12. package/dist/src/capabilities/colophon/colophon.render.js +7 -4
  13. package/dist/src/capabilities/colophon/colophon.render.js.map +1 -1
  14. package/dist/src/capabilities/colophon/colophon.verb.js +1 -0
  15. package/dist/src/capabilities/colophon/colophon.verb.js.map +1 -1
  16. package/dist/src/capabilities/config/get.verb.js +2 -0
  17. package/dist/src/capabilities/config/get.verb.js.map +1 -1
  18. package/dist/src/capabilities/config/runField.js +2 -2
  19. package/dist/src/capabilities/config/runField.js.map +1 -1
  20. package/dist/src/capabilities/config/set.verb.js +2 -0
  21. package/dist/src/capabilities/config/set.verb.js.map +1 -1
  22. package/dist/src/capabilities/config/show.verb.js +1 -0
  23. package/dist/src/capabilities/config/show.verb.js.map +1 -1
  24. package/dist/src/capabilities/config/unset.verb.js +2 -0
  25. package/dist/src/capabilities/config/unset.verb.js.map +1 -1
  26. package/dist/src/capabilities/create/constants.js +2 -2
  27. package/dist/src/capabilities/create/create.verb.js +14 -4
  28. package/dist/src/capabilities/create/create.verb.js.map +1 -1
  29. package/dist/src/capabilities/distribution.js +3 -1
  30. package/dist/src/capabilities/distribution.js.map +1 -1
  31. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js +10 -2
  32. package/dist/src/capabilities/doctor/checks/checkPackageRefs.js.map +1 -1
  33. package/dist/src/capabilities/doctor/doctor.verb.js +2 -0
  34. package/dist/src/capabilities/doctor/doctor.verb.js.map +1 -1
  35. package/dist/src/capabilities/graph/connect.verb.js +2 -0
  36. package/dist/src/capabilities/graph/connect.verb.js.map +1 -1
  37. package/dist/src/capabilities/graph/inspect.render.js +7 -1
  38. package/dist/src/capabilities/graph/inspect.render.js.map +1 -1
  39. package/dist/src/capabilities/graph/inspect.verb.js +2 -0
  40. package/dist/src/capabilities/graph/inspect.verb.js.map +1 -1
  41. package/dist/src/capabilities/graph/query.render.js +37 -5
  42. package/dist/src/capabilities/graph/query.render.js.map +1 -1
  43. package/dist/src/capabilities/graph/query.verb.js +2 -0
  44. package/dist/src/capabilities/graph/query.verb.js.map +1 -1
  45. package/dist/src/capabilities/graph/queryText.js +28 -0
  46. package/dist/src/capabilities/graph/queryText.js.map +1 -1
  47. package/dist/src/capabilities/graph/runConnect.js +3 -3
  48. package/dist/src/capabilities/graph/runConnect.js.map +1 -1
  49. package/dist/src/capabilities/graph/runQuery.js +8 -6
  50. package/dist/src/capabilities/graph/runQuery.js.map +1 -1
  51. package/dist/src/capabilities/info/info.verb.js +2 -0
  52. package/dist/src/capabilities/info/info.verb.js.map +1 -1
  53. package/dist/src/capabilities/meta/mcp.verb.js +1 -0
  54. package/dist/src/capabilities/meta/mcp.verb.js.map +1 -1
  55. package/dist/src/capabilities/ontology/verbs.js +7 -10
  56. package/dist/src/capabilities/ontology/verbs.js.map +1 -1
  57. package/dist/src/capabilities/prompt/verbs.js +5 -4
  58. package/dist/src/capabilities/prompt/verbs.js.map +1 -1
  59. package/dist/src/capabilities/resources/provider.js +6 -3
  60. package/dist/src/capabilities/resources/provider.js.map +1 -1
  61. package/dist/src/capabilities/setup/setup.verb.js +13 -5
  62. package/dist/src/capabilities/setup/setup.verb.js.map +1 -1
  63. package/dist/src/capabilities/shared/calls.js +16 -0
  64. package/dist/src/capabilities/shared/calls.js.map +1 -0
  65. package/dist/src/capabilities/skill/render.js +7 -5
  66. package/dist/src/capabilities/skill/render.js.map +1 -1
  67. package/dist/src/capabilities/skill/verbs.js +5 -4
  68. package/dist/src/capabilities/skill/verbs.js.map +1 -1
  69. package/dist/src/capabilities/sources/collectStatus.js +6 -1
  70. package/dist/src/capabilities/sources/collectStatus.js.map +1 -1
  71. package/dist/src/capabilities/sources/index.js +4 -3
  72. package/dist/src/capabilities/sources/index.js.map +1 -1
  73. package/dist/src/capabilities/sources/reset.render.js +37 -0
  74. package/dist/src/capabilities/sources/reset.render.js.map +1 -0
  75. package/dist/src/capabilities/sources/reset.verb.js +51 -0
  76. package/dist/src/capabilities/sources/reset.verb.js.map +1 -0
  77. package/dist/src/capabilities/sources/runReset.js +59 -0
  78. package/dist/src/capabilities/sources/runReset.js.map +1 -0
  79. package/dist/src/capabilities/sources/runUpdate.js +7 -6
  80. package/dist/src/capabilities/sources/runUpdate.js.map +1 -1
  81. package/dist/src/capabilities/sources/status.render.js +24 -8
  82. package/dist/src/capabilities/sources/status.render.js.map +1 -1
  83. package/dist/src/capabilities/sources/status.verb.js +1 -0
  84. package/dist/src/capabilities/sources/status.verb.js.map +1 -1
  85. package/dist/src/capabilities/sources/update.verb.js +2 -0
  86. package/dist/src/capabilities/sources/update.verb.js.map +1 -1
  87. package/dist/src/capabilities/upgrade/upgrade.verb.js +1 -0
  88. package/dist/src/capabilities/upgrade/upgrade.verb.js.map +1 -1
  89. package/dist/src/capabilities/version/version.verb.js +1 -0
  90. package/dist/src/capabilities/version/version.verb.js.map +1 -1
  91. package/dist/src/constants.js +4 -3
  92. package/dist/src/constants.js.map +1 -1
  93. package/dist/src/kernel/error/index.js +1 -1
  94. package/dist/src/kernel/error/index.js.map +1 -1
  95. package/dist/src/kernel/error/recovery.js +24 -42
  96. package/dist/src/kernel/error/recovery.js.map +1 -1
  97. package/dist/src/kernel/packs/collect.js +123 -9
  98. package/dist/src/kernel/packs/collect.js.map +1 -1
  99. package/dist/src/kernel/packs/compile.js +74 -15
  100. package/dist/src/kernel/packs/compile.js.map +1 -1
  101. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js +3 -3
  102. package/dist/src/kernel/packs/graphql/fetchGraphqlLookup.js.map +1 -1
  103. package/dist/src/kernel/packs/iri.js +2 -4
  104. package/dist/src/kernel/packs/iri.js.map +1 -1
  105. package/dist/src/kernel/packs/renderPack.js +90 -50
  106. package/dist/src/kernel/packs/renderPack.js.map +1 -1
  107. package/dist/src/kernel/packs/resolveEntity.js +202 -90
  108. package/dist/src/kernel/packs/resolveEntity.js.map +1 -1
  109. package/dist/src/kernel/packs/runBodies.js +89 -30
  110. package/dist/src/kernel/packs/runBodies.js.map +1 -1
  111. package/dist/src/kernel/packs/schema.js +66 -12
  112. package/dist/src/kernel/packs/schema.js.map +1 -1
  113. package/dist/src/kernel/packs/sparql/buildListQuery.js +80 -13
  114. package/dist/src/kernel/packs/sparql/buildListQuery.js.map +1 -1
  115. package/dist/src/kernel/packs/sparql/buildLookupQuery.js +41 -13
  116. package/dist/src/kernel/packs/sparql/buildLookupQuery.js.map +1 -1
  117. package/dist/src/kernel/packs/sparql/filterValues.js +32 -23
  118. package/dist/src/kernel/packs/sparql/filterValues.js.map +1 -1
  119. package/dist/src/kernel/packs/sparql/runSelect.js +3 -5
  120. package/dist/src/kernel/packs/sparql/runSelect.js.map +1 -1
  121. package/dist/src/kernel/packs/storyRules.js +31 -4
  122. package/dist/src/kernel/packs/storyRules.js.map +1 -1
  123. package/dist/src/kernel/packs/tierScope.js +3 -3
  124. package/dist/src/kernel/packs/tierScope.js.map +1 -1
  125. package/dist/src/kernel/packs/types.js +4 -0
  126. package/dist/src/kernel/packs/types.js.map +1 -1
  127. package/dist/src/kernel/project/cli/buildProgram.js +4 -0
  128. package/dist/src/kernel/project/cli/buildProgram.js.map +1 -1
  129. package/dist/src/kernel/project/cli/dispatch.js +32 -8
  130. package/dist/src/kernel/project/cli/dispatch.js.map +1 -1
  131. package/dist/src/kernel/project/cli/suggestNames.js +44 -1
  132. package/dist/src/kernel/project/cli/suggestNames.js.map +1 -1
  133. package/dist/src/kernel/project/cli/verbHelp.js +17 -18
  134. package/dist/src/kernel/project/cli/verbHelp.js.map +1 -1
  135. package/dist/src/kernel/project/mcp/buildServer.js +11 -4
  136. package/dist/src/kernel/project/mcp/buildServer.js.map +1 -1
  137. package/dist/src/kernel/project/mcp/envelope.js +3 -2
  138. package/dist/src/kernel/project/mcp/envelope.js.map +1 -1
  139. package/dist/src/kernel/project/mcp/instructions.js +101 -31
  140. package/dist/src/kernel/project/mcp/instructions.js.map +1 -1
  141. package/dist/src/kernel/project/mcp/registerVerb.js +59 -23
  142. package/dist/src/kernel/project/mcp/registerVerb.js.map +1 -1
  143. package/dist/src/kernel/render/renderers.js +3 -3
  144. package/dist/src/kernel/render/turtle.js +21 -4
  145. package/dist/src/kernel/render/turtle.js.map +1 -1
  146. package/dist/src/kernel/runtime/graphpack/build.js +54 -1
  147. package/dist/src/kernel/runtime/graphpack/build.js.map +1 -1
  148. package/dist/src/kernel/runtime/graphpack/manifest.js +14 -0
  149. package/dist/src/kernel/runtime/graphpack/manifest.js.map +1 -1
  150. package/dist/src/kernel/runtime/graphpack/read.js +3 -5
  151. package/dist/src/kernel/runtime/graphpack/read.js.map +1 -1
  152. package/dist/src/kernel/runtime/graphpack/schemas.js +1 -0
  153. package/dist/src/kernel/runtime/graphpack/schemas.js.map +1 -1
  154. package/dist/src/kernel/runtime/loadSession.js +8 -1
  155. package/dist/src/kernel/runtime/loadSession.js.map +1 -1
  156. package/dist/src/kernel/runtime/packVersion.js +75 -0
  157. package/dist/src/kernel/runtime/packVersion.js.map +1 -0
  158. package/dist/src/kernel/runtime/readEntity.js +43 -4
  159. package/dist/src/kernel/runtime/readEntity.js.map +1 -1
  160. package/dist/src/kernel/runtime/resolveSources.js +61 -9
  161. package/dist/src/kernel/runtime/resolveSources.js.map +1 -1
  162. package/dist/src/kernel/runtime/storeReadiness.js +3 -2
  163. package/dist/src/kernel/runtime/storeReadiness.js.map +1 -1
  164. package/dist/src/kernel/spec/call.js +167 -0
  165. package/dist/src/kernel/spec/call.js.map +1 -0
  166. package/dist/src/kernel/spec/emitReference.js +9 -13
  167. package/dist/src/kernel/spec/emitReference.js.map +1 -1
  168. package/dist/src/kernel/spec/emitSurface.js +8 -1
  169. package/dist/src/kernel/spec/emitSurface.js.map +1 -1
  170. package/dist/src/kernel/spec/guidance.js +63 -0
  171. package/dist/src/kernel/spec/guidance.js.map +1 -0
  172. package/dist/src/kernel/spec/wireType.js +36 -0
  173. package/dist/src/kernel/spec/wireType.js.map +1 -0
  174. package/package.json +14 -14
  175. package/pragma.conf.ts +294 -177
  176. package/src/capabilities/block.parity.test.ts +1 -1
  177. package/src/capabilities/callRule.test.ts +147 -0
  178. package/src/capabilities/capabilities/capabilities.test.ts +47 -19
  179. package/src/capabilities/capabilities/capabilities.verb.ts +2 -0
  180. package/src/capabilities/capabilities/catalog.ts +60 -55
  181. package/src/capabilities/capabilities/index.ts +2 -0
  182. package/src/capabilities/capabilities/types.ts +16 -19
  183. package/src/capabilities/colophon/colophon.render.ts +9 -5
  184. package/src/capabilities/colophon/colophon.verb.ts +1 -0
  185. package/src/capabilities/config/get.verb.ts +2 -0
  186. package/src/capabilities/config/runField.ts +3 -3
  187. package/src/capabilities/config/set.verb.ts +3 -0
  188. package/src/capabilities/config/show.verb.ts +2 -0
  189. package/src/capabilities/config/unset.verb.ts +2 -0
  190. package/src/capabilities/create/constants.ts +2 -2
  191. package/src/capabilities/create/create.verb.ts +16 -0
  192. package/src/capabilities/create/createGrammar.test.ts +1 -1
  193. package/src/capabilities/distribution.test.ts +6 -3
  194. package/src/capabilities/distribution.ts +6 -0
  195. package/src/capabilities/doctor/checks/checkPackageRefs.ts +14 -2
  196. package/src/capabilities/doctor/doctor.test.ts +38 -1
  197. package/src/capabilities/doctor/doctor.verb.ts +2 -0
  198. package/src/capabilities/emptyRecovery.test.ts +5 -0
  199. package/src/capabilities/graph/connect.verb.ts +2 -0
  200. package/src/capabilities/graph/inspect.render.ts +9 -1
  201. package/src/capabilities/graph/inspect.test.ts +73 -0
  202. package/src/capabilities/graph/inspect.verb.ts +2 -0
  203. package/src/capabilities/graph/query.render.test.ts +35 -0
  204. package/src/capabilities/graph/query.render.ts +45 -7
  205. package/src/capabilities/graph/query.shipped.exec.test.ts +44 -0
  206. package/src/capabilities/graph/query.verb.ts +2 -0
  207. package/src/capabilities/graph/queryText.test.ts +55 -1
  208. package/src/capabilities/graph/queryText.ts +47 -0
  209. package/src/capabilities/graph/runConnect.ts +4 -5
  210. package/src/capabilities/graph/runQuery.ts +23 -9
  211. package/src/capabilities/info/info.verb.ts +2 -0
  212. package/src/capabilities/links.shipped.exec.test.ts +398 -0
  213. package/src/capabilities/listBudget.shipped.exec.test.ts +2 -2
  214. package/src/capabilities/listLookup.shipped.exec.test.ts +122 -13
  215. package/src/capabilities/listQuery.shipped.exec.test.ts +39 -16
  216. package/src/capabilities/lookupBudget.shipped.exec.test.ts +208 -0
  217. package/src/capabilities/meta/mcp.verb.ts +2 -0
  218. package/src/capabilities/ontology/ontology.test.ts +24 -0
  219. package/src/capabilities/ontology/verbs.ts +16 -12
  220. package/src/capabilities/prompt/verbs.ts +10 -4
  221. package/src/capabilities/resources/provider.ts +7 -3
  222. package/src/capabilities/resources/resources.test.ts +2 -1
  223. package/src/capabilities/setup/setup.verb.ts +16 -0
  224. package/src/capabilities/shared/calls.ts +20 -0
  225. package/src/capabilities/skill/render.ts +9 -6
  226. package/src/capabilities/skill/verbs.ts +8 -4
  227. package/src/capabilities/sources/collectStatus.ts +6 -1
  228. package/src/capabilities/sources/index.ts +4 -3
  229. package/src/capabilities/sources/reset.render.test.ts +33 -0
  230. package/src/capabilities/sources/reset.render.ts +43 -0
  231. package/src/capabilities/sources/reset.verb.ts +59 -0
  232. package/src/capabilities/sources/runReset.ts +65 -0
  233. package/src/capabilities/sources/runUpdate.ts +12 -11
  234. package/src/capabilities/sources/sources.test.ts +158 -3
  235. package/src/capabilities/sources/status.render.test.ts +63 -1
  236. package/src/capabilities/sources/status.render.ts +25 -8
  237. package/src/capabilities/sources/status.verb.ts +2 -0
  238. package/src/capabilities/sources/types.ts +26 -0
  239. package/src/capabilities/sources/update.verb.ts +3 -0
  240. package/src/capabilities/surface.test.ts +2 -2
  241. package/src/capabilities/token.parity.test.ts +3 -2
  242. package/src/capabilities/tokenGraph.shipped.exec.test.ts +14 -2
  243. package/src/capabilities/upgrade/upgrade.verb.ts +1 -0
  244. package/src/capabilities/variable.parity.test.ts +2 -1
  245. package/src/capabilities/version/version.verb.ts +1 -0
  246. package/src/capabilities/wireContract.test.ts +110 -0
  247. package/src/constants.ts +4 -3
  248. package/src/kernel/copy.test.ts +1 -1
  249. package/src/kernel/error/PragmaError.test.ts +7 -3
  250. package/src/kernel/error/index.ts +1 -1
  251. package/src/kernel/error/recovery.test.ts +52 -18
  252. package/src/kernel/error/recovery.ts +25 -46
  253. package/src/kernel/error/types.ts +1 -1
  254. package/src/kernel/packs/collect.test.ts +79 -0
  255. package/src/kernel/packs/collect.ts +151 -11
  256. package/src/kernel/packs/compile.test.ts +107 -10
  257. package/src/kernel/packs/compile.ts +100 -11
  258. package/src/kernel/packs/filteredEmpty.test.ts +22 -5
  259. package/src/kernel/packs/graphql/fetchGraphqlLookup.ts +5 -6
  260. package/src/kernel/packs/graphqlSource.test.ts +42 -0
  261. package/src/kernel/packs/iri.ts +5 -4
  262. package/src/kernel/packs/listNotice.test.ts +1 -1
  263. package/src/kernel/packs/nounLink.test.ts +385 -0
  264. package/src/kernel/packs/renderPack.ts +137 -57
  265. package/src/kernel/packs/resolveEntity.test.ts +170 -1
  266. package/src/kernel/packs/resolveEntity.ts +281 -101
  267. package/src/kernel/packs/runBodies.ts +133 -31
  268. package/src/kernel/packs/schema.ts +77 -12
  269. package/src/kernel/packs/sparql/buildListQuery.test.ts +78 -1
  270. package/src/kernel/packs/sparql/buildListQuery.ts +106 -16
  271. package/src/kernel/packs/sparql/buildLookupQuery.ts +44 -13
  272. package/src/kernel/packs/sparql/filterValues.test.ts +36 -4
  273. package/src/kernel/packs/sparql/filterValues.ts +50 -31
  274. package/src/kernel/packs/sparql/runSelect.ts +4 -6
  275. package/src/kernel/packs/storyRules.ts +37 -4
  276. package/src/kernel/packs/tierScope.test.ts +120 -6
  277. package/src/kernel/packs/tierScope.ts +5 -7
  278. package/src/kernel/packs/toolDescription.test.ts +59 -74
  279. package/src/kernel/packs/types.ts +93 -11
  280. package/src/kernel/project/cli/buildProgram.ts +4 -0
  281. package/src/kernel/project/cli/dispatch.ts +34 -8
  282. package/src/kernel/project/cli/suggest.test.ts +77 -0
  283. package/src/kernel/project/cli/suggestNames.ts +47 -1
  284. package/src/kernel/project/cli/verbHelp.ts +16 -19
  285. package/src/kernel/project/mcp/buildServer.ts +15 -4
  286. package/src/kernel/project/mcp/envelope.ts +3 -2
  287. package/src/kernel/project/mcp/instructions.ts +123 -35
  288. package/src/kernel/project/mcp/prompts/prompts.test.ts +136 -20
  289. package/src/kernel/project/mcp/registerVerb.test.ts +28 -0
  290. package/src/kernel/project/mcp/registerVerb.ts +67 -29
  291. package/src/kernel/render/__snapshots__/renderers.test.ts.snap +1 -1
  292. package/src/kernel/render/renderers.test.ts +2 -2
  293. package/src/kernel/render/renderers.ts +3 -3
  294. package/src/kernel/render/turtle.ts +24 -4
  295. package/src/kernel/runtime/graphpack/build.ts +58 -1
  296. package/src/kernel/runtime/graphpack/graphpack.test.ts +20 -0
  297. package/src/kernel/runtime/graphpack/manifest.ts +15 -0
  298. package/src/kernel/runtime/graphpack/read.ts +4 -6
  299. package/src/kernel/runtime/graphpack/schemas.ts +1 -0
  300. package/src/kernel/runtime/graphpack/types.ts +13 -0
  301. package/src/kernel/runtime/loadSession.ts +8 -1
  302. package/src/kernel/runtime/packVersion.test.ts +61 -0
  303. package/src/kernel/runtime/packVersion.ts +84 -0
  304. package/src/kernel/runtime/readEntity.ts +61 -6
  305. package/src/kernel/runtime/resolveSources.test.ts +90 -7
  306. package/src/kernel/runtime/resolveSources.ts +91 -10
  307. package/src/kernel/runtime/storeReadiness.ts +4 -4
  308. package/src/kernel/runtime/types.ts +12 -0
  309. package/src/kernel/spec/call.test.ts +95 -0
  310. package/src/kernel/spec/call.ts +186 -0
  311. package/src/kernel/spec/emitReference.ts +9 -13
  312. package/src/kernel/spec/emitSurface.ts +9 -1
  313. package/src/kernel/spec/guidance.test.ts +49 -0
  314. package/src/kernel/spec/guidance.ts +68 -0
  315. package/src/kernel/spec/index.ts +4 -0
  316. package/src/kernel/spec/surfaceConformance.test.ts +2 -2
  317. package/src/kernel/spec/types.ts +64 -7
  318. package/src/kernel/spec/wireType.ts +53 -0
  319. package/src/testing/behavioral/errorMatrix.mcp.test.ts +2 -1
  320. package/src/testing/behavioral/journeys.firstInstall.test.ts +72 -2
  321. package/src/testing/behavioral/parity.test.ts +40 -0
  322. package/src/testing/eval/__snapshots__/eval.test.ts.snap +1 -1
  323. package/src/testing/eval/cases/assembly.ts +4 -3
  324. package/src/testing/eval/cases/stable.ts +2 -3
  325. package/src/testing/helpers/callSchema.ts +40 -0
  326. package/src/testing/helpers/parity.ts +35 -2
  327. package/src/testing/setupCallChecking.ts +30 -0
  328. package/dist/src/capabilities/capabilities/hints.js +0 -223
  329. package/dist/src/capabilities/capabilities/hints.js.map +0 -1
  330. package/src/capabilities/capabilities/hints.ts +0 -266
@@ -438,7 +438,7 @@ describe("capability commands (PROTECTED)", () => {
438
438
  it("no command quoted in capability prose is a bare literal", () => {
439
439
  // The other half of the same promise, and the half the position rule cannot
440
440
  // reach: an empty-state hint, a recovery MESSAGE (the second argument to
441
- // `cliRecovery`, beside a first argument the position rule already covers),
441
+ // `callRecovery`, beside a first argument the position rule already covers),
442
442
  // a `sources status` headline, a wizard step's title. They reach the same
443
443
  // user with the same instruction, and seven of them named this distribution
444
444
  // while the rule above reported zero exemptions.
@@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest";
2
2
  import { ISSUES_URL } from "../../constants.js";
3
3
  import { errorEnvelope, successEnvelope } from "../render/envelope.js";
4
4
  import { PragmaError } from "./PragmaError.js";
5
- import { cliRecovery } from "./recovery.js";
5
+ import { callRecovery } from "./recovery.js";
6
6
  import { serializeError } from "./serialize.js";
7
7
 
8
8
  describe("PragmaError factories", () => {
@@ -76,13 +76,17 @@ describe("serializeError", () => {
76
76
  it("includes suggestions, recovery, validOptions, and filters when present", () => {
77
77
  const error = PragmaError.notFound("block", "Buton", {
78
78
  suggestions: ["Button"],
79
- recovery: cliRecovery("block list", "List blocks."),
79
+ recovery: callRecovery({ verb: "block list" }, "List blocks."),
80
80
  });
81
81
  expect(serializeError(error)).toEqual({
82
82
  code: "ENTITY_NOT_FOUND",
83
83
  message: 'block "Buton" not found.',
84
84
  suggestions: ["Button"],
85
- recovery: { cli: "pragma block list", message: "List blocks." },
85
+ recovery: {
86
+ cli: "pragma block list",
87
+ message: "List blocks.",
88
+ mcp: { tool: "block_list", params: {} },
89
+ },
86
90
  });
87
91
  });
88
92
  });
@@ -8,7 +8,7 @@
8
8
 
9
9
  export { ERROR_CODES } from "./constants.js";
10
10
  export { PragmaError } from "./PragmaError.js";
11
- export { cliRecovery } from "./recovery.js";
11
+ export { callRecovery } from "./recovery.js";
12
12
  export {
13
13
  renderErrorJson,
14
14
  renderErrorLlm,
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { RECOVERY_CLI_PREFIX } from "../../constants.js";
3
- import { cliRecovery } from "./recovery.js";
3
+ import { callRecovery } from "./recovery.js";
4
4
 
5
5
  describe("recovery.cli invariant (D5)", () => {
6
6
  it("carries the shipped distribution's recovery prefix", () => {
@@ -11,27 +11,61 @@ describe("recovery.cli invariant (D5)", () => {
11
11
  expect(RECOVERY_CLI_PREFIX).toBe("pragma ");
12
12
  });
13
13
 
14
- it("prepends the distribution's prefix to the command it is given", () => {
15
- // The caller passes the SUFFIX, so a hint naming the wrong binary is
16
- // unwritable rather than merely asserted against. What replaced the deleted
17
- // `assertRecoveryCli` is `kernel/copy.test.ts`'s position rule, which sees
18
- // the raw `cli:` literals that never reached this function at all — the only
19
- // place a wrong prefix was ever actually written.
20
- expect(cliRecovery("config show", "See the resolved config.")).toEqual({
21
- cli: "pragma config show",
22
- message: "See the resolved config.",
14
+ it("derives both spellings from the one call it is given", () => {
15
+ // The caller names a CALL, so a hint naming the wrong binary — or a CLI
16
+ // string and an MCP hint that disagree about an argument — is unwritable
17
+ // rather than merely asserted against. `kernel/copy.test.ts`'s position
18
+ // rule still sees the raw `cli:` literals that never reach this function.
19
+ expect(
20
+ callRecovery(
21
+ { verb: "config unset", params: { key: "tier" } },
22
+ "Clear the field.",
23
+ ),
24
+ ).toEqual({
25
+ cli: "pragma config unset tier",
26
+ message: "Clear the field.",
27
+ // A mutating tool is plan-first: the recovery never carries `confirm`.
28
+ mcp: { tool: "config_unset", params: { key: "tier" } },
23
29
  });
24
30
  });
25
31
 
26
- it("carries an MCP tool alongside the command when one is given", () => {
32
+ it("spells a flag, quotes what a shell would split, and repeats a variadic positional", () => {
27
33
  expect(
28
- cliRecovery("sources update", "Build the store.", {
29
- tool: "sources_update",
30
- }),
31
- ).toEqual({
32
- cli: "pragma sources update",
33
- message: "Build the store.",
34
- mcp: { tool: "sources_update" },
34
+ callRecovery(
35
+ { verb: "token consumers", params: { symbol: "color.text" } },
36
+ "m",
37
+ ).cli,
38
+ ).toBe("pragma token consumers --symbol color.text");
39
+ expect(
40
+ callRecovery(
41
+ { verb: "graph query", params: { sparql: "ASK { ?s ?p 'x' }" } },
42
+ "m",
43
+ ).cli,
44
+ ).toBe("pragma graph query 'ASK { ?s ?p '\\''x'\\'' }'");
45
+ expect(
46
+ callRecovery(
47
+ { verb: "block lookup", params: { name: ["Button", "Card"] } },
48
+ "m",
49
+ ).cli,
50
+ ).toBe("pragma block lookup Button Card");
51
+ expect(
52
+ callRecovery(
53
+ { verb: "sources update", params: { skipInvalid: true } },
54
+ "m",
55
+ ).cli,
56
+ ).toBe("pragma sources update --skip-invalid");
57
+ expect(
58
+ callRecovery(
59
+ { verb: "sources update", params: { skipInvalid: false } },
60
+ "m",
61
+ ).cli,
62
+ ).toBe("pragma sources update");
63
+ });
64
+
65
+ it("names no MCP tool for a verb withheld from MCP", () => {
66
+ expect(callRecovery({ verb: "version" }, "See the version.")).toEqual({
67
+ cli: "pragma version",
68
+ message: "See the version.",
35
69
  });
36
70
  });
37
71
  });
@@ -1,58 +1,37 @@
1
1
  /**
2
- * The recovery-string invariant (D5).
2
+ * The recovery invariant (D5): a `recovery.cli` hint quotes a command the
3
+ * installed binary answers to, so it begins with {@link RECOVERY_CLI_PREFIX}.
3
4
  *
4
- * A `recovery.cli` hint quotes a command the installed binary answers to, so it
5
- * must begin with {@link RECOVERY_CLI_PREFIX} — the distribution's own `name`
6
- * plus a space. {@link cliRecovery} takes the command SUFFIX and prepends the
7
- * prefix itself, so a hint that names the wrong binary is unwritable rather
8
- * than merely detected. That is why there is no assertion here: an assertion
9
- * over a string the caller composed from the prefix cannot fail, and the hints
10
- * that were actually wrong were raw `cli:` object literals that never reached
11
- * this function at all. `kernel/copy.test.ts` covers those, at the position.
12
- *
13
- * A THIRD authoring route is also legal and reached by NEITHER guard: a `cli`
14
- * DERIVED from the program's own name at the call site. One site does this —
15
- * the create mount (`capabilities/create/mount.ts`,
16
- * `[...detail.chain, suggestion].join(" ")`), whose `chain[0]` is the root
17
- * Commander program's name, `BIN_NAME` by wiring. It bypasses
18
- * {@link cliRecovery}, and the position rule is structurally blind to it (it
19
- * flags QUOTED literals containing the distribution's name, never a computed
20
- * expression) — so D5 holds there by derivation, and the derivation is pinned
21
- * where the value surfaces: `createGrammar.test.ts` COMPOSES its expected
22
- * `cli` from {@link RECOVERY_CLI_PREFIX}, so a renamed root program reddens
23
- * the cell naming the constant. (A separate `startsWith` assertion cannot
24
- * pin it — behind an exact pin of the same value it has no reachable
25
- * failing input.)
26
- *
27
- * `kernel/packs/schema.ts` holds a user-authored pack's `emptyRecovery.cli` to
28
- * the same shape from the other side — it must NOT carry a prefix, because the
29
- * consuming distribution's renderer supplies one.
5
+ * {@link callRecovery} takes a CALL and the one call renderer spells it, prefix
6
+ * included, so a hint naming the wrong binary — or a `cli` and an `mcp` that
7
+ * disagree — is unwritable. Two routes do not pass through here:
8
+ * raw `cli:` object literals (`kernel/copy.test.ts` polices those at the
9
+ * position), and the create mount, which DERIVES its `cli` from the root
10
+ * program's name (`capabilities/create/mount.ts`; pinned by
11
+ * `createGrammar.test.ts`, whose expectation is composed from the prefix).
12
+ * A pack's `emptyRecovery.call` is held to the same shape from the other side
13
+ * by `kernel/packs/schema.ts`: a verb path, never a binary name.
30
14
  */
31
15
 
32
- import { RECOVERY_CLI_PREFIX } from "../../constants.js";
16
+ import { callTool, renderCall } from "../spec/call.js";
17
+ import type { Call } from "../spec/types.js";
33
18
  import type { Recovery } from "./types.js";
34
19
 
35
20
  /**
36
- * Build a {@link Recovery} whose `cli` command carries the distribution's own
37
- * prefix, optionally pairing it with an MCP tool an agent can call.
21
+ * Build a {@link Recovery} from the call that recovers.
38
22
  *
39
- * A recovery may need to speak to BOTH surfaces: the `cli` string guides a human,
40
- * while `mcp` names the tool an agent invokes (an agent cannot run a shell
41
- * command). The single human `message` is shared by both.
23
+ * A recovery speaks to BOTH surfaces: `cli` guides a person, while `mcp` names
24
+ * the tool an agent invokes (an agent cannot run a shell command). Both derive
25
+ * from the one call, so they cannot disagree about the verb or its arguments;
26
+ * `mcp` is absent only when the verb is withheld from MCP. Neither spelling
27
+ * ever carries `confirm`: a mutating tool is plan-first, and the plan it
28
+ * returns says how to proceed.
42
29
  *
43
- * @param command - The recovery command WITHOUT the binary name (`sources update`).
30
+ * @param call - The verb to run and the params to run it with.
44
31
  * @param message - Human-readable guidance shown alongside the command.
45
- * @param mcp - The MCP tool (and optional params) an agent calls to recover.
46
- * @returns A recovery hint whose `cli` names this distribution's binary.
32
+ * @returns A recovery hint carrying the call in both spellings.
47
33
  */
48
- export function cliRecovery(
49
- command: string,
50
- message: string,
51
- mcp?: Recovery["mcp"],
52
- ): Recovery {
53
- return {
54
- message,
55
- cli: `${RECOVERY_CLI_PREFIX}${command}`,
56
- ...(mcp ? { mcp } : {}),
57
- };
34
+ export function callRecovery(call: Call, message: string): Recovery {
35
+ const mcp = callTool(call);
36
+ return { message, cli: renderCall(call, "cli"), ...(mcp ? { mcp } : {}) };
58
37
  }
@@ -16,7 +16,7 @@ type ErrorCode = (typeof ERROR_CODES)[number];
16
16
  *
17
17
  * `cli` — when present — is the command as a user would type it: this
18
18
  * distribution's own bin name (`RECOVERY_CLI_PREFIX`) plus a grammar path (D5).
19
- * `cliRecovery` takes the path alone and prepends the prefix, so there is no
19
+ * `callRecovery` takes the path alone and prepends the prefix, so there is no
20
20
  * assertion to make; the one COMPUTED producer (the create mount) derives
21
21
  * the prefix from the program's own name, pinned by a test expectation
22
22
  * COMPOSED from `RECOVERY_CLI_PREFIX` — the routes are enumerated in the
@@ -19,6 +19,7 @@ import type { CapabilityModule, VerbSpec } from "../spec/types.js";
19
19
  import {
20
20
  assembleEffectiveModules,
21
21
  loadEffectiveModules,
22
+ migrateLegacyRecoveries,
22
23
  validateStories,
23
24
  } from "./collect.js";
24
25
  import { assertUniqueVerbs } from "./uniqueness.js";
@@ -210,6 +211,84 @@ describe("validateStories — package stories NEVER throw (PROTECTED)", () => {
210
211
  ]);
211
212
  });
212
213
 
214
+ it("carries a package story's retired emptyRecovery.cli forward instead of losing the noun", () => {
215
+ // A pack built before the grammar changed still has `cli` on disk. The
216
+ // project config gets a hard error for it (its author can rename the key);
217
+ // a package is third-party data, so the hint is migrated when it IS a verb
218
+ // path and otherwise only the hint is dropped — never the noun.
219
+ const withCli = (noun: string, cli: string) => ({
220
+ noun,
221
+ list: {
222
+ ...validPack(noun).list,
223
+ emptyRecovery: { message: "None yet.", cli },
224
+ },
225
+ verbs: [
226
+ {
227
+ ...validPack(noun).list,
228
+ verb: "extras",
229
+ emptyRecovery: { message: "None yet.", cli },
230
+ },
231
+ ],
232
+ });
233
+ const result = validateStories(
234
+ [
235
+ record(
236
+ "pkg/stories/recipe.json",
237
+ JSON.stringify(withCli("recipe", "sources update")),
238
+ ),
239
+ record(
240
+ "pkg/stories/menu.json",
241
+ JSON.stringify(withCli("menu", "acme sources update --all")),
242
+ ),
243
+ ],
244
+ STATIC,
245
+ );
246
+ const [recipe, menu] = result.entries.map((entry) => entry.definition);
247
+ expect(recipe?.list?.emptyRecovery).toEqual({
248
+ message: "None yet.",
249
+ call: { verb: "sources update" },
250
+ });
251
+ expect(recipe?.verbs?.at(0)?.emptyRecovery?.call).toEqual({
252
+ verb: "sources update",
253
+ });
254
+ // Not a verb path: the story survives, the hint does not, and doctor hears.
255
+ expect(menu?.noun).toBe("menu");
256
+ expect(menu?.list?.emptyRecovery).toEqual({ message: "None yet." });
257
+ expect(result.problems.map((problem) => problem.source)).toEqual([
258
+ "pkg/stories/menu.json",
259
+ "pkg/stories/menu.json",
260
+ ]);
261
+ expect(result.problems.at(0)?.message).toMatch(
262
+ /story is kept.*emptyRecovery\.cli.*emptyRecovery\.call/,
263
+ );
264
+ });
265
+
266
+ it("leaves a story with nothing to migrate, and a non-object, untouched", () => {
267
+ const story = validPack("recipe");
268
+ expect(migrateLegacyRecoveries(story)).toEqual({ raw: story, dropped: [] });
269
+ expect(migrateLegacyRecoveries("nope")).toEqual({
270
+ raw: "nope",
271
+ dropped: [],
272
+ });
273
+ // A half that already names a call keeps it; the stale `cli` beside it goes.
274
+ const both = {
275
+ message: "m",
276
+ cli: "doctor",
277
+ call: { verb: "sources update" },
278
+ };
279
+ expect(
280
+ migrateLegacyRecoveries({ noun: "x", verbs: [{ emptyRecovery: both }] }),
281
+ ).toEqual({
282
+ raw: {
283
+ noun: "x",
284
+ verbs: [
285
+ { emptyRecovery: { message: "m", call: { verb: "sources update" } } },
286
+ ],
287
+ },
288
+ dropped: [],
289
+ });
290
+ });
291
+
213
292
  it("last declaration wins for a noun, and the shadowed file is reported", () => {
214
293
  const result = validateStories(
215
294
  [
@@ -28,9 +28,11 @@ import type { ConfigLayers } from "../config/index.js";
28
28
  import { PragmaError } from "../error/index.js";
29
29
  import type { PackStoryRecord } from "../runtime/graphpack/stories.js";
30
30
  import type { CapabilityModule } from "../spec/index.js";
31
- import { compileStoryModule } from "./compile.js";
31
+ import { compileStoryModule, storyOf } from "./compile.js";
32
32
  import { parsePackDefinition } from "./schema.js";
33
- import type { PackDefinition, PackEntry } from "./types.js";
33
+ import { nounsNamed } from "./storyRules.js";
34
+ import type { NounLookups, PackDefinition, PackEntry } from "./types.js";
35
+ import { VERB_PATH_PATTERN } from "./types.js";
34
36
  import { assertUniqueVerbs } from "./uniqueness.js";
35
37
 
36
38
  /** One package-declared story that could not be used, and why. */
@@ -83,10 +85,14 @@ export function validateStories(
83
85
  const problems: StoryProblem[] = [];
84
86
  for (const record of records) {
85
87
  try {
86
- const definition = parsePackDefinition(
87
- JSON.parse(record.content),
88
- record.source,
89
- );
88
+ const migrated = migrateLegacyRecoveries(JSON.parse(record.content));
89
+ for (const hint of migrated.dropped) {
90
+ problems.push({
91
+ source: record.source,
92
+ message: `its story is kept, but its emptyRecovery.cli hint "${hint}" is not a verb path and was dropped; the key is now emptyRecovery.call.`,
93
+ });
94
+ }
95
+ const definition = parsePackDefinition(migrated.raw, record.source);
90
96
  if (reserved.has(definition.noun)) {
91
97
  problems.push({
92
98
  source: record.source,
@@ -112,6 +118,55 @@ export function validateStories(
112
118
  return { entries: [...byNoun.values()], problems };
113
119
  }
114
120
 
121
+ /**
122
+ * Carry a PACKAGE story written against the old grammar forward.
123
+ *
124
+ * `emptyRecovery.cli: "sources update"` became `emptyRecovery.call: { verb }`. A
125
+ * project's own config gets the hard error that names the change — its author
126
+ * can fix it. A package is third-party data, often already built into a pack on
127
+ * disk, and refusing the key would cost the user the whole noun for the sake of
128
+ * a hint. So the old string becomes a call when it IS a verb path, and
129
+ * otherwise only the hint is dropped, reported once under `doctor`.
130
+ *
131
+ * @param raw - The parsed story JSON (untrusted; returned unchanged when it
132
+ * carries no legacy key).
133
+ * @returns The story to validate, and the legacy hints that could not be kept.
134
+ */
135
+ export function migrateLegacyRecoveries(raw: unknown): {
136
+ raw: unknown;
137
+ dropped: string[];
138
+ } {
139
+ const dropped: string[] = [];
140
+ const migrateHalf = (half: unknown): unknown => {
141
+ const recovery = (
142
+ half as { emptyRecovery?: Record<string, unknown> } | null
143
+ )?.emptyRecovery;
144
+ if (typeof recovery?.cli !== "string") return half;
145
+ const { cli, ...rest } = recovery;
146
+ const keep = VERB_PATH_PATTERN.test(cli);
147
+ if (!keep) dropped.push(cli);
148
+ return {
149
+ ...(half as object),
150
+ emptyRecovery:
151
+ keep && rest.call === undefined
152
+ ? { ...rest, call: { verb: cli } }
153
+ : rest,
154
+ };
155
+ };
156
+ if (typeof raw !== "object" || raw === null) return { raw, dropped };
157
+ const story = raw as { list?: unknown; verbs?: unknown };
158
+ return {
159
+ raw: {
160
+ ...story,
161
+ ...(story.list === undefined ? {} : { list: migrateHalf(story.list) }),
162
+ ...(Array.isArray(story.verbs)
163
+ ? { verbs: story.verbs.map(migrateHalf) }
164
+ : {}),
165
+ },
166
+ dropped,
167
+ };
168
+ }
169
+
115
170
  /**
116
171
  * The PROJECT's config-declared stories, weakest tier first.
117
172
  *
@@ -147,8 +202,8 @@ function projectStoryTiers(layers: ConfigLayers): readonly unknown[][] {
147
202
  * carries (see {@link validateStories}); weaker than either config tier.
148
203
  * @returns The effective modules, uniqueness-checked.
149
204
  * @throws PragmaError CONFIG_ERROR on an invalid CONFIG story, a config story
150
- * claiming an authored non-story noun, or a duplicate noun within one config
151
- * tier. Package stories were already screened and never throw here.
205
+ * claiming an authored non-story noun, a duplicate noun within one config
206
+ * tier, or a config or shipped story naming a noun no story declares. Package stories were already screened and never throw here.
152
207
  */
153
208
  export function assembleEffectiveModules(
154
209
  staticModules: readonly CapabilityModule[],
@@ -171,6 +226,19 @@ export function assembleEffectiveModules(
171
226
  // Keyed by noun so the stronger tier REPLACES the weaker one — declaring a
172
227
  // story both on its pack and at the top level is a refinement, not an error.
173
228
  const dynamic = new Map<string, CapabilityModule>();
229
+ // The EFFECTIVE lookup of a noun, for shipped and project stories alike.
230
+ // Read at run time, so it sees every tier whatever order they compile in.
231
+ const nouns: NounLookups = (noun) => {
232
+ const module =
233
+ dynamic.get(noun) ?? staticModules.find((m) => m.name === noun);
234
+ const story = module && storyOf(module);
235
+ if (story && !story.definition.lookup) {
236
+ throw PragmaError.configError(
237
+ `The "${noun}" story in ${story.source.label} declares no lookup, so a filter that takes a ${noun} cannot resolve its value. Add a lookup to that story.`,
238
+ );
239
+ }
240
+ return story?.definition.lookup;
241
+ };
174
242
  for (const entry of packageStories) {
175
243
  dynamic.set(
176
244
  entry.definition.noun,
@@ -178,6 +246,7 @@ export function assembleEffectiveModules(
178
246
  entry.definition,
179
247
  { label: entry.source, origin: "package" },
180
248
  prefixes,
249
+ nouns,
181
250
  ),
182
251
  );
183
252
  }
@@ -205,6 +274,7 @@ export function assembleEffectiveModules(
205
274
  definition,
206
275
  { label: "config", origin: "config" },
207
276
  prefixes,
277
+ nouns,
208
278
  ),
209
279
  );
210
280
  }
@@ -212,12 +282,79 @@ export function assembleEffectiveModules(
212
282
 
213
283
  // Drop the static module for any noun a config story overrides, then append
214
284
  // the dynamic modules.
215
- const kept = staticModules.filter((module) => !dynamic.has(module.name));
285
+ const kept = staticModules
286
+ .filter((module) => !dynamic.has(module.name))
287
+ // Recompiled so a shipped filter naming an overridden noun resolves
288
+ // through the project's lookup, as the project's own stories do.
289
+ .map((module) => {
290
+ const story = storyOf(module);
291
+ return story
292
+ ? compileStoryModule(
293
+ story.definition,
294
+ story.source,
295
+ story.prefixes,
296
+ nouns,
297
+ )
298
+ : module;
299
+ });
216
300
  const effective = [...kept, ...dynamic.values()];
301
+ // A noun some story declares without a lookup is refused when a filter on it
302
+ // is used, not here: only a noun NO story declares is a declaration error.
303
+ // Package stories never throw; {@link screenPackageStories} drops them.
304
+ for (const module of effective) {
305
+ const story = storyOf(module);
306
+ const unknown =
307
+ story && story.source.origin !== "package"
308
+ ? undeclaredNoun(story.definition, effective)
309
+ : undefined;
310
+ if (story && unknown) {
311
+ throw PragmaError.configError(
312
+ `Invalid story in ${story.source.label}: "${module.name}" names the noun "${unknown}", and no story declares it.`,
313
+ );
314
+ }
315
+ }
217
316
  assertUniqueVerbs(effective.flatMap((module) => [...module.verbs]));
218
317
  return effective;
219
318
  }
220
319
 
320
+ /** The first noun a story names that no effective story declares. */
321
+ function undeclaredNoun(
322
+ definition: PackDefinition,
323
+ effective: readonly CapabilityModule[],
324
+ ): string | undefined {
325
+ return nounsNamed(definition).find(
326
+ (noun) => !effective.some((m) => m.name === noun && storyOf(m)),
327
+ );
328
+ }
329
+
330
+ /**
331
+ * Drop each PACKAGE story naming a noun no effective story declares, reporting
332
+ * it — judged over the assembled set, so the order of declaration is nothing.
333
+ *
334
+ * @param effective - The assembled modules.
335
+ * @returns The modules kept, and one problem per story dropped.
336
+ */
337
+ export function screenPackageStories(effective: readonly CapabilityModule[]): {
338
+ readonly modules: readonly CapabilityModule[];
339
+ readonly problems: readonly StoryProblem[];
340
+ } {
341
+ const problems: StoryProblem[] = [];
342
+ const modules = effective.filter((module) => {
343
+ const story = storyOf(module);
344
+ const unknown =
345
+ story?.source.origin === "package"
346
+ ? undeclaredNoun(story.definition, effective)
347
+ : undefined;
348
+ if (!story || unknown === undefined) return true;
349
+ problems.push({
350
+ source: story.source.label,
351
+ message: `it names the noun "${unknown}", and no story declares it.`,
352
+ });
353
+ return false;
354
+ });
355
+ return { modules: problems.length === 0 ? effective : modules, problems };
356
+ }
357
+
221
358
  /**
222
359
  * Load the effective modules for a real invocation: read the layered config and
223
360
  * the answering pack's carried stories, and merge both into the static
@@ -252,8 +389,11 @@ export async function loadEffectiveModules(
252
389
  activeStories(resolveSources(layers, cwd)),
253
390
  staticModules,
254
391
  );
392
+ const screened = screenPackageStories(
393
+ assembleEffectiveModules(staticModules, layers, entries),
394
+ );
255
395
  return {
256
- modules: assembleEffectiveModules(staticModules, layers, entries),
257
- problems,
396
+ modules: screened.modules,
397
+ problems: [...problems, ...screened.problems],
258
398
  };
259
399
  }