@intentius/chant 0.124.52 → 0.124.54

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 (584) hide show
  1. package/dist/audit/discover.d.ts.map +1 -1
  2. package/dist/audit/discover.js +3 -1
  3. package/dist/behaviour.d.ts +1 -1
  4. package/dist/behaviour.d.ts.map +1 -1
  5. package/dist/capabilities/templates.d.ts +65 -0
  6. package/dist/capabilities/templates.d.ts.map +1 -0
  7. package/dist/capabilities/templates.js +193 -0
  8. package/dist/capabilities/templates.json +145 -0
  9. package/dist/change-set-graph.d.ts +35 -3
  10. package/dist/change-set-graph.d.ts.map +1 -1
  11. package/dist/change-set-graph.js +60 -9
  12. package/dist/change-set.d.ts +65 -7
  13. package/dist/change-set.d.ts.map +1 -1
  14. package/dist/change-set.js +23 -12
  15. package/dist/ci-identity.d.ts +7 -2
  16. package/dist/ci-identity.d.ts.map +1 -1
  17. package/dist/ci-identity.js +4 -1
  18. package/dist/cli/commands/import-index.d.ts +52 -0
  19. package/dist/cli/commands/import-index.d.ts.map +1 -0
  20. package/dist/cli/commands/import-index.js +226 -0
  21. package/dist/cli/commands/lint.d.ts.map +1 -1
  22. package/dist/cli/commands/lint.js +4 -2
  23. package/dist/cli/handlers/components.d.ts.map +1 -1
  24. package/dist/cli/handlers/components.js +11 -2
  25. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  26. package/dist/cli/handlers/fan-out.js +16 -3
  27. package/dist/cli/handlers/graph.d.ts.map +1 -1
  28. package/dist/cli/handlers/graph.js +22 -4
  29. package/dist/cli/handlers/index-cloud.d.ts +14 -0
  30. package/dist/cli/handlers/index-cloud.d.ts.map +1 -0
  31. package/dist/cli/handlers/index-cloud.js +22 -0
  32. package/dist/cli/handlers/index-diff.d.ts +18 -0
  33. package/dist/cli/handlers/index-diff.d.ts.map +1 -0
  34. package/dist/cli/handlers/index-diff.js +142 -0
  35. package/dist/cli/handlers/lifecycle-drift.d.ts +25 -0
  36. package/dist/cli/handlers/lifecycle-drift.d.ts.map +1 -0
  37. package/dist/cli/handlers/lifecycle-drift.js +64 -0
  38. package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
  39. package/dist/cli/handlers/lifecycle.js +188 -28
  40. package/dist/cli/handlers/misc.d.ts +9 -0
  41. package/dist/cli/handlers/misc.d.ts.map +1 -1
  42. package/dist/cli/handlers/misc.js +77 -0
  43. package/dist/cli/handlers/pr.d.ts.map +1 -1
  44. package/dist/cli/handlers/pr.js +15 -2
  45. package/dist/cli/handlers/promote.d.ts.map +1 -1
  46. package/dist/cli/handlers/promote.js +89 -15
  47. package/dist/cli/handlers/query.d.ts.map +1 -1
  48. package/dist/cli/handlers/query.js +28 -4
  49. package/dist/cli/handlers/scenario.d.ts.map +1 -1
  50. package/dist/cli/handlers/scenario.js +8 -7
  51. package/dist/cli/handlers/search.d.ts +34 -4
  52. package/dist/cli/handlers/search.d.ts.map +1 -1
  53. package/dist/cli/handlers/search.js +216 -36
  54. package/dist/cli/main.d.ts.map +1 -1
  55. package/dist/cli/main.js +55 -1
  56. package/dist/cli/mcp/lifecycle-tools.d.ts.map +1 -1
  57. package/dist/cli/mcp/lifecycle-tools.js +3 -2
  58. package/dist/cli/mcp/resource-handlers.d.ts.map +1 -1
  59. package/dist/cli/mcp/resource-handlers.js +4 -3
  60. package/dist/cli/mcp/workspace-tools.js +1 -1
  61. package/dist/cli/parse-args.d.ts.map +1 -1
  62. package/dist/cli/parse-args.js +55 -2
  63. package/dist/cli/registry.d.ts +19 -1
  64. package/dist/cli/registry.d.ts.map +1 -1
  65. package/dist/cloud-lister/aws.d.ts +35 -0
  66. package/dist/cloud-lister/aws.d.ts.map +1 -0
  67. package/dist/cloud-lister/aws.js +203 -0
  68. package/dist/cloud-lister/azure.d.ts +34 -0
  69. package/dist/cloud-lister/azure.d.ts.map +1 -0
  70. package/dist/cloud-lister/azure.js +129 -0
  71. package/dist/cloud-lister/common.d.ts +40 -0
  72. package/dist/cloud-lister/common.d.ts.map +1 -0
  73. package/dist/cloud-lister/common.js +83 -0
  74. package/dist/cloud-lister/credentials.d.ts +50 -0
  75. package/dist/cloud-lister/credentials.d.ts.map +1 -0
  76. package/dist/cloud-lister/credentials.js +86 -0
  77. package/dist/cloud-lister/fakes.d.ts +27 -0
  78. package/dist/cloud-lister/fakes.d.ts.map +1 -0
  79. package/dist/cloud-lister/fakes.js +50 -0
  80. package/dist/cloud-lister/gcp.d.ts +42 -0
  81. package/dist/cloud-lister/gcp.d.ts.map +1 -0
  82. package/dist/cloud-lister/gcp.js +143 -0
  83. package/dist/cloud-lister/guard.d.ts +49 -0
  84. package/dist/cloud-lister/guard.d.ts.map +1 -0
  85. package/dist/cloud-lister/guard.js +103 -0
  86. package/dist/cloud-lister/ids.d.ts +23 -0
  87. package/dist/cloud-lister/ids.d.ts.map +1 -0
  88. package/dist/cloud-lister/ids.js +42 -0
  89. package/dist/cloud-lister/index.d.ts +67 -0
  90. package/dist/cloud-lister/index.d.ts.map +1 -0
  91. package/dist/cloud-lister/index.js +102 -0
  92. package/dist/cloud-lister/kubernetes.d.ts +64 -0
  93. package/dist/cloud-lister/kubernetes.d.ts.map +1 -0
  94. package/dist/cloud-lister/kubernetes.js +276 -0
  95. package/dist/cloud-lister/markers.d.ts +31 -0
  96. package/dist/cloud-lister/markers.d.ts.map +1 -0
  97. package/dist/cloud-lister/markers.js +73 -0
  98. package/dist/cloud-lister/mask.d.ts +31 -0
  99. package/dist/cloud-lister/mask.d.ts.map +1 -0
  100. package/dist/cloud-lister/mask.js +74 -0
  101. package/dist/cloud-lister/sigv4.d.ts +29 -0
  102. package/dist/cloud-lister/sigv4.d.ts.map +1 -0
  103. package/dist/cloud-lister/sigv4.js +54 -0
  104. package/dist/cloud-lister/transport.d.ts +55 -0
  105. package/dist/cloud-lister/transport.d.ts.map +1 -0
  106. package/dist/cloud-lister/transport.js +86 -0
  107. package/dist/cloud-lister/types.d.ts +121 -0
  108. package/dist/cloud-lister/types.d.ts.map +1 -0
  109. package/dist/cloud-lister/types.js +24 -0
  110. package/dist/components/capability-plugin-loader.d.ts.map +1 -1
  111. package/dist/components/capability-plugin-loader.js +6 -0
  112. package/dist/components/capability-plugin.d.ts +9 -0
  113. package/dist/components/capability-plugin.d.ts.map +1 -1
  114. package/dist/components/capability.d.ts +215 -0
  115. package/dist/components/capability.d.ts.map +1 -1
  116. package/dist/components/cli-support.d.ts +21 -0
  117. package/dist/components/cli-support.d.ts.map +1 -1
  118. package/dist/components/cli-support.js +58 -14
  119. package/dist/components/declared-reads.d.ts +38 -0
  120. package/dist/components/declared-reads.d.ts.map +1 -0
  121. package/dist/components/declared-reads.js +131 -0
  122. package/dist/components/deploy-units.d.ts.map +1 -1
  123. package/dist/components/deploy-units.js +4 -0
  124. package/dist/components/driver.d.ts +34 -1
  125. package/dist/components/driver.d.ts.map +1 -1
  126. package/dist/components/driver.js +66 -3
  127. package/dist/components/fan-out-run.d.ts +23 -1
  128. package/dist/components/fan-out-run.d.ts.map +1 -1
  129. package/dist/components/fan-out-run.js +82 -14
  130. package/dist/components/fan-out-support.d.ts +6 -0
  131. package/dist/components/fan-out-support.d.ts.map +1 -1
  132. package/dist/components/fan-out-support.js +4 -1
  133. package/dist/components/fan-out.d.ts +28 -0
  134. package/dist/components/fan-out.d.ts.map +1 -1
  135. package/dist/components/groups.d.ts +229 -0
  136. package/dist/components/groups.d.ts.map +1 -0
  137. package/dist/components/groups.js +760 -0
  138. package/dist/components/index.d.ts +6 -2
  139. package/dist/components/index.d.ts.map +1 -1
  140. package/dist/components/index.js +4 -0
  141. package/dist/components/plan-shape-conformance.d.ts +48 -0
  142. package/dist/components/plan-shape-conformance.d.ts.map +1 -0
  143. package/dist/components/plan-shape-conformance.js +122 -0
  144. package/dist/components/pr-run.d.ts +41 -4
  145. package/dist/components/pr-run.d.ts.map +1 -1
  146. package/dist/components/pr-run.js +209 -39
  147. package/dist/components/promote-rounds.d.ts +9 -0
  148. package/dist/components/promote-rounds.d.ts.map +1 -1
  149. package/dist/components/promote-rounds.js +23 -2
  150. package/dist/components/promote.d.ts +17 -0
  151. package/dist/components/promote.d.ts.map +1 -1
  152. package/dist/components/promote.js +36 -6
  153. package/dist/components/release-gate.d.ts +23 -1
  154. package/dist/components/release-gate.d.ts.map +1 -1
  155. package/dist/components/release-gate.js +97 -33
  156. package/dist/components/run-groups.d.ts +58 -0
  157. package/dist/components/run-groups.d.ts.map +1 -0
  158. package/dist/components/run-groups.js +78 -0
  159. package/dist/components/starter-plugin.d.ts +1 -0
  160. package/dist/components/starter-plugin.d.ts.map +1 -1
  161. package/dist/components/starter-plugin.js +6 -1
  162. package/dist/components/verbs/index.d.ts +1 -0
  163. package/dist/components/verbs/index.d.ts.map +1 -1
  164. package/dist/components/verbs/index.js +1 -0
  165. package/dist/components/verbs/member-outputs.d.ts +187 -0
  166. package/dist/components/verbs/member-outputs.d.ts.map +1 -0
  167. package/dist/components/verbs/member-outputs.js +218 -0
  168. package/dist/config.d.ts +60 -0
  169. package/dist/config.d.ts.map +1 -1
  170. package/dist/config.js +27 -0
  171. package/dist/deep-observation.d.ts +1 -13
  172. package/dist/deep-observation.d.ts.map +1 -1
  173. package/dist/deep-observation.js +5 -22
  174. package/dist/drift-record.d.ts +542 -0
  175. package/dist/drift-record.d.ts.map +1 -0
  176. package/dist/drift-record.js +886 -0
  177. package/dist/engine-facts.d.ts +144 -0
  178. package/dist/engine-facts.d.ts.map +1 -0
  179. package/dist/engine-facts.js +14 -0
  180. package/dist/graph-ir.d.ts +153 -2
  181. package/dist/graph-ir.d.ts.map +1 -1
  182. package/dist/graph-ir.js +224 -6
  183. package/dist/graph-refs.d.ts +145 -0
  184. package/dist/graph-refs.d.ts.map +1 -1
  185. package/dist/graph-refs.js +305 -0
  186. package/dist/graph-schema/fixtures/adopt.json +15 -0
  187. package/dist/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
  188. package/dist/graph-schema/fixtures/index.json +68 -0
  189. package/dist/graph-schema/fixtures/plunge.engine-graph.json +158 -0
  190. package/dist/graph-schema/fixtures.d.ts +23 -0
  191. package/dist/graph-schema/fixtures.d.ts.map +1 -0
  192. package/dist/graph-schema/fixtures.js +246 -0
  193. package/dist/graph-schema/generate.d.ts +15 -0
  194. package/dist/graph-schema/generate.d.ts.map +1 -0
  195. package/dist/graph-schema/generate.js +267 -0
  196. package/dist/graph-schema/graph.schema.json +1387 -0
  197. package/dist/health.schema.json +2 -1
  198. package/dist/identity.d.ts.map +1 -1
  199. package/dist/identity.js +2 -0
  200. package/dist/index.d.ts +1 -0
  201. package/dist/index.d.ts.map +1 -1
  202. package/dist/index.js +2 -0
  203. package/dist/instance-nodes.d.ts +159 -0
  204. package/dist/instance-nodes.d.ts.map +1 -0
  205. package/dist/instance-nodes.js +231 -0
  206. package/dist/lexicon.d.ts +72 -0
  207. package/dist/lexicon.d.ts.map +1 -1
  208. package/dist/lifecycle/adoption-file.d.ts +56 -0
  209. package/dist/lifecycle/adoption-file.d.ts.map +1 -0
  210. package/dist/lifecycle/adoption-file.js +123 -0
  211. package/dist/lifecycle/cloud-index.d.ts +186 -0
  212. package/dist/lifecycle/cloud-index.d.ts.map +1 -0
  213. package/dist/lifecycle/cloud-index.js +618 -0
  214. package/dist/lifecycle/derive-edges.d.ts +59 -0
  215. package/dist/lifecycle/derive-edges.d.ts.map +1 -0
  216. package/dist/lifecycle/derive-edges.js +126 -0
  217. package/dist/lifecycle/git.d.ts +10 -9
  218. package/dist/lifecycle/git.d.ts.map +1 -1
  219. package/dist/lifecycle/git.js +7 -1
  220. package/dist/lifecycle/identity-match.d.ts +133 -0
  221. package/dist/lifecycle/identity-match.d.ts.map +1 -0
  222. package/dist/lifecycle/identity-match.js +147 -0
  223. package/dist/lifecycle/index-diff.d.ts +224 -0
  224. package/dist/lifecycle/index-diff.d.ts.map +1 -0
  225. package/dist/lifecycle/index-diff.js +327 -0
  226. package/dist/lifecycle/index-document.d.ts +130 -0
  227. package/dist/lifecycle/index-document.d.ts.map +1 -0
  228. package/dist/lifecycle/index-document.js +189 -0
  229. package/dist/lifecycle/index-drift.d.ts +121 -0
  230. package/dist/lifecycle/index-drift.d.ts.map +1 -0
  231. package/dist/lifecycle/index-drift.js +178 -0
  232. package/dist/lifecycle/index-import.d.ts +168 -0
  233. package/dist/lifecycle/index-import.d.ts.map +1 -0
  234. package/dist/lifecycle/index-import.js +515 -0
  235. package/dist/lifecycle/index-join.d.ts +129 -0
  236. package/dist/lifecycle/index-join.d.ts.map +1 -0
  237. package/dist/lifecycle/index-join.js +248 -0
  238. package/dist/lifecycle/index.d.ts +4 -0
  239. package/dist/lifecycle/index.d.ts.map +1 -1
  240. package/dist/lifecycle/index.js +4 -0
  241. package/dist/lifecycle/observation-baseline.d.ts +61 -21
  242. package/dist/lifecycle/observation-baseline.d.ts.map +1 -1
  243. package/dist/lifecycle/observation-baseline.js +144 -19
  244. package/dist/lifecycle/observe.d.ts.map +1 -1
  245. package/dist/lifecycle/observe.js +6 -1
  246. package/dist/lifecycle/query.d.ts +45 -4
  247. package/dist/lifecycle/query.d.ts.map +1 -1
  248. package/dist/lifecycle/query.js +89 -7
  249. package/dist/lifecycle/replay.d.ts +10 -3
  250. package/dist/lifecycle/replay.d.ts.map +1 -1
  251. package/dist/lifecycle/replay.js +10 -6
  252. package/dist/lifecycle/scenario.d.ts +4 -3
  253. package/dist/lifecycle/scenario.d.ts.map +1 -1
  254. package/dist/lifecycle/snapshot-store-fake.d.ts +9 -0
  255. package/dist/lifecycle/snapshot-store-fake.d.ts.map +1 -0
  256. package/dist/lifecycle/snapshot-store-fake.js +21 -0
  257. package/dist/lifecycle/snapshot-store-s3.d.ts +102 -0
  258. package/dist/lifecycle/snapshot-store-s3.d.ts.map +1 -0
  259. package/dist/lifecycle/snapshot-store-s3.js +254 -0
  260. package/dist/lifecycle/snapshot-store.d.ts +170 -0
  261. package/dist/lifecycle/snapshot-store.d.ts.map +1 -0
  262. package/dist/lifecycle/snapshot-store.js +832 -0
  263. package/dist/lifecycle/snapshot.d.ts +11 -0
  264. package/dist/lifecycle/snapshot.d.ts.map +1 -1
  265. package/dist/lifecycle/snapshot.js +18 -5
  266. package/dist/lifecycle/type-listing.d.ts +148 -0
  267. package/dist/lifecycle/type-listing.d.ts.map +1 -0
  268. package/dist/lifecycle/type-listing.js +166 -0
  269. package/dist/lint/component-checks.d.ts +15 -1
  270. package/dist/lint/component-checks.d.ts.map +1 -1
  271. package/dist/lint/component-checks.js +1 -0
  272. package/dist/lint/presets/relaxed.json +2 -1
  273. package/dist/lint/presets/strict.json +2 -1
  274. package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts +4 -0
  275. package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.d.ts.map +1 -0
  276. package/dist/lint/rules/__fixtures__/comp/comp008/fail/dns.component.js +13 -0
  277. package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts +4 -0
  278. package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.d.ts.map +1 -0
  279. package/dist/lint/rules/__fixtures__/comp/comp008/pass/dns.component.js +8 -0
  280. package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts +33 -0
  281. package/dist/lint/rules/comp/comp008-applies-signal-only-root.d.ts.map +1 -0
  282. package/dist/lint/rules/comp/comp008-applies-signal-only-root.js +123 -0
  283. package/dist/lint/rules/comp/index.d.ts +2 -1
  284. package/dist/lint/rules/comp/index.d.ts.map +1 -1
  285. package/dist/lint/rules/comp/index.js +4 -1
  286. package/dist/observation.d.ts +19 -2
  287. package/dist/observation.d.ts.map +1 -1
  288. package/dist/observation.js +18 -1
  289. package/dist/op/activities/activity-contracts.d.ts +1 -1
  290. package/dist/op/activities/activity-contracts.js +1 -1
  291. package/dist/op/activities/change-set.d.ts +6 -4
  292. package/dist/op/activities/change-set.d.ts.map +1 -1
  293. package/dist/op/activities/change-set.js +4 -2
  294. package/dist/op/activity-failure.d.ts +27 -0
  295. package/dist/op/activity-failure.d.ts.map +1 -1
  296. package/dist/op/activity-failure.js +31 -0
  297. package/dist/op/index.d.ts +2 -1
  298. package/dist/op/index.d.ts.map +1 -1
  299. package/dist/op/index.js +1 -1
  300. package/dist/op/local-executor.d.ts +5 -1
  301. package/dist/op/local-executor.d.ts.map +1 -1
  302. package/dist/op/local-executor.js +22 -8
  303. package/dist/pr-loop.d.ts +56 -1
  304. package/dist/pr-loop.d.ts.map +1 -1
  305. package/dist/pr-loop.js +51 -1
  306. package/dist/pulumi-urn.d.ts +101 -0
  307. package/dist/pulumi-urn.d.ts.map +1 -0
  308. package/dist/pulumi-urn.js +131 -0
  309. package/dist/release-floors.d.ts +23 -0
  310. package/dist/release-floors.d.ts.map +1 -0
  311. package/dist/release-floors.js +22 -0
  312. package/dist/sensitive-key.d.ts +23 -0
  313. package/dist/sensitive-key.d.ts.map +1 -0
  314. package/dist/sensitive-key.js +31 -0
  315. package/dist/wave-runtime.mjs +234 -234
  316. package/dist/workspace/adoption-report.d.ts +53 -0
  317. package/dist/workspace/adoption-report.d.ts.map +1 -0
  318. package/dist/workspace/adoption-report.js +76 -0
  319. package/dist/workspace/capabilities-contract.d.ts +7 -0
  320. package/dist/workspace/capabilities-contract.d.ts.map +1 -1
  321. package/dist/workspace/capabilities-contract.js +2 -1
  322. package/dist/workspace/capabilities.schema.json +98 -0
  323. package/dist/workspace/change-set.schema.json +42 -3
  324. package/dist/workspace/ci-cloud-identity.d.ts +13 -1
  325. package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
  326. package/dist/workspace/ci-cloud-identity.js +30 -1
  327. package/dist/workspace/compose-graph.d.ts +10 -1
  328. package/dist/workspace/compose-graph.d.ts.map +1 -1
  329. package/dist/workspace/compose-graph.js +6 -1
  330. package/dist/workspace/conformance/index.d.ts +1 -1
  331. package/dist/workspace/conformance/index.d.ts.map +1 -1
  332. package/dist/workspace/conformance/index.js +6 -1
  333. package/dist/workspace/drift-cli.d.ts +81 -0
  334. package/dist/workspace/drift-cli.d.ts.map +1 -0
  335. package/dist/workspace/drift-cli.js +317 -0
  336. package/dist/workspace/drift.schema.json +672 -0
  337. package/dist/workspace/graph-cli.d.ts +2 -0
  338. package/dist/workspace/graph-cli.d.ts.map +1 -1
  339. package/dist/workspace/graph-cli.js +3 -0
  340. package/dist/workspace/graph.schema.json +72 -0
  341. package/dist/workspace/init.d.ts +5 -1
  342. package/dist/workspace/init.d.ts.map +1 -1
  343. package/dist/workspace/init.js +55 -9
  344. package/dist/workspace/ledger.schema.json +1 -1
  345. package/dist/workspace/nested-graph.d.ts.map +1 -1
  346. package/dist/workspace/nested-graph.js +2 -0
  347. package/dist/workspace/pr-report.schema.json +51 -2
  348. package/dist/workspace/promote-waves.d.ts +112 -0
  349. package/dist/workspace/promote-waves.d.ts.map +1 -0
  350. package/dist/workspace/promote-waves.js +290 -0
  351. package/dist/workspace/promote.d.ts +84 -2
  352. package/dist/workspace/promote.d.ts.map +1 -1
  353. package/dist/workspace/promote.js +347 -61
  354. package/dist/workspace/reason-codes.d.ts +12 -0
  355. package/dist/workspace/reason-codes.d.ts.map +1 -1
  356. package/dist/workspace/reason-codes.js +14 -0
  357. package/dist/workspace/search-contract.d.ts +3 -3
  358. package/dist/workspace/search-contract.d.ts.map +1 -1
  359. package/dist/workspace/search-contract.js +2 -0
  360. package/dist/workspace/search.schema.json +103 -5
  361. package/package.json +14 -1
  362. package/src/__fixtures__/drift-record/README.md +58 -0
  363. package/src/__fixtures__/drift-record/choudoufu-cone.ndjson +4 -0
  364. package/src/__fixtures__/drift-record/choudoufu-resource.ndjson +3 -0
  365. package/src/__fixtures__/drift-record/component-status-ledger.json +65 -0
  366. package/src/__fixtures__/drift-record/component-status.json +91 -0
  367. package/src/__fixtures__/drift-record/deep-diff.json +259 -0
  368. package/src/__fixtures__/drift-record/lifecycle-diff-live.json +825 -0
  369. package/src/__fixtures__/drift-record/live-diff.json +125 -0
  370. package/src/audit/discover.e2e.test.ts +14 -0
  371. package/src/audit/discover.ts +3 -1
  372. package/src/behaviour.ts +1 -1
  373. package/src/capabilities/templates.json +145 -0
  374. package/src/capabilities/templates.test.ts +212 -0
  375. package/src/capabilities/templates.ts +204 -0
  376. package/src/change-set-bundle.test.ts +83 -0
  377. package/src/change-set-graph.ts +80 -9
  378. package/src/change-set.test.ts +24 -0
  379. package/src/change-set.ts +77 -14
  380. package/src/ci-identity-targets.test.ts +23 -0
  381. package/src/ci-identity.ts +10 -4
  382. package/src/cli/commands/import-index.test.ts +117 -0
  383. package/src/cli/commands/import-index.ts +265 -0
  384. package/src/cli/commands/lint.ts +4 -2
  385. package/src/cli/handlers/components.test.ts +9 -0
  386. package/src/cli/handlers/components.ts +12 -2
  387. package/src/cli/handlers/fan-out.ts +17 -3
  388. package/src/cli/handlers/graph.test.ts +42 -0
  389. package/src/cli/handlers/graph.ts +26 -4
  390. package/src/cli/handlers/index-cloud.ts +32 -0
  391. package/src/cli/handlers/index-diff.test.ts +68 -0
  392. package/src/cli/handlers/index-diff.ts +146 -0
  393. package/src/cli/handlers/ledger-root-member.test.ts +161 -0
  394. package/src/cli/handlers/lifecycle-drift.ts +68 -0
  395. package/src/cli/handlers/lifecycle.test.ts +33 -11
  396. package/src/cli/handlers/lifecycle.ts +205 -30
  397. package/src/cli/handlers/misc.ts +73 -0
  398. package/src/cli/handlers/pr-waves-blocked.test.ts +37 -2
  399. package/src/cli/handlers/pr.ts +14 -2
  400. package/src/cli/handlers/promote.test.ts +64 -0
  401. package/src/cli/handlers/promote.ts +81 -6
  402. package/src/cli/handlers/query.ts +27 -4
  403. package/src/cli/handlers/run-declared-reads-cli.test.ts +187 -0
  404. package/src/cli/handlers/run-groups-cli.test.ts +229 -0
  405. package/src/cli/handlers/scenario.test.ts +13 -0
  406. package/src/cli/handlers/scenario.ts +8 -7
  407. package/src/cli/handlers/search-index.test.ts +255 -0
  408. package/src/cli/handlers/search-json.test.ts +1 -1
  409. package/src/cli/handlers/search-ownership.test.ts +194 -0
  410. package/src/cli/handlers/search.ts +271 -38
  411. package/src/cli/main.test.ts +7 -0
  412. package/src/cli/main.ts +56 -1
  413. package/src/cli/mcp/lifecycle-tools.ts +3 -2
  414. package/src/cli/mcp/resource-handlers.ts +4 -3
  415. package/src/cli/mcp/workspace-tools.ts +1 -1
  416. package/src/cli/parse-args.ts +40 -2
  417. package/src/cli/registry.ts +19 -1
  418. package/src/cloud-lister/aws.test.ts +202 -0
  419. package/src/cloud-lister/aws.ts +226 -0
  420. package/src/cloud-lister/azure.test.ts +132 -0
  421. package/src/cloud-lister/azure.ts +142 -0
  422. package/src/cloud-lister/common.ts +115 -0
  423. package/src/cloud-lister/credentials.ts +110 -0
  424. package/src/cloud-lister/fakes.ts +66 -0
  425. package/src/cloud-lister/gcp.test.ts +121 -0
  426. package/src/cloud-lister/gcp.ts +159 -0
  427. package/src/cloud-lister/guard.test.ts +198 -0
  428. package/src/cloud-lister/guard.ts +111 -0
  429. package/src/cloud-lister/ids.ts +54 -0
  430. package/src/cloud-lister/index.ts +134 -0
  431. package/src/cloud-lister/kubernetes.test.ts +160 -0
  432. package/src/cloud-lister/kubernetes.ts +284 -0
  433. package/src/cloud-lister/markers.ts +74 -0
  434. package/src/cloud-lister/mask.ts +77 -0
  435. package/src/cloud-lister/shape.test.ts +81 -0
  436. package/src/cloud-lister/sigv4.ts +70 -0
  437. package/src/cloud-lister/transport.ts +118 -0
  438. package/src/cloud-lister/types.ts +135 -0
  439. package/src/components/capability-plugin-loader.ts +4 -0
  440. package/src/components/capability-plugin.ts +10 -0
  441. package/src/components/capability.ts +229 -0
  442. package/src/components/cli-support.ts +70 -14
  443. package/src/components/declared-reads.test.ts +103 -0
  444. package/src/components/declared-reads.ts +134 -0
  445. package/src/components/deploy-units.ts +4 -0
  446. package/src/components/driver.ts +89 -4
  447. package/src/components/fan-out-run.ts +95 -15
  448. package/src/components/fan-out-support.ts +10 -1
  449. package/src/components/fan-out.ts +30 -0
  450. package/src/components/groups.test.ts +320 -0
  451. package/src/components/groups.ts +880 -0
  452. package/src/components/index.ts +42 -0
  453. package/src/components/plan-shape-conformance.ts +130 -0
  454. package/src/components/pr-env-run-bundle.test.ts +2 -0
  455. package/src/components/pr-run.test.ts +516 -3
  456. package/src/components/pr-run.ts +231 -41
  457. package/src/components/promote-rounds.ts +25 -2
  458. package/src/components/promote.ts +55 -5
  459. package/src/components/registry.test.ts +1 -1
  460. package/src/components/release-gate.ts +115 -30
  461. package/src/components/release-groups.test.ts +362 -0
  462. package/src/components/run-groups.ts +113 -0
  463. package/src/components/starter-plugin.ts +6 -0
  464. package/src/components/verbs/index.ts +1 -0
  465. package/src/components/verbs/member-outputs.test.ts +205 -0
  466. package/src/components/verbs/member-outputs.ts +308 -0
  467. package/src/config.ts +44 -0
  468. package/src/deep-observation.ts +5 -23
  469. package/src/drift-record.test.ts +596 -0
  470. package/src/drift-record.ts +1206 -0
  471. package/src/engine-facts.guard.test.ts +111 -0
  472. package/src/engine-facts.test.ts +178 -0
  473. package/src/engine-facts.ts +154 -0
  474. package/src/gated-waves-bundle.test.ts +2 -0
  475. package/src/graph-ir-live.test.ts +92 -0
  476. package/src/graph-ir.ts +317 -7
  477. package/src/graph-refs.ts +416 -0
  478. package/src/graph-schema/fixtures/adopt.json +15 -0
  479. package/src/graph-schema/fixtures/choudoufu.engine-graph.json +169 -0
  480. package/src/graph-schema/fixtures/index.json +68 -0
  481. package/src/graph-schema/fixtures/plunge.engine-graph.json +158 -0
  482. package/src/graph-schema/fixtures.ts +267 -0
  483. package/src/graph-schema/generate.ts +263 -0
  484. package/src/graph-schema/graph-schema.test.ts +153 -0
  485. package/src/graph-schema/graph.schema.json +1387 -0
  486. package/src/health.schema.json +2 -1
  487. package/src/identity.ts +2 -0
  488. package/src/index.ts +2 -0
  489. package/src/instance-nodes.ts +288 -0
  490. package/src/lexicon.ts +76 -0
  491. package/src/lifecycle/__fixtures__/index-diff/20261026T120000Z-aaaaaaaaaaaa.json +149 -0
  492. package/src/lifecycle/__fixtures__/index-diff/20261026T130000Z-bbbbbbbbbbbb.json +127 -0
  493. package/src/lifecycle/adoption-file.test.ts +100 -0
  494. package/src/lifecycle/adoption-file.ts +154 -0
  495. package/src/lifecycle/cloud-index.test.ts +517 -0
  496. package/src/lifecycle/cloud-index.ts +736 -0
  497. package/src/lifecycle/derive-edges.test.ts +193 -0
  498. package/src/lifecycle/derive-edges.ts +182 -0
  499. package/src/lifecycle/git.ts +10 -4
  500. package/src/lifecycle/identity-match.test.ts +308 -0
  501. package/src/lifecycle/identity-match.ts +257 -0
  502. package/src/lifecycle/index-diff.test.ts +198 -0
  503. package/src/lifecycle/index-diff.ts +476 -0
  504. package/src/lifecycle/index-document.test.ts +64 -0
  505. package/src/lifecycle/index-document.ts +299 -0
  506. package/src/lifecycle/index-drift.test.ts +191 -0
  507. package/src/lifecycle/index-drift.ts +304 -0
  508. package/src/lifecycle/index-import.test.ts +255 -0
  509. package/src/lifecycle/index-import.ts +634 -0
  510. package/src/lifecycle/index-join.test.ts +250 -0
  511. package/src/lifecycle/index-join.ts +304 -0
  512. package/src/lifecycle/index-store-load-bearing.test.ts +187 -0
  513. package/src/lifecycle/index.ts +4 -0
  514. package/src/lifecycle/member-ledger.test.ts +25 -7
  515. package/src/lifecycle/observation-baseline.test.ts +72 -1
  516. package/src/lifecycle/observation-baseline.ts +190 -27
  517. package/src/lifecycle/observe.ts +6 -1
  518. package/src/lifecycle/query.test.ts +69 -1
  519. package/src/lifecycle/query.ts +103 -10
  520. package/src/lifecycle/replay.test.ts +9 -5
  521. package/src/lifecycle/replay.ts +9 -5
  522. package/src/lifecycle/scenario.ts +4 -3
  523. package/src/lifecycle/snapshot-store-fake.ts +29 -0
  524. package/src/lifecycle/snapshot-store-s3.ts +316 -0
  525. package/src/lifecycle/snapshot-store.test.ts +385 -0
  526. package/src/lifecycle/snapshot-store.ts +981 -0
  527. package/src/lifecycle/snapshot.test.ts +13 -0
  528. package/src/lifecycle/snapshot.ts +23 -6
  529. package/src/lifecycle/type-listing.test.ts +166 -0
  530. package/src/lifecycle/type-listing.ts +309 -0
  531. package/src/lint/component-checks.ts +17 -1
  532. package/src/lint/config.test.ts +3 -0
  533. package/src/lint/presets/relaxed.json +2 -1
  534. package/src/lint/presets/strict.json +2 -1
  535. package/src/lint/rules/__fixtures__/comp/comp008/fail/dns.component.ts +15 -0
  536. package/src/lint/rules/__fixtures__/comp/comp008/pass/dns.component.ts +10 -0
  537. package/src/lint/rules/comp/comp.test.ts +2 -1
  538. package/src/lint/rules/comp/comp008-applies-signal-only-root.ts +121 -0
  539. package/src/lint/rules/comp/comp008.test.ts +77 -0
  540. package/src/lint/rules/comp/index.ts +4 -1
  541. package/src/observation-edges.test.ts +33 -0
  542. package/src/observation.ts +36 -1
  543. package/src/op/activities/activity-contracts.ts +1 -1
  544. package/src/op/activities/change-set.ts +8 -5
  545. package/src/op/activity-failure.ts +36 -0
  546. package/src/op/index.ts +2 -1
  547. package/src/op/local-executor.test.ts +80 -0
  548. package/src/op/local-executor.ts +27 -9
  549. package/src/pr-loop-bundle.test.ts +5 -2
  550. package/src/pr-loop.test.ts +43 -0
  551. package/src/pr-loop.ts +111 -2
  552. package/src/pulumi-urn.ts +151 -0
  553. package/src/release-floors.ts +22 -0
  554. package/src/sensitive-key.ts +34 -0
  555. package/src/workspace/adoption-report.test.ts +61 -0
  556. package/src/workspace/adoption-report.ts +103 -0
  557. package/src/workspace/capabilities-contract.test.ts +4 -0
  558. package/src/workspace/capabilities-contract.ts +9 -1
  559. package/src/workspace/capabilities.schema.json +98 -0
  560. package/src/workspace/change-set.schema.json +42 -3
  561. package/src/workspace/ci-cloud-identity.ts +31 -1
  562. package/src/workspace/compose-graph.test.ts +12 -0
  563. package/src/workspace/compose-graph.ts +12 -1
  564. package/src/workspace/conformance/conformance.e2e.test.ts +2 -1
  565. package/src/workspace/conformance/index.ts +6 -1
  566. package/src/workspace/drift-cli.test.ts +65 -0
  567. package/src/workspace/drift-cli.ts +365 -0
  568. package/src/workspace/drift.schema.json +672 -0
  569. package/src/workspace/graph-cli.ts +5 -0
  570. package/src/workspace/graph.schema.json +72 -0
  571. package/src/workspace/init.test.ts +38 -1
  572. package/src/workspace/init.ts +50 -8
  573. package/src/workspace/intent-gaps.test.ts +18 -2
  574. package/src/workspace/ledger.schema.json +1 -1
  575. package/src/workspace/nested-graph.ts +1 -0
  576. package/src/workspace/pr-report.schema.json +51 -2
  577. package/src/workspace/promote-waves.test.ts +296 -0
  578. package/src/workspace/promote-waves.ts +340 -0
  579. package/src/workspace/promote.test.ts +158 -4
  580. package/src/workspace/promote.ts +398 -57
  581. package/src/workspace/reason-codes.test.ts +4 -1
  582. package/src/workspace/reason-codes.ts +14 -0
  583. package/src/workspace/search-contract.ts +2 -0
  584. package/src/workspace/search.schema.json +103 -5
@@ -67,6 +67,14 @@
67
67
  * says whether the approved change set covers what it planned, by the same
68
68
  * test a resume uses ({@link planCoveredBy}). Covered, the wave applies under
69
69
  * the pull request's approval; not covered, it needs its own.
70
+ *
71
+ * ## Groups
72
+ *
73
+ * A fan-out with `groups` (ws-107, `./groups.ts`) plans each group with one
74
+ * `planGroup` call at its wave and applies it with one `runGroup` call
75
+ * there. A member's read of another member of its group is computed by that
76
+ * apply: it is no `unknownInputs` entry and holds nothing back. Each member's
77
+ * digest binds the group's, so the one approval binds the composition.
70
78
  */
71
79
  import { composeChangeSet, verifyChangeSetDigest } from "../change-set.js";
72
80
  import { evaluateGate } from "../op/gate.js";
@@ -76,6 +84,7 @@ import { deployUnits } from "./deploy-units.js";
76
84
  import { runFanOut } from "./fan-out-run.js";
77
85
  import { remainingFanOut } from "./fan-out.js";
78
86
  import { coveredRound } from "./covered-round.js";
87
+ import { groupsByComponent, narrowGroups, planComponentGroup, regroupRemaining } from "./groups.js";
79
88
  import { capabilitySteps, planWaveComponent, readDeployedOutputs } from "./wave-plan.js";
80
89
  /** The phase a pull request's planning is, in its run's events. */
81
90
  export const PR_PLAN_PHASE = "plan";
@@ -113,13 +122,18 @@ export async function planPrSet(options) {
113
122
  let failed = false;
114
123
  const emit = options.onRunEvent;
115
124
  emit?.({ type: "phase-start", component: null, phase: PR_PLAN_PHASE });
125
+ // ws-107: each group plans once, in its wave, with one call.
126
+ const groupOf = groupsByComponent(options.plan);
127
+ const groups = [];
116
128
  for (const wave of options.plan.waves) {
117
129
  // The dependencies' outputs first, each once. One the change plans is
118
130
  // read from its plan, which an earlier wave made (#3999). Any other is
119
131
  // read from the deployed estate (#4104). A dependency that cannot say
120
132
  // leaves its references unresolved, which its dependent's plan reports
121
- // if it needs them.
122
- const deps = [...new Set(wave.flatMap((name) => byName.get(name)?.dependsOn ?? []))].filter((dep) => !read.has(dep));
133
+ // if it needs them. A member of the dependent's own group plans with it.
134
+ const deps = [
135
+ ...new Set(wave.flatMap((name) => (byName.get(name)?.dependsOn ?? []).filter((dep) => !groupOf.get(name)?.components.includes(dep)))),
136
+ ].filter((dep) => !read.has(dep));
123
137
  const fromEstate = [];
124
138
  for (const dep of deps) {
125
139
  read.add(dep);
@@ -134,26 +148,60 @@ export async function planPrSet(options) {
134
148
  planned[dep] = Object.keys(known).sort();
135
149
  }
136
150
  Object.assign(deployed, await readDeployedOutputs(fromEstate, byName, options.registry, (dep) => deployContext(options, dep), outputs));
137
- const results = await Promise.all(wave.map(async (name) => {
138
- const at = { component: name, phase: PR_PLAN_PHASE, step: "plan" };
139
- emit?.({ type: "step-start", ...at });
140
- const start = Date.now();
141
- const p = await planWaveComponent(byName.get(name), options.registry, deployContext(options, name), outputs);
151
+ const settle = (name, start, p) => {
142
152
  emit?.({
143
153
  type: "step-settle",
144
- ...at,
154
+ component: name,
155
+ phase: PR_PLAN_PHASE,
156
+ step: "plan",
145
157
  status: "error" in p ? "failed" : "ok",
146
158
  durationMs: Date.now() - start,
147
159
  ...("error" in p ? { error: p.error } : {}),
148
160
  });
149
- return p;
150
- }));
161
+ };
162
+ const groupsHere = [...new Set(wave.map((name) => groupOf.get(name)).filter((g) => g !== undefined))];
163
+ const results = (await Promise.all([
164
+ ...wave
165
+ .filter((name) => !groupOf.has(name))
166
+ .map(async (name) => {
167
+ emit?.({ type: "step-start", component: name, phase: PR_PLAN_PHASE, step: "plan" });
168
+ const start = Date.now();
169
+ const p = await planWaveComponent(byName.get(name), options.registry, deployContext(options, name), outputs);
170
+ settle(name, start, p);
171
+ return [p];
172
+ }),
173
+ ...groupsHere.map(async (group) => {
174
+ for (const name of group.components)
175
+ emit?.({ type: "step-start", component: name, phase: PR_PLAN_PHASE, step: "plan" });
176
+ const start = Date.now();
177
+ const g = await planComponentGroup({
178
+ group,
179
+ components: byName,
180
+ registry: options.registry,
181
+ env: options.env,
182
+ ...(options.vars ? { vars: options.vars } : {}),
183
+ ctxOf: (name) => deployContext(options, name),
184
+ outputs,
185
+ });
186
+ for (const p of g.plans)
187
+ settle(p.component, start, p);
188
+ const error = g.plans.find((p) => "error" in p)?.error;
189
+ groups.push({ ...group, digest: g.digest ?? null, ...(error !== undefined ? { error } : {}), ...(g.run ? { run: g.run } : {}) });
190
+ return g.plans;
191
+ }),
192
+ ])).flat();
193
+ /** What each member of a group planned to expose, for its group-mates' reads. */
194
+ const plannedHere = new Map(results.map((p) => [p.component, "error" in p ? undefined : p.outputs?.known]));
151
195
  for (const p of results) {
152
196
  const component = byName.get(p.component);
153
- const unknown = unknownInputsOf(component, outputs, inChange);
197
+ const group = groupOf.get(p.component);
198
+ const mates = group ? new Set(group.components) : undefined;
199
+ const unknown = unknownInputsOf(component, outputs, inChange, mates);
154
200
  if (unknown.unknown.length > 0 || unknown.build.length > 0)
155
201
  unknownOf.set(p.component, unknown);
156
- const reads = readsOf(component, outputs);
202
+ // A read of a group-mate is known when that mate's plan knows it.
203
+ const readsView = group ? { ...outputs, ...Object.fromEntries(group.components.filter((c) => c !== p.component).map((c) => [c, { ...(plannedHere.get(c) ?? {}) }])) } : outputs;
204
+ const reads = readsOf(component, readsView);
157
205
  if (reads.length > 0)
158
206
  readsBy.set(p.component, reads);
159
207
  if ("error" in p) {
@@ -195,12 +243,16 @@ export async function planPrSet(options) {
195
243
  const sorted = (r) => Object.fromEntries(Object.entries(r).sort(([a], [b]) => a.localeCompare(b)));
196
244
  const deployedOutputs = sorted(deployed);
197
245
  const plannedOutputs = sorted(planned);
246
+ const at = new Map(options.plan.order.map((name, i) => [name, i]));
247
+ groups.sort((a, b) => (at.get(a.components[0]) ?? 0) - (at.get(b.components[0]) ?? 0));
198
248
  return {
199
249
  doc,
200
250
  members,
201
251
  plans,
202
252
  outputs,
203
253
  failed,
254
+ ...(groups.length > 0 ? { groups } : {}),
255
+ ...(options.plan.fallbacks?.length ? { fallbacks: options.plan.fallbacks } : {}),
204
256
  ...(Object.keys(shapes).length > 0 ? { shapes } : {}),
205
257
  ...(Object.keys(deployedOutputs).length > 0 ? { deployedOutputs } : {}),
206
258
  ...(Object.keys(plannedOutputs).length > 0 ? { plannedOutputs } : {}),
@@ -212,14 +264,17 @@ export async function planPrSet(options) {
212
264
  * that upstream applies, each sorted. `build` are the published artifact
213
265
  * identities a build in the change produces (`WiringReference.publish`):
214
266
  * the build's provenance binds those, so they are never approved again.
215
- * `unknown` are the rest.
267
+ * `unknown` are the rest. A reference to a member of `group`, the
268
+ * component's own group (ws-107), is neither: the group's apply computes it.
216
269
  */
217
- function unknownInputsOf(component, outputs, inChange) {
270
+ function unknownInputsOf(component, outputs, inChange, group) {
218
271
  const unknown = new Set();
219
272
  const build = new Set();
220
273
  for (const step of capabilitySteps(component.deploy)) {
221
274
  const { kind: _kind, ...rest } = step;
222
275
  for (const r of unresolvedWiringReferences(rest, outputs)) {
276
+ if (group?.has(r.source))
277
+ continue;
223
278
  if (inChange.has(r.source))
224
279
  (r.publish ? build : unknown).add(r.ref);
225
280
  }
@@ -257,14 +312,16 @@ function readsOf(component, outputs) {
257
312
  * stands (#3999): each reference its steps make that resolves to another
258
313
  * value, said once. `undefined` when every one resolves as it did. A
259
314
  * published artifact's identity from a build in `inChange` never holds a
260
- * member back: the build's provenance binds it, not this approval.
315
+ * member back: the build's provenance binds it, not this approval. Nor
316
+ * does a reference to a member of `group`, the component's own group
317
+ * (ws-107), whose apply computes it.
261
318
  */
262
- export function heldReason(component, read, now, inChange = new Set()) {
319
+ export function heldReason(component, read, now, inChange = new Set(), group = new Set()) {
263
320
  const refs = new Set();
264
321
  for (const step of capabilitySteps(component.deploy)) {
265
322
  const { kind: _kind, ...rest } = step;
266
323
  for (const r of movedWiringReferences(rest, read, now))
267
- if (!(r.publish && inChange.has(r.source)))
324
+ if (!(r.publish && inChange.has(r.source)) && !group.has(r.source))
268
325
  refs.add(r.ref);
269
326
  }
270
327
  if (refs.size === 0)
@@ -335,6 +392,10 @@ export function approversWhoAuthored(approvedBy, authors) {
335
392
  function roundCover(options, fresh, plan, now, inChange, byName) {
336
393
  if (options.approval?.status !== "approved")
337
394
  return { covered: false, reason: "no approval of the first plan stands" };
395
+ // ws-107: a round's group is covered only when it has the approved group's members.
396
+ const moved = groupsMoved(options.set.groups ?? [], fresh.groups ?? [], plan.order);
397
+ if (moved)
398
+ return { covered: false, reason: moved };
338
399
  // The values the round reads of a component it plans again are the ones
339
400
  // that plan says it will expose: it has not applied yet, so the outputs
340
401
  // standing say nothing of it. An output the first plan knew and the round's
@@ -358,15 +419,45 @@ function roundCover(options, fresh, plan, now, inChange, byName) {
358
419
  }
359
420
  changedKnown[name] = [...refs].sort();
360
421
  }
422
+ // A member whose round plan still reads only outputs of components this
423
+ // round plans and has not applied (a chain of imports, #4466d) cannot apply
424
+ // in this round: it is held again once those apply, and its own round
425
+ // checks its coverage. Only the members this round can apply are checked.
426
+ const inRound = plan.order;
427
+ const fromRound = (ref) => inRound.some((c) => ref === c || ref.startsWith(`${c}.`));
428
+ const waits = (m) => (m.unknownInputs?.length ?? 0) > 0 && m.unknownInputs.every(fromRound);
361
429
  const approved = { doc: options.set.doc, members: options.set.members, ...(options.set.shapes ? { shapes: options.set.shapes } : {}) };
362
430
  return coveredRound({
363
431
  approved,
364
432
  approvedDigest: options.set.doc.digest,
365
- fresh: { doc: fresh.doc, members: fresh.members, ...(fresh.shapes ? { shapes: fresh.shapes } : {}) },
433
+ fresh: { doc: fresh.doc, members: fresh.members.filter((m) => !waits(m)), ...(fresh.shapes ? { shapes: fresh.shapes } : {}) },
366
434
  changedKnown,
367
435
  attributes: (member) => memberAttributes(options.set.doc, fresh.doc, member, fresh.shapes?.[member] !== undefined),
368
436
  });
369
437
  }
438
+ /**
439
+ * Why the groups `fresh` planned are not the `approved` ones over the
440
+ * components in `order` (ws-107), or `undefined` when each group the round
441
+ * plans has the members the approved group had.
442
+ */
443
+ function groupsMoved(approved, fresh, order) {
444
+ const same = (a, b) => a.length === b.length && a.every((c) => b.includes(c));
445
+ const inRound = new Set(order);
446
+ for (const was of approved) {
447
+ const here = was.components.filter((c) => inRound.has(c));
448
+ if (here.length === 0)
449
+ continue;
450
+ const now = fresh.find((g) => g.components.includes(here[0]));
451
+ if (!now || !same(now.components, was.components)) {
452
+ return `the approved plan grouped ${was.components.join(", ")}, and the round ${now ? `groups ${now.components.join(", ")}` : `plans ${here.join(", ")} without that group`}`;
453
+ }
454
+ }
455
+ for (const now of fresh) {
456
+ if (!approved.some((was) => same(was.components, now.components)))
457
+ return `the round groups ${now.components.join(", ")}, which the approved plan did not`;
458
+ }
459
+ return undefined;
460
+ }
370
461
  /**
371
462
  * The part of coverage that reads the change set's own attributes, shared by
372
463
  * a round, a resume and a wave: a member whose planner describes no changes
@@ -397,6 +488,8 @@ function joinRuns(a, b) {
397
488
  componentOutputs: b.componentOutputs,
398
489
  ...(gate ? { gate } : {}),
399
490
  ...(b.held ? { held: b.held } : {}),
491
+ ...(a.notStarted || b.notStarted ? { notStarted: [...new Set([...(a.notStarted ?? []), ...(b.notStarted ?? [])])].sort() } : {}),
492
+ ...(a.groupOutcomes || b.groupOutcomes ? { groupOutcomes: { ...(a.groupOutcomes ?? {}), ...(b.groupOutcomes ?? {}) } } : {}),
400
493
  };
401
494
  }
402
495
  /**
@@ -419,18 +512,24 @@ export async function applyPrSet(options) {
419
512
  ...Object.fromEntries(Object.entries(options.set.outputs).filter(([name]) => !toApply.has(name))),
420
513
  ...(options.resumed?.outputs ?? {}),
421
514
  };
422
- const runRound = (plan, plans, read, outputs) => runFanOut(plan, options.components, options.registry, {
423
- env: options.env,
424
- ...(options.vars ? { vars: options.vars } : {}),
425
- plans,
426
- ...(options.targets ? { targets: options.targets } : {}),
427
- componentOutputs: outputs,
428
- hold: (name, now) => heldReason(byName.get(name), read, now, inChange),
429
- ...(options.onProgress ? { onProgress: options.onProgress } : {}),
430
- ...(options.onRunEvent ? { onRunEvent: options.onRunEvent } : {}),
431
- ...(options.onComponentSettled ? { onComponentSettled: options.onComponentSettled } : {}),
432
- });
433
- let run = await runRound(options.plan, options.set.plans, options.set.outputs, { ...standing });
515
+ const runRound = (plan, set, read, outputs) => {
516
+ // ws-107: each group runs the plan its group planned, and a read of a group-mate holds nothing back.
517
+ const groupOf = groupsByComponent(plan);
518
+ const groupRuns = Object.fromEntries((set.groups ?? []).filter((g) => g.run).map((g) => [g.components[0], g.run]));
519
+ return runFanOut(plan, options.components, options.registry, {
520
+ env: options.env,
521
+ ...(options.vars ? { vars: options.vars } : {}),
522
+ plans: set.plans,
523
+ ...(Object.keys(groupRuns).length > 0 ? { groupRuns } : {}),
524
+ ...(options.targets ? { targets: options.targets } : {}),
525
+ componentOutputs: outputs,
526
+ hold: (name, now) => heldReason(byName.get(name), read, now, inChange, new Set(groupOf.get(name)?.components ?? [])),
527
+ ...(options.onProgress ? { onProgress: options.onProgress } : {}),
528
+ ...(options.onRunEvent ? { onRunEvent: options.onRunEvent } : {}),
529
+ ...(options.onComponentSettled ? { onComponentSettled: options.onComponentSettled } : {}),
530
+ });
531
+ };
532
+ let run = await runRound(options.plan, options.set, options.set.outputs, { ...standing });
434
533
  const rounds = [];
435
534
  /** Per component, the round that applied it or holds it, and that round's set, after the first. */
436
535
  const roundOf = new Map();
@@ -439,7 +538,8 @@ export async function applyPrSet(options) {
439
538
  const round = rounds.length + 2;
440
539
  const gate = prRoundGate(options.gate ?? PR_APPLY_GATE, round);
441
540
  const heldNames = new Set(run.held.map((h) => h.component));
442
- const plan = remainingFanOut(options.plan, options.components, { completed: options.plan.order.filter((name) => !heldNames.has(name)) });
541
+ // A held group is planned again as the same group (ws-107).
542
+ const plan = narrowGroups(remainingFanOut(options.plan, options.components, { completed: options.plan.order.filter((name) => !heldNames.has(name)) }), options.components, options.plan.groups);
443
543
  const set = await planPrSet({
444
544
  components: options.components,
445
545
  plan,
@@ -479,27 +579,35 @@ export async function applyPrSet(options) {
479
579
  stopped = "waiting";
480
580
  break;
481
581
  }
482
- const next = await runRound(plan, set.plans, set.outputs, run.componentOutputs);
582
+ const next = await runRound(plan, set, set.outputs, run.componentOutputs);
483
583
  record(next.status === "fail" ? "failed" : "applied", decision.approval, undefined, decision.covered);
484
584
  run = joinRuns(run, next);
485
585
  }
486
586
  const completed = new Set(run.completed);
587
+ const notStarted = new Set(run.notStarted ?? []);
487
588
  const held = new Map((run.held ?? []).map((h) => [h.component, h]));
488
589
  const blocked = new Map(run.blocked.map((b) => [b.component, b.blockedBy]));
489
590
  const errorOf = (component) => {
490
591
  const result = [...run.results].reverse().find((r) => r.component === component);
491
592
  if (result?.status === "gated")
492
593
  return `stopped at its own gate ${result.gate?.gate ?? ""}`.trim();
493
- return result?.records.find((r) => r.status === "fail")?.error;
594
+ return result?.records.find((r) => r.status === "fail" || (notStarted.has(component) && r.status === "skipped"))?.error;
494
595
  };
495
596
  const members = options.set.members.map((m) => {
496
597
  if (priorCompleted.has(m.component))
497
598
  return { ...m, status: "applied" };
498
599
  const later = roundOf.get(m.component);
499
600
  const fresh = later?.set.members.find((x) => x.member === m.member);
500
- const asPlanned = later && fresh ? { ...m, planDigest: fresh.planDigest, counts: fresh.counts, round: later.round } : m;
601
+ const planned = later && fresh ? { ...m, planDigest: fresh.planDigest, counts: fresh.counts, round: later.round } : m;
602
+ // #4446: how its part of a group's apply ended, as the capability said.
603
+ const groupOutcome = run.groupOutcomes?.[m.component];
604
+ const asPlanned = groupOutcome ? { ...planned, groupOutcome } : planned;
501
605
  if (completed.has(m.component))
502
606
  return { ...asPlanned, status: "applied" };
607
+ if (notStarted.has(m.component)) {
608
+ const error = errorOf(m.component);
609
+ return { ...asPlanned, status: "not-started", ...(error ? { error } : {}) };
610
+ }
503
611
  const h = held.get(m.component);
504
612
  if (h)
505
613
  return { ...asPlanned, status: "waiting", held: h.heldBy ? `${h.heldBy} is held: ${h.reason}` : h.reason };
@@ -614,20 +722,42 @@ export function planCoveredBy(approved, fresh, member) {
614
722
  * is `record.digest`, and the document gives that digest. The digest binds
615
723
  * the entries, holes and side effects {@link planCoveredBy} reads (#3555),
616
724
  * so a record cannot widen what a re-planned member may do.
725
+ *
726
+ * A group that failed part way (ws-107, "Resume"; #4446) leaves its
727
+ * `partial`, `failed` and `not-started` members; `applied` and `no-changes`
728
+ * ones are in `completed`. What is left of each approved group is grouped
729
+ * again ({@link regroupRemaining}), so it plans as a smaller group, or one
730
+ * by one when the rule or the capability says so. The smaller group's
731
+ * digest differs from the approved one, so coverage rests on entries and
732
+ * shapes, as for any resumed member.
617
733
  */
618
734
  export async function resumePrSet(options) {
619
735
  const { record } = options;
620
736
  if (record.changeSet.digest !== record.digest || !verifyChangeSetDigest(record.changeSet)) {
621
737
  return { ok: false, reasons: [`the record's change set is not the one its digest ${record.digest} names`] };
622
738
  }
623
- const plan = remainingFanOut(options.plan, options.components, { completed: options.completed });
739
+ const plan = await regroupRemaining({
740
+ components: options.components,
741
+ plan: remainingFanOut(options.plan, options.components, { completed: options.completed }),
742
+ registry: options.registry,
743
+ env: options.env,
744
+ ...(options.vars ? { vars: options.vars } : {}),
745
+ groups: options.plan.groups,
746
+ ...(options.plan.fallbacks ? { fallbacks: options.plan.fallbacks } : {}),
747
+ });
748
+ // The outputs of the applied members of a group with members left: the values the group's apply computed.
749
+ const left = new Set(plan.order);
750
+ const fromGroup = Object.fromEntries((options.plan.groups ?? [])
751
+ .filter((g) => g.components.some((c) => left.has(c)))
752
+ .flatMap((g) => g.components.filter((c) => !left.has(c) && options.applied?.[c] !== undefined))
753
+ .map((c) => [c, options.applied[c]]));
624
754
  const fresh = await planPrSet({
625
755
  components: options.components,
626
756
  plan,
627
757
  registry: options.registry,
628
758
  env: options.env,
629
759
  ...(options.vars ? { vars: options.vars } : {}),
630
- seededOutputs: { ...(options.seededOutputs ?? {}), ...options.record.planOutputs },
760
+ seededOutputs: { ...(options.seededOutputs ?? {}), ...options.record.planOutputs, ...fromGroup },
631
761
  ...(options.targets ? { targets: options.targets } : {}),
632
762
  });
633
763
  // #4422: decided as a round decides (`coveredRound`), by the same function a wave uses.
@@ -642,7 +772,9 @@ export async function resumePrSet(options) {
642
772
  doc: options.record.changeSet,
643
773
  members: options.record.members.map((m) => ({ ...m, status: "planned" })),
644
774
  plans: fresh.plans,
645
- outputs: options.record.planOutputs,
775
+ outputs: { ...options.record.planOutputs, ...fromGroup },
776
+ ...(fresh.groups ? { groups: fresh.groups } : {}),
777
+ ...(fresh.fallbacks ? { fallbacks: fresh.fallbacks } : {}),
646
778
  failed: false,
647
779
  },
648
780
  };
@@ -661,7 +793,17 @@ export function prWavePlan(plan, components, wave, completed = []) {
661
793
  const seeds = [
662
794
  ...new Set([...plan.seeds, ...order.flatMap((name) => (byName.get(name)?.dependsOn ?? []).filter((dep) => !inWave.has(dep)))]),
663
795
  ].sort();
664
- return { order, waves: order.length > 0 ? [order] : [], skipped: [], seeds, indeterminate: plan.indeterminate, digest: plan.digest };
796
+ // ws-107: a group sits in one wave, so what is left of it plans and applies as one there.
797
+ const groups = (plan.groups ?? []).map((g) => ({ ...g, components: g.components.filter((c) => inWave.has(c)) })).filter((g) => g.components.length > 1);
798
+ return {
799
+ order,
800
+ waves: order.length > 0 ? [order] : [],
801
+ skipped: [],
802
+ seeds,
803
+ indeterminate: plan.indeterminate,
804
+ digest: plan.digest,
805
+ ...(groups.length > 0 ? { groups } : {}),
806
+ };
665
807
  }
666
808
  /**
667
809
  * Why the approved change set does not cover a wave's new plan, one line per
@@ -713,9 +855,35 @@ export function waveNotCovered(approved, fresh, approvedMembers = [], shapes = {
713
855
  })
714
856
  .filter((r) => r !== undefined);
715
857
  }
858
+ /**
859
+ * The report's `groups` (#4446): each group the set planned, with the wave
860
+ * of `waves` its members sit in and the reads of group-mates its members'
861
+ * change-set parts name, which the group's apply computes.
862
+ */
863
+ function reportGroups(set, waves) {
864
+ const componentOf = new Map(set.members.map((m) => [m.member, m.component]));
865
+ return (set.groups ?? []).map((g) => {
866
+ const wave = waves.findIndex((w) => g.components.some((c) => w.includes(c))) + 1;
867
+ const reads = set.doc.members
868
+ .filter((m) => g.components.includes(componentOf.get(m.member) ?? m.member))
869
+ .flatMap((m) => (m.group?.reads ?? []).map((ref) => ({ component: componentOf.get(m.member) ?? m.member, ref })))
870
+ .sort((a, b) => a.component.localeCompare(b.component) || a.ref.localeCompare(b.ref));
871
+ return {
872
+ capability: g.capability,
873
+ components: [...g.components],
874
+ wave: wave > 0 ? wave : 1,
875
+ digest: g.digest,
876
+ ...(g.error !== undefined ? { error: g.error } : {}),
877
+ ...(reads.length > 0 ? { reads } : {}),
878
+ };
879
+ });
880
+ }
716
881
  /** The report a stage writes. */
717
882
  export function prReport(input) {
718
883
  const changed = new Set(input.signal.changed);
884
+ const groups = reportGroups(input.set, input.plan.waves);
885
+ const groupOf = new Map(groups.flatMap((g, i) => g.components.map((c) => [c, i])));
886
+ const members = (input.members ?? input.set.members).map((m) => (groupOf.has(m.component) ? { ...m, group: groupOf.get(m.component) } : m));
719
887
  return {
720
888
  $schema: PR_REPORT_SCHEMA_ID,
721
889
  contract: PR_REPORT_CONTRACT,
@@ -746,7 +914,9 @@ export function prReport(input) {
746
914
  indeterminate: input.plan.indeterminate,
747
915
  waves: input.plan.waves,
748
916
  },
749
- members: input.members ?? input.set.members,
917
+ ...(groups.length > 0 ? { groups } : {}),
918
+ ...(input.set.fallbacks?.length ? { fallbacks: input.set.fallbacks.map((f) => ({ ...f })) } : {}),
919
+ members,
750
920
  changeSet: input.set.doc,
751
921
  };
752
922
  }
@@ -22,6 +22,12 @@
22
22
  * A stage whose components declare no gate has nowhere to wait, so the
23
23
  * promote stops there with nothing more deployed.
24
24
  *
25
+ * - **Groups** (ws-107, #4465). With `grouped`, the waves are the grouped
26
+ * fan-out's, so each group sits in one wave and is checked, planned again
27
+ * and run as one: when any member's input moved, every member left of the
28
+ * group is planned again with it. Under `--wave-gate` no group forms
29
+ * (`formRunGroups`), so there is none here.
30
+ *
25
31
  * A promote that stops at a round's or a wave's gate writes a resume record
26
32
  * ({@link PromoteResume}): the components that applied and the outputs they
27
33
  * left. The same promote run again with it skips what applied and carries on
@@ -31,6 +37,7 @@
31
37
  import { type DriverComponent, type DriverRunResult, type ReleaseGateBinding } from "./driver.js";
32
38
  import type { ChangeSetDocument } from "../change-set.js";
33
39
  import type { ReleasePlan } from "./release-gate.js";
40
+ import type { FanOutPlan } from "./fan-out.js";
34
41
  export declare const PROMOTE_RESUME_SCHEMA = "chant-promote-resume/v1";
35
42
  /** What a promote that stopped at a round's or a wave's gate leaves for the next attempt. */
36
43
  export interface PromoteResume {
@@ -80,6 +87,8 @@ export interface PromoteRoundsOptions {
80
87
  replan: (only: ReadonlySet<string>, outputs: Record<string, Record<string, unknown>>) => Promise<ChangeSetDocument>;
81
88
  /** Store a stage's plan and bind its gates (empty resolutions included). */
82
89
  bind: (doc: ChangeSetDocument, gates: string[]) => Promise<ReleaseGateBinding>;
90
+ /** The grouped fan-out (#4465): its waves replace the ones `dependsOn` gives, and each group is checked as one. */
91
+ grouped?: FanOutPlan;
83
92
  }
84
93
  export interface PromoteRoundsResult {
85
94
  run: DriverRunResult;
@@ -1 +1 @@
1
- {"version":3,"file":"promote-rounds.d.ts","sourceRoot":"","sources":["../../src/components/promote-rounds.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"promote-rounds.d.ts","sourceRoot":"","sources":["../../src/components/promote-rounds.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,12 @@
22
22
  * A stage whose components declare no gate has nowhere to wait, so the
23
23
  * promote stops there with nothing more deployed.
24
24
  *
25
+ * - **Groups** (ws-107, #4465). With `grouped`, the waves are the grouped
26
+ * fan-out's, so each group sits in one wave and is checked, planned again
27
+ * and run as one: when any member's input moved, every member left of the
28
+ * group is planned again with it. Under `--wave-gate` no group forms
29
+ * (`formRunGroups`), so there is none here.
30
+ *
25
31
  * A promote that stops at a round's or a wave's gate writes a resume record
26
32
  * ({@link PromoteResume}): the components that applied and the outputs they
27
33
  * left. The same promote run again with it skips what applied and carries on
@@ -34,6 +40,7 @@ import { waveNotCovered } from "./pr-run.js";
34
40
  import { prRoundGate } from "../pr-loop.js";
35
41
  import { waveGateName } from "../gated-waves.js";
36
42
  import { capabilitySteps } from "./wave-plan.js";
43
+ import { groupsByComponent } from "./groups.js";
37
44
  export const PROMOTE_RESUME_SCHEMA = "chant-promote-resume/v1";
38
45
  function isGate(step) {
39
46
  return step.kind === "gate";
@@ -107,7 +114,18 @@ function joinRuns(runs, outputs) {
107
114
  */
108
115
  export async function runPromotionInRounds(options) {
109
116
  const byName = new Map(options.components.map((c) => [c.name, c]));
110
- const { waves } = resolveComponentGraph(options.components.map((c) => ({ ...c, dependsOn: (c.dependsOn ?? []).filter((d) => byName.has(d)) })));
117
+ const grouped = options.grouped?.groups?.length ? options.grouped : undefined;
118
+ const placed = new Set(grouped?.order ?? []);
119
+ // A grouped fan-out over what a resume left holds no wave for what applied earlier; that is skipped anyway.
120
+ const waves = grouped
121
+ ? grouped.waves.map((w) => w.filter((name) => byName.has(name)))
122
+ : resolveComponentGraph(options.components.map((c) => ({ ...c, dependsOn: (c.dependsOn ?? []).filter((d) => byName.has(d)) }))).waves;
123
+ if (grouped) {
124
+ const missing = options.components.filter((c) => !placed.has(c.name) && !(options.completed ?? []).includes(c.name)).map((c) => c.name);
125
+ if (missing.length > 0)
126
+ throw new Error(`the grouped waves leave out ${missing.join(", ")}, which this promote runs`);
127
+ }
128
+ const groupOf = grouped ? groupsByComponent(grouped) : new Map();
111
129
  const completed = [...(options.completed ?? [])];
112
130
  const done = new Set(completed);
113
131
  let outputs = { ...options.outputs };
@@ -119,9 +137,12 @@ export async function runPromotionInRounds(options) {
119
137
  const pending = wave.filter((name) => !done.has(name));
120
138
  if (pending.length === 0)
121
139
  continue;
122
- const check = options.waveGate !== undefined && waveNumber > 1
140
+ const moved = options.waveGate !== undefined && waveNumber > 1
123
141
  ? pending
124
142
  : pending.filter((name) => movedInputs(byName.get(name), options.reads[name], outputs).length > 0);
143
+ // A group is planned again as one: a member whose input moved takes the rest of its group with it.
144
+ const withMates = new Set(moved.flatMap((name) => [name, ...(groupOf.get(name)?.components ?? [])]));
145
+ const check = pending.filter((name) => withMates.has(name));
125
146
  const batches = [];
126
147
  const rest = pending.filter((name) => !check.includes(name));
127
148
  if (check.length > 0) {
@@ -41,6 +41,8 @@ import { type ReleaseRecord, type ReleaseRecordInput, type ReleaseAdmission, typ
41
41
  import { CapabilityRegistry, type Capability } from "./capability.js";
42
42
  import { type DriverComponent, type DriverComponentResult, type ReleaseGateBinding, type DriverRunResult } from "./driver.js";
43
43
  import type { GateLedgerPort } from "../op/gate.js";
44
+ import type { GroupRun } from "./capability.js";
45
+ import type { FanOutPlan } from "./fan-out.js";
44
46
  import type { Release } from "../lifecycle/release-store.js";
45
47
  import type { RunProgressEvent } from "./run-progress.js";
46
48
  import type { RunEventSink } from "../run-event-stream.js";
@@ -253,6 +255,21 @@ export interface RunPromotionOptions {
253
255
  onProgress?: (event: RunProgressEvent) => void;
254
256
  /** Where the run's events go (#4041, `--events-json`). */
255
257
  onRunEvent?: RunEventSink;
258
+ /**
259
+ * The grouped fan-out (ws-107, #4465, `formRunGroups`): each of its groups
260
+ * applies as one, in the wave it places it in. Absent, or without
261
+ * `groups`: every component runs its own deploy, as before.
262
+ */
263
+ grouped?: FanOutPlan;
264
+ /**
265
+ * The approved plan of each group, as the release gate's plan made it
266
+ * (`ReleasePlan.groups`). A group runs the one whose members are its own;
267
+ * the newest first. A group with none plans in its wave and applies only
268
+ * under `planGroupsAtWave`, and fails otherwise.
269
+ */
270
+ groupRuns?: readonly GroupRun[];
271
+ /** A promote with no release gate to bind plans each group in its wave (#4465). */
272
+ planGroupsAtWave?: boolean;
256
273
  }
257
274
  /**
258
275
  * Deploy the plan's components to `plan.to`, in dependency order. A
@@ -1 +1 @@
1
- {"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../src/components/promote.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAGH,OAAO,EAAqC,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACpK,OAAO,EAAE,kBAAkB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAE1B,KAAK,kBAAkB,EAEvB,KAAK,eAAe,EAErB,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAM7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAK/C,CAAC;AAEF,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,gEAAgE;IAChE,WAAW,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,aAAa,EAAE,EACxB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAY/C;AAkBD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAiBtG;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,aAAa,EAAE,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B,GAAG,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA6CpC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA0BpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAAC,CAAC;IACxE,sDAAsD;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0FAA0F;IAC1F,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC,GAAG,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAuCpC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAepC;AAUD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAAiD,CAAC;AAElG;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,EAAE,CAqBxE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG,OAAO,CAIlE;AAED,qEAAqE;AACrE,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,eAAe,CAAC;IAC3B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,gIAAgI;IAChI,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD,0DAA0D;AAC1D,eAAO,MAAM,wBAAwB,EAAE,UAAU,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAMvF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,eAAe,EAC1B,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1E,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAyFzC;AAmBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,kBAAkB,EAC5B,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,kBAAkB,CAuCpB;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,CAAC;IACpB,sFAAsF;IACtF,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3D,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC/C,0DAA0D;IAC1D,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC,CA6BzF;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAM1F;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAOrG;AAED,+FAA+F;AAC/F,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAiCD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAEvG;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAEvG;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAEvG"}
1
+ {"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../src/components/promote.ts"],"names":[],"mappings":"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"}