@mysten-incubation/devstack 0.1.0 → 0.2.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 (858) hide show
  1. package/README.md +7 -4
  2. package/dashboard-ui/assets/grpc-a4usE3Nk.js +3 -0
  3. package/dashboard-ui/assets/index-B82Bh84P.css +1 -0
  4. package/dashboard-ui/assets/index-CRYJ4pru.js +1277 -0
  5. package/dashboard-ui/index.html +2 -2
  6. package/dist/api/define-capabilities.d.mts +1 -20
  7. package/dist/api/define-capabilities.mjs +15 -22
  8. package/dist/api/define-capabilities.mjs.map +1 -1
  9. package/dist/api/define-devstack-with.d.mts +7 -1
  10. package/dist/api/define-devstack-with.mjs.map +1 -1
  11. package/dist/api/define-devstack.mjs.map +1 -1
  12. package/dist/api/define-plugin.d.mts +2 -1
  13. package/dist/api/inference-network.d.mts +31 -17
  14. package/dist/api/inference-network.mjs +40 -43
  15. package/dist/api/inference-network.mjs.map +1 -1
  16. package/dist/api/load-config.mjs +88 -0
  17. package/dist/api/load-config.mjs.map +1 -0
  18. package/dist/api/mode-narrowed-factory.d.mts +1 -1
  19. package/dist/api/mode-narrowed-factory.mjs.map +1 -1
  20. package/dist/api/run-stack-internal.mjs +202 -0
  21. package/dist/api/run-stack-internal.mjs.map +1 -0
  22. package/dist/api/run-stack.d.mts +82 -31
  23. package/dist/api/run-stack.mjs +22 -141
  24. package/dist/api/run-stack.mjs.map +1 -1
  25. package/dist/build-integrations/dapp-kit/index.d.mts +61 -0
  26. package/dist/build-integrations/dapp-kit/index.mjs +58 -0
  27. package/dist/build-integrations/dapp-kit/index.mjs.map +1 -0
  28. package/dist/build-integrations/playwright/config.d.mts +1 -30
  29. package/dist/build-integrations/playwright/config.mjs +1 -27
  30. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  31. package/dist/build-integrations/playwright/errors.d.mts +4 -7
  32. package/dist/build-integrations/playwright/errors.mjs.map +1 -1
  33. package/dist/build-integrations/playwright/global-setup.d.mts +42 -71
  34. package/dist/build-integrations/playwright/global-setup.mjs +142 -218
  35. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  36. package/dist/build-integrations/playwright/index.d.mts +2 -2
  37. package/dist/build-integrations/playwright/index.mjs +2 -2
  38. package/dist/build-integrations/playwright/stack-context.d.mts +3 -1
  39. package/dist/build-integrations/playwright/stack-context.mjs +4 -2
  40. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  41. package/dist/build-integrations/playwright/wallet-context.mjs +44 -19
  42. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  43. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  44. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -1
  45. package/dist/build-integrations/runtime/dapp-kit-slot.mjs.map +1 -1
  46. package/dist/build-integrations/runtime/discover.d.mts +6 -4
  47. package/dist/build-integrations/runtime/discover.mjs +15 -4
  48. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  49. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/errors.mjs.map +1 -1
  51. package/dist/build-integrations/runtime/read-stack-context.mjs +3 -3
  52. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  53. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +23 -7
  54. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +25 -12
  55. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/stack-context.d.mts +2 -2
  57. package/dist/build-integrations/vite/index.d.mts +84 -19
  58. package/dist/build-integrations/vite/index.mjs +203 -28
  59. package/dist/build-integrations/vite/index.mjs.map +1 -1
  60. package/dist/build-integrations/vitest/config.d.mts +20 -2
  61. package/dist/build-integrations/vitest/config.mjs +16 -4
  62. package/dist/build-integrations/vitest/config.mjs.map +1 -1
  63. package/dist/build-integrations/vitest/env.d.mts +18 -10
  64. package/dist/build-integrations/vitest/env.mjs +11 -10
  65. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  66. package/dist/build-integrations/vitest/errors.d.mts +7 -11
  67. package/dist/build-integrations/vitest/errors.mjs +3 -4
  68. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  69. package/dist/build-integrations/vitest/global-setup.d.mts +35 -0
  70. package/dist/build-integrations/vitest/global-setup.mjs +156 -0
  71. package/dist/build-integrations/vitest/global-setup.mjs.map +1 -0
  72. package/dist/build-integrations/vitest/index.d.mts +3 -2
  73. package/dist/build-integrations/vitest/index.mjs +3 -2
  74. package/dist/build-integrations/vitest/setup.mjs +2 -2
  75. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  76. package/dist/build-integrations/vitest/stack-context.d.mts +5 -3
  77. package/dist/build-integrations/vitest/stack-context.mjs +3 -2
  78. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  79. package/dist/cli/bail.mjs.map +1 -1
  80. package/dist/cli/doctor-probes.mjs +1 -3
  81. package/dist/cli/doctor-probes.mjs.map +1 -1
  82. package/dist/cli/main.d.mts +23 -1
  83. package/dist/cli/main.mjs +63 -8
  84. package/dist/cli/main.mjs.map +1 -1
  85. package/dist/cli/prune-direct.mjs.map +1 -1
  86. package/dist/cli/snapshot-reader.mjs.map +1 -1
  87. package/dist/cli/up-lifecycle.mjs.map +1 -1
  88. package/dist/cli/wirings/apply.mjs +28 -21
  89. package/dist/cli/wirings/apply.mjs.map +1 -1
  90. package/dist/cli/wirings/codegen.mjs +108 -0
  91. package/dist/cli/wirings/codegen.mjs.map +1 -0
  92. package/dist/cli/wirings/config-loader.mjs +12 -62
  93. package/dist/cli/wirings/config-loader.mjs.map +1 -1
  94. package/dist/cli/wirings/dump-ids.mjs +86 -0
  95. package/dist/cli/wirings/dump-ids.mjs.map +1 -0
  96. package/dist/cli/wirings/engine-command.mjs +1 -1
  97. package/dist/cli/wirings/engine-command.mjs.map +1 -1
  98. package/dist/cli/wirings/identity.mjs +2 -2
  99. package/dist/cli/wirings/identity.mjs.map +1 -1
  100. package/dist/cli/wirings/provide-file-system.mjs.map +1 -1
  101. package/dist/cli/wirings/read-devstack-version.mjs +17 -0
  102. package/dist/cli/wirings/read-devstack-version.mjs.map +1 -0
  103. package/dist/cli/wirings/snapshot.mjs +27 -34
  104. package/dist/cli/wirings/snapshot.mjs.map +1 -1
  105. package/dist/cli/wirings/up-ipc.mjs +147 -0
  106. package/dist/cli/wirings/up-ipc.mjs.map +1 -0
  107. package/dist/cli/wirings/up.mjs +218 -198
  108. package/dist/cli/wirings/up.mjs.map +1 -1
  109. package/dist/cli/wirings/wipe.mjs +1 -1
  110. package/dist/cli/wirings/wipe.mjs.map +1 -1
  111. package/dist/contracts/chain-probe.d.mts +1 -1
  112. package/dist/contracts/chain-probe.mjs +1 -1
  113. package/dist/contracts/chain-probe.mjs.map +1 -1
  114. package/dist/contracts/codegenable.d.mts +60 -6
  115. package/dist/contracts/codegenable.mjs +28 -0
  116. package/dist/contracts/codegenable.mjs.map +1 -0
  117. package/dist/contracts/config-bindings.mjs +162 -0
  118. package/dist/contracts/config-bindings.mjs.map +1 -0
  119. package/dist/contracts/container-runtime.d.mts +23 -17
  120. package/dist/contracts/plugin-expander.mjs.map +1 -1
  121. package/dist/contracts/snapshotable.d.mts +5 -7
  122. package/dist/contracts/wallet-protocol.d.mts +2 -5
  123. package/dist/contracts/wallet-protocol.mjs +2 -5
  124. package/dist/contracts/wallet-protocol.mjs.map +1 -1
  125. package/dist/index.d.mts +21 -26
  126. package/dist/index.mjs +8 -9
  127. package/dist/orchestrators/boot.d.mts +28 -0
  128. package/dist/orchestrators/boot.mjs +440 -0
  129. package/dist/orchestrators/boot.mjs.map +1 -0
  130. package/dist/orchestrators/codegen/bindings.d.mts +13 -1
  131. package/dist/orchestrators/codegen/bindings.mjs +23 -9
  132. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  133. package/dist/orchestrators/codegen/config-runtime.mjs +208 -0
  134. package/dist/orchestrators/codegen/config-runtime.mjs.map +1 -0
  135. package/dist/orchestrators/codegen/emit.mjs +1 -1
  136. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  137. package/dist/orchestrators/codegen/errors.mjs +21 -1
  138. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  139. package/dist/orchestrators/codegen/format.mjs +2 -0
  140. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  141. package/dist/orchestrators/codegen/gitignore.mjs +30 -11
  142. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/id-config.mjs +107 -0
  144. package/dist/orchestrators/codegen/id-config.mjs.map +1 -0
  145. package/dist/orchestrators/codegen/output-location.mjs +23 -31
  146. package/dist/orchestrators/codegen/output-location.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/paths.mjs +8 -1
  148. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  150. package/dist/orchestrators/codegen/service.mjs +286 -58
  151. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  152. package/dist/orchestrators/layers.mjs +31 -0
  153. package/dist/orchestrators/layers.mjs.map +1 -0
  154. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -1
  155. package/dist/orchestrators/lifecycle-prune/index.mjs +8 -10
  156. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -1
  157. package/dist/orchestrators/network-options.d.mts +52 -0
  158. package/dist/orchestrators/network-options.mjs +43 -0
  159. package/dist/orchestrators/network-options.mjs.map +1 -0
  160. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  161. package/dist/orchestrators/router/cors.mjs.map +1 -1
  162. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  163. package/dist/orchestrators/router/errors.mjs.map +1 -1
  164. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  165. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  166. package/dist/orchestrators/router/profile.mjs +1 -1
  167. package/dist/orchestrators/router/profile.mjs.map +1 -1
  168. package/dist/orchestrators/router/service.d.mts +2 -2
  169. package/dist/orchestrators/router/service.mjs +12 -27
  170. package/dist/orchestrators/router/service.mjs.map +1 -1
  171. package/dist/orchestrators/router/traefik-container.mjs +1 -1
  172. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  173. package/dist/orchestrators/snapshot/capture.mjs +171 -195
  174. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  175. package/dist/orchestrators/snapshot/descriptor.d.mts +1 -1
  176. package/dist/orchestrators/snapshot/descriptor.mjs +53 -11
  177. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  178. package/dist/orchestrators/snapshot/identity-guard.mjs +3 -5
  179. package/dist/orchestrators/snapshot/identity-guard.mjs.map +1 -1
  180. package/dist/orchestrators/snapshot/image-bundle-tags.mjs +32 -101
  181. package/dist/orchestrators/snapshot/image-bundle-tags.mjs.map +1 -1
  182. package/dist/orchestrators/snapshot/index.mjs +1 -4
  183. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  184. package/dist/orchestrators/snapshot/interrupted-restore.mjs +116 -0
  185. package/dist/orchestrators/snapshot/interrupted-restore.mjs.map +1 -0
  186. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -1
  187. package/dist/orchestrators/snapshot/prune.mjs +40 -31
  188. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  189. package/dist/orchestrators/snapshot/restore.mjs +221 -196
  190. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  191. package/dist/orchestrators/snapshot/service.mjs +72 -62
  192. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  193. package/dist/orchestrators/snapshot/wipe.mjs +67 -56
  194. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  195. package/dist/plugins/account/codegen.mjs +3 -0
  196. package/dist/plugins/account/codegen.mjs.map +1 -1
  197. package/dist/plugins/account/errors.d.mts +2 -2
  198. package/dist/plugins/account/errors.mjs +1 -4
  199. package/dist/plugins/account/errors.mjs.map +1 -1
  200. package/dist/plugins/account/funding.mjs +3 -27
  201. package/dist/plugins/account/funding.mjs.map +1 -1
  202. package/dist/plugins/account/index.d.mts +3 -8
  203. package/dist/plugins/account/index.mjs +71 -35
  204. package/dist/plugins/account/index.mjs.map +1 -1
  205. package/dist/plugins/account/keypair.d.mts +8 -7
  206. package/dist/plugins/account/keypair.mjs +5 -18
  207. package/dist/plugins/account/keypair.mjs.map +1 -1
  208. package/dist/plugins/account/lease.mjs.map +1 -1
  209. package/dist/plugins/account/registry.d.mts +1 -46
  210. package/dist/plugins/account/registry.mjs.map +1 -1
  211. package/dist/plugins/account/service.d.mts +43 -34
  212. package/dist/plugins/account/service.mjs +9 -54
  213. package/dist/plugins/account/service.mjs.map +1 -1
  214. package/dist/plugins/account/snapshot.mjs.map +1 -1
  215. package/dist/plugins/account/variants/ephemeral.mjs.map +1 -1
  216. package/dist/plugins/account/variants/impersonate.mjs.map +1 -1
  217. package/dist/plugins/account/variants/signer.mjs.map +1 -1
  218. package/dist/plugins/action/discriminator.mjs.map +1 -1
  219. package/dist/plugins/action/errors.mjs +1 -4
  220. package/dist/plugins/action/errors.mjs.map +1 -1
  221. package/dist/plugins/action/execute.mjs +3 -4
  222. package/dist/plugins/action/execute.mjs.map +1 -1
  223. package/dist/plugins/action/index.d.mts +2 -2
  224. package/dist/plugins/action/index.mjs +7 -11
  225. package/dist/plugins/action/index.mjs.map +1 -1
  226. package/dist/plugins/action/service.d.mts +5 -7
  227. package/dist/plugins/action/service.mjs +2 -16
  228. package/dist/plugins/action/service.mjs.map +1 -1
  229. package/dist/plugins/coin/address-resolution.mjs.map +1 -1
  230. package/dist/plugins/coin/codegen.mjs +97 -16
  231. package/dist/plugins/coin/codegen.mjs.map +1 -1
  232. package/dist/plugins/coin/discovery.mjs.map +1 -1
  233. package/dist/plugins/coin/errors.mjs +1 -4
  234. package/dist/plugins/coin/errors.mjs.map +1 -1
  235. package/dist/plugins/coin/index.d.mts +4 -34
  236. package/dist/plugins/coin/index.mjs +47 -28
  237. package/dist/plugins/coin/index.mjs.map +1 -1
  238. package/dist/plugins/coin/metadata.d.mts +1 -0
  239. package/dist/plugins/coin/metadata.mjs +8 -9
  240. package/dist/plugins/coin/metadata.mjs.map +1 -1
  241. package/dist/plugins/coin/mint.mjs +7 -21
  242. package/dist/plugins/coin/mint.mjs.map +1 -1
  243. package/dist/plugins/coin/registry.mjs +33 -20
  244. package/dist/plugins/coin/registry.mjs.map +1 -1
  245. package/dist/plugins/coin/service.d.mts +1 -1
  246. package/dist/plugins/coin/service.mjs +1 -8
  247. package/dist/plugins/coin/service.mjs.map +1 -1
  248. package/dist/plugins/coin/snapshot.mjs.map +1 -1
  249. package/dist/plugins/coin/type-strings.mjs.map +1 -1
  250. package/dist/plugins/dashboard/domain.mjs +106 -167
  251. package/dist/plugins/dashboard/domain.mjs.map +1 -1
  252. package/dist/plugins/dashboard/index.mjs +13 -13
  253. package/dist/plugins/dashboard/index.mjs.map +1 -1
  254. package/dist/plugins/dashboard/origin-policy.mjs +3 -3
  255. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -1
  256. package/dist/plugins/dashboard/routable.mjs.map +1 -1
  257. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -1
  258. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -1
  259. package/dist/plugins/dashboard/schema/root.mjs +23 -44
  260. package/dist/plugins/dashboard/schema/root.mjs.map +1 -1
  261. package/dist/plugins/dashboard/schema/types.mjs +37 -91
  262. package/dist/plugins/dashboard/schema/types.mjs.map +1 -1
  263. package/dist/plugins/dashboard/schema.mjs.map +1 -1
  264. package/dist/plugins/dashboard/server.mjs.map +1 -1
  265. package/dist/plugins/deepbook/codegen.d.mts +12 -11
  266. package/dist/plugins/deepbook/codegen.mjs +108 -11
  267. package/dist/plugins/deepbook/codegen.mjs.map +1 -1
  268. package/dist/plugins/deepbook/deploy.mjs +7 -14
  269. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  270. package/dist/plugins/deepbook/errors.mjs +4 -2
  271. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  272. package/dist/plugins/deepbook/faucet-strategy.mjs +4 -10
  273. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  274. package/dist/plugins/deepbook/hash.mjs.map +1 -1
  275. package/dist/plugins/deepbook/index.d.mts +38 -34
  276. package/dist/plugins/deepbook/index.mjs +133 -64
  277. package/dist/plugins/deepbook/index.mjs.map +1 -1
  278. package/dist/plugins/deepbook/plugin-key.mjs.map +1 -1
  279. package/dist/plugins/deepbook/pyth/index.mjs +4 -8
  280. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  281. package/dist/plugins/deepbook/snapshot.mjs +0 -1
  282. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  283. package/dist/plugins/deepbook/type-strings.mjs.map +1 -1
  284. package/dist/plugins/deepbook/types.d.mts +2 -1
  285. package/dist/plugins/deepbook/types.mjs.map +1 -1
  286. package/dist/plugins/faucet/dispatcher.d.mts +3 -3
  287. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  288. package/dist/plugins/faucet/errors.mjs.map +1 -1
  289. package/dist/plugins/faucet/http.mjs +2 -10
  290. package/dist/plugins/faucet/http.mjs.map +1 -1
  291. package/dist/plugins/faucet/index.mjs +0 -1
  292. package/dist/plugins/faucet/index.mjs.map +1 -1
  293. package/dist/plugins/host-service/errors.d.mts +1 -3
  294. package/dist/plugins/host-service/errors.mjs +1 -2
  295. package/dist/plugins/host-service/errors.mjs.map +1 -1
  296. package/dist/plugins/host-service/index.d.mts +1 -2
  297. package/dist/plugins/host-service/index.mjs +11 -11
  298. package/dist/plugins/host-service/index.mjs.map +1 -1
  299. package/dist/plugins/host-service/routable.mjs.map +1 -1
  300. package/dist/plugins/host-service/service.mjs +13 -13
  301. package/dist/plugins/host-service/service.mjs.map +1 -1
  302. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -1
  303. package/dist/plugins/internal/codegen-helpers.mjs +2 -0
  304. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -1
  305. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -1
  306. package/dist/plugins/{postgres → internal/postgres-sidecar}/connection.mjs +1 -1
  307. package/dist/plugins/internal/postgres-sidecar/connection.mjs.map +1 -0
  308. package/dist/plugins/{postgres → internal/postgres-sidecar}/db-ensure.mjs +30 -16
  309. package/dist/plugins/internal/postgres-sidecar/db-ensure.mjs.map +1 -0
  310. package/dist/plugins/internal/postgres-sidecar/errors.mjs +21 -0
  311. package/dist/plugins/internal/postgres-sidecar/errors.mjs.map +1 -0
  312. package/dist/{substrate/runtime/scoped-multimap → plugins/internal/postgres-sidecar}/index.mjs +1 -0
  313. package/dist/plugins/internal/postgres-sidecar/service.mjs +121 -0
  314. package/dist/plugins/internal/postgres-sidecar/service.mjs.map +1 -0
  315. package/dist/plugins/package/build.mjs +2 -2
  316. package/dist/plugins/package/build.mjs.map +1 -1
  317. package/dist/plugins/package/codegen.d.mts +7 -14
  318. package/dist/plugins/package/codegen.mjs +187 -59
  319. package/dist/plugins/package/codegen.mjs.map +1 -1
  320. package/dist/plugins/package/dep-resolution.mjs +51 -3
  321. package/dist/plugins/package/dep-resolution.mjs.map +1 -1
  322. package/dist/plugins/package/errors.mjs +1 -4
  323. package/dist/plugins/package/errors.mjs.map +1 -1
  324. package/dist/plugins/package/git-source.d.mts +18 -0
  325. package/dist/plugins/package/git-source.mjs +119 -0
  326. package/dist/plugins/package/git-source.mjs.map +1 -0
  327. package/dist/plugins/package/index.d.mts +28 -19
  328. package/dist/plugins/package/index.mjs +107 -32
  329. package/dist/plugins/package/index.mjs.map +1 -1
  330. package/dist/plugins/package/mode-known.mjs +2 -2
  331. package/dist/plugins/package/mode-known.mjs.map +1 -1
  332. package/dist/plugins/package/mode-local.mjs +18 -35
  333. package/dist/plugins/package/mode-local.mjs.map +1 -1
  334. package/dist/plugins/package/publish-executor.mjs +13 -8
  335. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  336. package/dist/plugins/package/publish-output.d.mts +1 -11
  337. package/dist/plugins/package/publish-output.mjs +1 -9
  338. package/dist/plugins/package/publish-output.mjs.map +1 -1
  339. package/dist/plugins/package/registry.d.mts +1 -1
  340. package/dist/plugins/package/registry.mjs +26 -14
  341. package/dist/plugins/package/registry.mjs.map +1 -1
  342. package/dist/plugins/package/service.mjs.map +1 -1
  343. package/dist/plugins/package/snapshot.mjs.map +1 -1
  344. package/dist/plugins/router-entrypoints.mjs +1 -3
  345. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  346. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +1 -2
  347. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  348. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +1 -6
  349. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  350. package/dist/plugins/seal/codegen.d.mts +1 -5
  351. package/dist/plugins/seal/codegen.mjs +83 -12
  352. package/dist/plugins/seal/codegen.mjs.map +1 -1
  353. package/dist/plugins/seal/config-render.mjs +2 -6
  354. package/dist/plugins/seal/config-render.mjs.map +1 -1
  355. package/dist/plugins/seal/deploy.mjs +18 -29
  356. package/dist/plugins/seal/deploy.mjs.map +1 -1
  357. package/dist/plugins/seal/errors.d.mts +4 -5
  358. package/dist/plugins/seal/errors.mjs +1 -8
  359. package/dist/plugins/seal/errors.mjs.map +1 -1
  360. package/dist/plugins/seal/index.d.mts +7 -28
  361. package/dist/plugins/seal/index.mjs +69 -47
  362. package/dist/plugins/seal/index.mjs.map +1 -1
  363. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  364. package/dist/plugins/seal/key-server.mjs +1 -6
  365. package/dist/plugins/seal/key-server.mjs.map +1 -1
  366. package/dist/plugins/seal/keygen.mjs +2 -3
  367. package/dist/plugins/seal/keygen.mjs.map +1 -1
  368. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  369. package/dist/plugins/seal/mode/live.mjs +1 -1
  370. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  371. package/dist/plugins/seal/mode/local-keygen.mjs +4 -10
  372. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  373. package/dist/plugins/seal/plugin-key.mjs.map +1 -1
  374. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  375. package/dist/plugins/seal/routable.mjs.map +1 -1
  376. package/dist/plugins/seal/service.mjs.map +1 -1
  377. package/dist/plugins/seal/snapshot.mjs +1 -2
  378. package/dist/plugins/seal/snapshot.mjs.map +1 -1
  379. package/dist/plugins/sui/auto-tick.mjs +5 -5
  380. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  381. package/dist/plugins/sui/chain-build-container.mjs +2 -2
  382. package/dist/plugins/sui/chain-build-container.mjs.map +1 -1
  383. package/dist/plugins/sui/chain-probe.mjs +4 -4
  384. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  385. package/dist/plugins/sui/codegen.d.mts +9 -7
  386. package/dist/plugins/sui/codegen.mjs +49 -46
  387. package/dist/plugins/sui/codegen.mjs.map +1 -1
  388. package/dist/plugins/sui/errors.d.mts +1 -1
  389. package/dist/plugins/sui/errors.mjs +1 -9
  390. package/dist/plugins/sui/errors.mjs.map +1 -1
  391. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.d.mts +1 -1
  392. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/index.mjs +3 -7
  393. package/dist/plugins/sui/exec/index.mjs.map +1 -0
  394. package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.mjs +1 -1
  395. package/dist/plugins/sui/exec/sign-and-dispatch.mjs.map +1 -0
  396. package/dist/plugins/sui/fork-faucet-strategy.mjs +2 -6
  397. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -1
  398. package/dist/plugins/sui/fork-orchestration.mjs +13 -23
  399. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  400. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  401. package/dist/plugins/sui/index.d.mts +34 -83
  402. package/dist/plugins/sui/index.mjs +200 -68
  403. package/dist/plugins/sui/index.mjs.map +1 -1
  404. package/dist/{substrate/runtime/sui-ledger → plugins/sui/ledger}/object-ref.mjs +1 -1
  405. package/dist/plugins/sui/ledger/object-ref.mjs.map +1 -0
  406. package/dist/plugins/sui/local-faucet-strategy.mjs +1 -5
  407. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -1
  408. package/dist/plugins/sui/log-attrs.mjs +11 -0
  409. package/dist/plugins/sui/log-attrs.mjs.map +1 -0
  410. package/dist/plugins/sui/mode/external.mjs +4 -12
  411. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  412. package/dist/plugins/sui/mode/fork.mjs +19 -16
  413. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  414. package/dist/plugins/sui/mode/live.mjs +4 -17
  415. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  416. package/dist/plugins/sui/mode/local.d.mts +1 -0
  417. package/dist/plugins/sui/mode/local.mjs +203 -61
  418. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  419. package/dist/plugins/sui/mode/shared-boot.mjs +18 -23
  420. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  421. package/dist/plugins/sui/mode/shared.d.mts +6 -7
  422. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  423. package/dist/plugins/sui/mode/spec.d.mts +23 -6
  424. package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.mjs +28 -30
  425. package/dist/plugins/sui/move/index.mjs.map +1 -0
  426. package/dist/plugins/sui/move-summary-runner.mjs +8 -4
  427. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -1
  428. package/dist/{substrate/network.d.mts → plugins/sui/network-config.d.mts} +11 -10
  429. package/dist/plugins/sui/network-resolver.d.mts +6 -6
  430. package/dist/plugins/sui/routable.mjs.map +1 -1
  431. package/dist/plugins/sui/service.mjs +10 -6
  432. package/dist/plugins/sui/service.mjs.map +1 -1
  433. package/dist/plugins/sui/snapshot.mjs +10 -5
  434. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  435. package/dist/plugins/wallet/codegen.d.mts +8 -6
  436. package/dist/plugins/wallet/codegen.mjs +4 -10
  437. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  438. package/dist/plugins/wallet/errors.mjs +1 -4
  439. package/dist/plugins/wallet/errors.mjs.map +1 -1
  440. package/dist/plugins/wallet/index.d.mts +3 -6
  441. package/dist/plugins/wallet/index.mjs +16 -21
  442. package/dist/plugins/wallet/index.mjs.map +1 -1
  443. package/dist/plugins/wallet/origin-policy.mjs +3 -3
  444. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  445. package/dist/plugins/wallet/pairing.mjs +6 -24
  446. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  447. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  448. package/dist/plugins/wallet/routable.mjs.map +1 -1
  449. package/dist/plugins/wallet/server.mjs +17 -24
  450. package/dist/plugins/wallet/server.mjs.map +1 -1
  451. package/dist/plugins/wallet/service.d.mts +2 -2
  452. package/dist/plugins/wallet/service.mjs +4 -15
  453. package/dist/plugins/wallet/service.mjs.map +1 -1
  454. package/dist/plugins/wallet/snapshot.mjs.map +1 -1
  455. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +1 -5
  456. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  457. package/dist/plugins/walrus/codegen.d.mts +2 -13
  458. package/dist/plugins/walrus/codegen.mjs +93 -28
  459. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  460. package/dist/plugins/walrus/deploy-paths.mjs +2 -3
  461. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  462. package/dist/plugins/walrus/deploy.mjs +26 -19
  463. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  464. package/dist/plugins/walrus/errors.mjs +1 -8
  465. package/dist/plugins/walrus/errors.mjs.map +1 -1
  466. package/dist/plugins/walrus/faucet-strategy.mjs +15 -1
  467. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  468. package/dist/plugins/walrus/index.d.mts +13 -44
  469. package/dist/plugins/walrus/index.mjs +119 -122
  470. package/dist/plugins/walrus/index.mjs.map +1 -1
  471. package/dist/plugins/walrus/mode/known-deploy.mjs +6 -6
  472. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  473. package/dist/plugins/walrus/mode/local-cluster.d.mts +2 -2
  474. package/dist/plugins/walrus/mode/local-cluster.mjs +2 -10
  475. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  476. package/dist/plugins/walrus/plugin-key.mjs.map +1 -1
  477. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  478. package/dist/plugins/walrus/routable.mjs.map +1 -1
  479. package/dist/plugins/walrus/service.mjs.map +1 -1
  480. package/dist/plugins/walrus/snapshot.mjs +3 -3
  481. package/dist/plugins/walrus/snapshot.mjs.map +1 -1
  482. package/dist/plugins/walrus/storage-nodes.mjs +53 -14
  483. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  484. package/dist/plugins/walrus/wal-swap.mjs +4 -8
  485. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  486. package/dist/primitives/artifact-publisher.mjs.map +1 -1
  487. package/dist/primitives/cache.d.mts +1 -1
  488. package/dist/runtime/docker/client.mjs +47 -3
  489. package/dist/runtime/docker/client.mjs.map +1 -1
  490. package/dist/runtime/docker/container.mjs +37 -57
  491. package/dist/runtime/docker/container.mjs.map +1 -1
  492. package/dist/runtime/docker/errors.mjs.map +1 -1
  493. package/dist/runtime/docker/exec.mjs +2 -2
  494. package/dist/runtime/docker/exec.mjs.map +1 -1
  495. package/dist/runtime/docker/image.mjs +10 -11
  496. package/dist/runtime/docker/image.mjs.map +1 -1
  497. package/dist/runtime/docker/index.mjs +0 -1
  498. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -1
  499. package/dist/runtime/docker/inventory.mjs +9 -9
  500. package/dist/runtime/docker/inventory.mjs.map +1 -1
  501. package/dist/runtime/docker/labels.mjs +12 -1
  502. package/dist/runtime/docker/labels.mjs.map +1 -1
  503. package/dist/runtime/docker/network.mjs +6 -6
  504. package/dist/runtime/docker/network.mjs.map +1 -1
  505. package/dist/runtime/docker/render-run-args.mjs.map +1 -1
  506. package/dist/runtime/docker/service.mjs +31 -45
  507. package/dist/runtime/docker/service.mjs.map +1 -1
  508. package/dist/runtime/docker/sweep.mjs +14 -64
  509. package/dist/runtime/docker/sweep.mjs.map +1 -1
  510. package/dist/runtime/docker/volume.mjs +1 -1
  511. package/dist/runtime/docker/volume.mjs.map +1 -1
  512. package/dist/runtime/docker/wrap.mjs +14 -2
  513. package/dist/runtime/docker/wrap.mjs.map +1 -1
  514. package/dist/substrate/brand.d.mts +2 -5
  515. package/dist/substrate/brand.mjs +3 -2
  516. package/dist/substrate/brand.mjs.map +1 -1
  517. package/dist/substrate/cross-process.mjs +2 -16
  518. package/dist/substrate/cross-process.mjs.map +1 -1
  519. package/dist/substrate/event-time.mjs +0 -2
  520. package/dist/substrate/event-time.mjs.map +1 -1
  521. package/dist/substrate/events.d.mts +46 -16
  522. package/dist/substrate/identity.d.mts +11 -5
  523. package/dist/substrate/manifest.d.mts +33 -26
  524. package/dist/substrate/manifest.mjs +8 -3
  525. package/dist/substrate/manifest.mjs.map +1 -1
  526. package/dist/substrate/options.d.mts +33 -4
  527. package/dist/substrate/plugin-ctx.d.mts +70 -0
  528. package/dist/substrate/plugin-ctx.mjs +66 -0
  529. package/dist/substrate/plugin-ctx.mjs.map +1 -0
  530. package/dist/substrate/plugin.d.mts +46 -38
  531. package/dist/substrate/plugin.mjs +13 -9
  532. package/dist/substrate/plugin.mjs.map +1 -1
  533. package/dist/substrate/projection.d.mts +1 -1
  534. package/dist/substrate/runtime/atomic-write.mjs +3 -4
  535. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  536. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  537. package/dist/substrate/runtime/cache/service.mjs +50 -20
  538. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  539. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  540. package/dist/substrate/runtime/control-plane/domain.mjs +34 -12
  541. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -1
  542. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -1
  543. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +14 -17
  544. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  545. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  546. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  547. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs.map +1 -1
  548. package/dist/substrate/runtime/cross-process/index.mjs +0 -2
  549. package/dist/substrate/runtime/cross-process/live-clock.mjs +1 -1
  550. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -1
  551. package/dist/substrate/runtime/cross-process/liveness.mjs +11 -18
  552. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  553. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +2 -2
  554. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -1
  555. package/dist/substrate/runtime/cross-process/roster.mjs +17 -127
  556. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  557. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -1
  558. package/dist/substrate/runtime/cross-process/stack-lock.mjs +29 -28
  559. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  560. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  561. package/dist/substrate/runtime/errors.mjs +1 -13
  562. package/dist/substrate/runtime/errors.mjs.map +1 -1
  563. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -1
  564. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -1
  565. package/dist/substrate/runtime/host-gateway.mjs.map +1 -1
  566. package/dist/substrate/runtime/host-tree-tar/index.mjs +15 -163
  567. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  568. package/dist/substrate/runtime/http-probe.d.mts +1 -3
  569. package/dist/substrate/runtime/http-probe.mjs.map +1 -1
  570. package/dist/substrate/runtime/index.mjs +1 -6
  571. package/dist/substrate/runtime/lease-broker/service.mjs +5 -23
  572. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  573. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +3 -3
  574. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  575. package/dist/substrate/runtime/lifecycle/graph-input-id.d.mts +1 -0
  576. package/dist/substrate/runtime/lifecycle/graph-input-id.mjs +133 -0
  577. package/dist/substrate/runtime/lifecycle/graph-input-id.mjs.map +1 -0
  578. package/dist/substrate/runtime/lifecycle/index.mjs +2 -2
  579. package/dist/substrate/runtime/lifecycle/plugin-registry.d.mts +1 -1
  580. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +22 -1
  581. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  582. package/dist/substrate/runtime/lifecycle/ready-gate.mjs +2 -15
  583. package/dist/substrate/runtime/lifecycle/ready-gate.mjs.map +1 -1
  584. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +29 -25
  585. package/dist/substrate/runtime/lifecycle/selective-restart.mjs.map +1 -1
  586. package/dist/substrate/runtime/lifecycle/signals.mjs +1 -1
  587. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  588. package/dist/substrate/runtime/lifecycle/state-machine.mjs.map +1 -1
  589. package/dist/substrate/runtime/lifecycle/watch-attribution.d.mts +1 -1
  590. package/dist/substrate/runtime/lifecycle/watch-attribution.mjs +0 -1
  591. package/dist/substrate/runtime/lifecycle/watch-attribution.mjs.map +1 -1
  592. package/dist/substrate/runtime/managed-container.d.mts +5 -1
  593. package/dist/substrate/runtime/managed-container.mjs +8 -10
  594. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  595. package/dist/substrate/runtime/manifest/manifest.mjs +8 -30
  596. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  597. package/dist/substrate/runtime/mode-errors.d.mts +1 -2
  598. package/dist/substrate/runtime/mode-errors.mjs.map +1 -1
  599. package/dist/substrate/runtime/observability/cascade-formatter.mjs +1 -11
  600. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  601. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -1
  602. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  603. package/dist/substrate/runtime/observability/index.mjs +4 -6
  604. package/dist/substrate/runtime/observability/log-attrs.mjs +46 -0
  605. package/dist/substrate/runtime/observability/log-attrs.mjs.map +1 -0
  606. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -1
  607. package/dist/substrate/runtime/observability/logger.mjs +3 -3
  608. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  609. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -1
  610. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  611. package/dist/substrate/runtime/observability/process-lines.mjs.map +1 -1
  612. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  613. package/dist/substrate/runtime/observability/subprocess-capture.mjs +2 -2
  614. package/dist/substrate/runtime/observability/subprocess-capture.mjs.map +1 -1
  615. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -1
  616. package/dist/substrate/runtime/paths.mjs +27 -9
  617. package/dist/substrate/runtime/paths.mjs.map +1 -1
  618. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -1
  619. package/dist/substrate/runtime/port-broker/service.mjs +10 -27
  620. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  621. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  622. package/dist/substrate/runtime/probes.d.mts +2 -3
  623. package/dist/substrate/runtime/probes.mjs.map +1 -1
  624. package/dist/substrate/runtime/process-supervisor.mjs.map +1 -1
  625. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  626. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  627. package/dist/substrate/runtime/projection/update.mjs +87 -11
  628. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  629. package/dist/substrate/runtime/random-suffix.mjs.map +1 -1
  630. package/dist/substrate/runtime/reconcile/fs-plan.mjs +146 -0
  631. package/dist/substrate/runtime/reconcile/fs-plan.mjs.map +1 -0
  632. package/dist/substrate/runtime/reconcile/graph.mjs +19 -0
  633. package/dist/substrate/runtime/reconcile/graph.mjs.map +1 -0
  634. package/dist/substrate/runtime/reconcile/index.mjs +5 -0
  635. package/dist/substrate/runtime/reconcile/label.mjs +41 -0
  636. package/dist/substrate/runtime/reconcile/label.mjs.map +1 -0
  637. package/dist/substrate/runtime/reconcile/spec.mjs +15 -0
  638. package/dist/substrate/runtime/reconcile/spec.mjs.map +1 -0
  639. package/dist/substrate/runtime/retry-policy.d.mts +2 -3
  640. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  641. package/dist/substrate/runtime/routed-url.mjs.map +1 -1
  642. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  643. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  644. package/dist/substrate/runtime/stage-and-swap/index.mjs +49 -12
  645. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  646. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -1
  647. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  648. package/dist/substrate/runtime/strategy-registry/service.mjs +29 -17
  649. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  650. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -1
  651. package/dist/substrate/runtime/supervisor/acquire-node.mjs +188 -56
  652. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -1
  653. package/dist/substrate/runtime/supervisor/background-tasks.mjs +79 -65
  654. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -1
  655. package/dist/substrate/runtime/supervisor/command-loop.mjs +82 -23
  656. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -1
  657. package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs +16 -0
  658. package/dist/substrate/runtime/supervisor/contribution-dispatcher.mjs.map +1 -0
  659. package/dist/substrate/runtime/supervisor/errors.mjs +11 -2
  660. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -1
  661. package/dist/substrate/runtime/supervisor/index.mjs +2 -0
  662. package/dist/substrate/runtime/supervisor/shutdown.mjs +6 -6
  663. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -1
  664. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +60 -70
  665. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -1
  666. package/dist/substrate/runtime/supervisor/state.d.mts +1 -1
  667. package/dist/substrate/runtime/supervisor/state.mjs +1 -1
  668. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -1
  669. package/dist/substrate/runtime/supervisor/teardown.mjs +10 -9
  670. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -1
  671. package/dist/substrate/runtime/supervisor/wiring.mjs +6 -20
  672. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -1
  673. package/dist/substrate/runtime/tar/reader.mjs +216 -0
  674. package/dist/substrate/runtime/tar/reader.mjs.map +1 -0
  675. package/dist/substrate/runtime/typed-env.mjs.map +1 -1
  676. package/dist/substrate/versioned-doc-schema.mjs.map +1 -1
  677. package/dist/substrate/versioned-doc-sync.mjs +5 -5
  678. package/dist/substrate/versioned-doc-sync.mjs.map +1 -1
  679. package/dist/surfaces/cli/command-tree.mjs +49 -7
  680. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  681. package/dist/surfaces/cli/commands/config.mjs +1 -1
  682. package/dist/surfaces/cli/commands/config.mjs.map +1 -1
  683. package/dist/surfaces/cli/commands/confirm-node.mjs.map +1 -1
  684. package/dist/surfaces/cli/commands/confirm.mjs.map +1 -1
  685. package/dist/surfaces/cli/commands/doctor.mjs +1 -1
  686. package/dist/surfaces/cli/commands/doctor.mjs.map +1 -1
  687. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -1
  688. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  689. package/dist/surfaces/cli/commands/prune.mjs +1 -1
  690. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  691. package/dist/surfaces/cli/commands/snapshot.mjs +1 -1
  692. package/dist/surfaces/cli/commands/snapshot.mjs.map +1 -1
  693. package/dist/surfaces/cli/commands/status.mjs +1 -1
  694. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  695. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  696. package/dist/surfaces/cli/commands/wipe.mjs +3 -4
  697. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  698. package/dist/surfaces/cli/envelope.mjs.map +1 -1
  699. package/dist/surfaces/cli/errors.mjs.map +1 -1
  700. package/dist/surfaces/cli/flags.mjs.map +1 -1
  701. package/dist/surfaces/cli/index.mjs +45 -14
  702. package/dist/surfaces/cli/index.mjs.map +1 -1
  703. package/dist/surfaces/cli/output.mjs.map +1 -1
  704. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  705. package/dist/surfaces/tui/app.mjs +0 -21
  706. package/dist/surfaces/tui/app.mjs.map +1 -1
  707. package/dist/surfaces/tui/dashboard.mjs +0 -48
  708. package/dist/surfaces/tui/dashboard.mjs.map +1 -1
  709. package/dist/surfaces/tui/display-derivation.mjs +80 -16
  710. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  711. package/dist/surfaces/tui/errors.mjs.map +1 -1
  712. package/dist/surfaces/tui/event-log.mjs +0 -9
  713. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  714. package/dist/surfaces/tui/heartbeat.mjs.map +1 -1
  715. package/dist/surfaces/tui/index.mjs +2 -2
  716. package/dist/surfaces/tui/index.mjs.map +1 -1
  717. package/dist/surfaces/tui/input.mjs.map +1 -1
  718. package/dist/surfaces/tui/mode-detect.mjs.map +1 -1
  719. package/dist/surfaces/tui/mount-ink.mjs.map +1 -1
  720. package/dist/surfaces/tui/plain-renderer.mjs +26 -19
  721. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  722. package/dist/surfaces/tui/resource-table.mjs +8 -10
  723. package/dist/surfaces/tui/resource-table.mjs.map +1 -1
  724. package/images/postgres/Dockerfile +0 -1
  725. package/images/sui/Dockerfile +27 -54
  726. package/images/sui/entrypoint.sh +17 -179
  727. package/package.json +23 -15
  728. package/dashboard-ui/assets/index-Bmi1UtAg.js +0 -1356
  729. package/dashboard-ui/assets/index-D5EShVt4.js +0 -3
  730. package/dashboard-ui/assets/index-Deml9drg.css +0 -1
  731. package/dist/api/plugin-errors.d.mts +0 -7
  732. package/dist/api/plugin-errors.mjs +0 -10
  733. package/dist/api/plugin-errors.mjs.map +0 -1
  734. package/dist/cli/wirings/build-verb-layers.mjs +0 -42
  735. package/dist/cli/wirings/build-verb-layers.mjs.map +0 -1
  736. package/dist/contracts/capability-decl.d.mts +0 -40
  737. package/dist/orchestrators/built-in-plugin-layers.mjs +0 -54
  738. package/dist/orchestrators/built-in-plugin-layers.mjs.map +0 -1
  739. package/dist/orchestrators/run.mjs +0 -91
  740. package/dist/orchestrators/run.mjs.map +0 -1
  741. package/dist/orchestrators/runtime-composition.d.mts +0 -10
  742. package/dist/orchestrators/runtime-composition.mjs +0 -252
  743. package/dist/orchestrators/runtime-composition.mjs.map +0 -1
  744. package/dist/orchestrators/snapshot/capture-command.d.mts +0 -1
  745. package/dist/orchestrators/snapshot/capture-command.mjs +0 -25
  746. package/dist/orchestrators/snapshot/capture-command.mjs.map +0 -1
  747. package/dist/orchestrators/snapshot/pending-marker.mjs +0 -99
  748. package/dist/orchestrators/snapshot/pending-marker.mjs.map +0 -1
  749. package/dist/orchestrators/snapshot/recover-pending.mjs +0 -223
  750. package/dist/orchestrators/snapshot/recover-pending.mjs.map +0 -1
  751. package/dist/orchestrators/snapshot/state-document.d.mts +0 -1
  752. package/dist/orchestrators/snapshot/state-document.mjs +0 -58
  753. package/dist/orchestrators/snapshot/state-document.mjs.map +0 -1
  754. package/dist/plugins/account/spans.mjs +0 -16
  755. package/dist/plugins/account/spans.mjs.map +0 -1
  756. package/dist/plugins/account/variants/env.mjs +0 -24
  757. package/dist/plugins/account/variants/env.mjs.map +0 -1
  758. package/dist/plugins/account/variants/inline.mjs +0 -13
  759. package/dist/plugins/account/variants/inline.mjs.map +0 -1
  760. package/dist/plugins/account/variants/keystore.mjs +0 -91
  761. package/dist/plugins/account/variants/keystore.mjs.map +0 -1
  762. package/dist/plugins/action/spans.mjs +0 -11
  763. package/dist/plugins/action/spans.mjs.map +0 -1
  764. package/dist/plugins/coin/spans.mjs +0 -20
  765. package/dist/plugins/coin/spans.mjs.map +0 -1
  766. package/dist/plugins/deepbook/spans.mjs +0 -18
  767. package/dist/plugins/deepbook/spans.mjs.map +0 -1
  768. package/dist/plugins/faucet/spans.mjs +0 -12
  769. package/dist/plugins/faucet/spans.mjs.map +0 -1
  770. package/dist/plugins/package/spans.mjs +0 -14
  771. package/dist/plugins/package/spans.mjs.map +0 -1
  772. package/dist/plugins/postgres/codegen.mjs +0 -42
  773. package/dist/plugins/postgres/codegen.mjs.map +0 -1
  774. package/dist/plugins/postgres/connection.d.mts +0 -33
  775. package/dist/plugins/postgres/connection.mjs.map +0 -1
  776. package/dist/plugins/postgres/db-ensure.mjs.map +0 -1
  777. package/dist/plugins/postgres/errors.d.mts +0 -60
  778. package/dist/plugins/postgres/errors.mjs +0 -29
  779. package/dist/plugins/postgres/errors.mjs.map +0 -1
  780. package/dist/plugins/postgres/index.d.mts +0 -37
  781. package/dist/plugins/postgres/index.mjs +0 -68
  782. package/dist/plugins/postgres/index.mjs.map +0 -1
  783. package/dist/plugins/postgres/routable.mjs +0 -33
  784. package/dist/plugins/postgres/routable.mjs.map +0 -1
  785. package/dist/plugins/postgres/service.d.mts +0 -50
  786. package/dist/plugins/postgres/service.mjs +0 -179
  787. package/dist/plugins/postgres/service.mjs.map +0 -1
  788. package/dist/plugins/postgres/snapshot.mjs +0 -32
  789. package/dist/plugins/postgres/snapshot.mjs.map +0 -1
  790. package/dist/plugins/postgres/spans.mjs +0 -11
  791. package/dist/plugins/postgres/spans.mjs.map +0 -1
  792. package/dist/plugins/seal/spans.mjs +0 -18
  793. package/dist/plugins/seal/spans.mjs.map +0 -1
  794. package/dist/plugins/sui/spans.mjs +0 -17
  795. package/dist/plugins/sui/spans.mjs.map +0 -1
  796. package/dist/plugins/wallet/spans.mjs +0 -22
  797. package/dist/plugins/wallet/spans.mjs.map +0 -1
  798. package/dist/plugins/walrus/registry-publish.d.mts +0 -24
  799. package/dist/plugins/walrus/spans.mjs +0 -18
  800. package/dist/plugins/walrus/spans.mjs.map +0 -1
  801. package/dist/runtime/docker/logs.d.mts +0 -1
  802. package/dist/runtime/docker/logs.mjs +0 -34
  803. package/dist/runtime/docker/logs.mjs.map +0 -1
  804. package/dist/substrate/runtime/artifact-publisher/index.mjs +0 -86
  805. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +0 -1
  806. package/dist/substrate/runtime/capability-sinks/index.d.mts +0 -1
  807. package/dist/substrate/runtime/capability-sinks/index.mjs +0 -3
  808. package/dist/substrate/runtime/capability-sinks/layer.d.mts +0 -1
  809. package/dist/substrate/runtime/capability-sinks/layer.mjs +0 -31
  810. package/dist/substrate/runtime/capability-sinks/layer.mjs.map +0 -1
  811. package/dist/substrate/runtime/capability-sinks/service.d.mts +0 -95
  812. package/dist/substrate/runtime/capability-sinks/service.mjs +0 -69
  813. package/dist/substrate/runtime/capability-sinks/service.mjs.map +0 -1
  814. package/dist/substrate/runtime/cross-process/lock.d.mts +0 -1
  815. package/dist/substrate/runtime/cross-process/lock.mjs +0 -23
  816. package/dist/substrate/runtime/cross-process/lock.mjs.map +0 -1
  817. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +0 -113
  818. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +0 -1
  819. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs +0 -31
  820. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +0 -1
  821. package/dist/substrate/runtime/observability/formatter-registry.d.mts +0 -1
  822. package/dist/substrate/runtime/observability/formatter-registry.mjs +0 -48
  823. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +0 -1
  824. package/dist/substrate/runtime/observability/span-store.d.mts +0 -1
  825. package/dist/substrate/runtime/observability/span-store.mjs +0 -110
  826. package/dist/substrate/runtime/observability/span-store.mjs.map +0 -1
  827. package/dist/substrate/runtime/observability/spans.d.mts +0 -1
  828. package/dist/substrate/runtime/observability/spans.mjs +0 -87
  829. package/dist/substrate/runtime/observability/spans.mjs.map +0 -1
  830. package/dist/substrate/runtime/projection/index.mjs +0 -4
  831. package/dist/substrate/runtime/projection/persisted.mjs +0 -213
  832. package/dist/substrate/runtime/projection/persisted.mjs.map +0 -1
  833. package/dist/substrate/runtime/scoped-multimap/service.mjs +0 -52
  834. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +0 -1
  835. package/dist/substrate/runtime/scoped-ref-map/index.mjs +0 -2
  836. package/dist/substrate/runtime/scoped-ref-map/service.mjs +0 -83
  837. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +0 -1
  838. package/dist/substrate/runtime/state-store/index.mjs +0 -3
  839. package/dist/substrate/runtime/state-store/schema.d.mts +0 -1
  840. package/dist/substrate/runtime/state-store/schema.mjs +0 -41
  841. package/dist/substrate/runtime/state-store/schema.mjs.map +0 -1
  842. package/dist/substrate/runtime/state-store/service.d.mts +0 -1
  843. package/dist/substrate/runtime/state-store/service.mjs +0 -145
  844. package/dist/substrate/runtime/state-store/service.mjs.map +0 -1
  845. package/dist/substrate/runtime/sui-execute/index.mjs.map +0 -1
  846. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +0 -1
  847. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +0 -1
  848. package/dist/substrate/runtime/sui-move-build/index.mjs.map +0 -1
  849. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +0 -151
  850. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +0 -1
  851. package/dist/substrate/state-store.d.mts +0 -1
  852. /package/dist/orchestrators/{snapshot/pending-marker.d.mts → codegen/id-config.d.mts} +0 -0
  853. /package/dist/orchestrators/snapshot/{recover-pending.d.mts → interrupted-restore.d.mts} +0 -0
  854. /package/dist/{substrate/runtime/sui-execute → plugins/sui/exec}/sign-and-dispatch.d.mts +0 -0
  855. /package/dist/plugins/{postgres/snapshot.d.mts → sui/ledger/object-ref.d.mts} +0 -0
  856. /package/dist/{substrate/runtime/sui-move-build → plugins/sui/move}/index.d.mts +0 -0
  857. /package/dist/substrate/runtime/{state-store/index.d.mts → reconcile/graph.d.mts} +0 -0
  858. /package/dist/substrate/runtime/{cross-process/snapshot-reservation.d.mts → supervisor/contribution-dispatcher.d.mts} +0 -0
@@ -1,32 +1,27 @@
1
- import { RuntimeRoot } from "../paths.mjs";
2
- import { withStackSpan } from "../observability/spans.mjs";
3
- import { CapabilitySinksService } from "../capability-sinks/service.mjs";
4
- import { layerCapabilitySinksDefault } from "../capability-sinks/layer.mjs";
5
- import "../capability-sinks/index.mjs";
6
1
  import { SupervisorBootError } from "./errors.mjs";
2
+ import { noopContributionDispatcher } from "./contribution-dispatcher.mjs";
3
+ import { resolveGraph } from "../lifecycle/dep-graph.mjs";
4
+ import { buildWatchIndex, exactPrefixMatch } from "../lifecycle/watch-attribution.mjs";
5
+ import { plan } from "../reconcile/graph.mjs";
6
+ import { installSignalHandler } from "../lifecycle/signals.mjs";
7
+ import "../lifecycle/index.mjs";
8
+ import { allReadyOrTerminal } from "./state.mjs";
7
9
  import { Logger as Logger$1 } from "../observability/logger.mjs";
8
10
  import { LogStore, makeLogStore } from "../observability/log-store.mjs";
9
- import { SpanStore, makeSpanStore } from "../observability/span-store.mjs";
10
11
  import "../observability/index.mjs";
11
12
  import { ControlPlaneService } from "../control-plane/service.mjs";
13
+ import { RuntimeRoot } from "../paths.mjs";
12
14
  import { controlPlaneDomainFromContext } from "../control-plane/domain.mjs";
13
15
  import { declareAccount, setIdentity } from "../projection/update.mjs";
14
- import { resolveGraph } from "../lifecycle/dep-graph.mjs";
15
- import { buildWatchIndex, exactPrefixMatch } from "../lifecycle/watch-attribution.mjs";
16
- import { planFullDrain } from "../lifecycle/selective-restart.mjs";
17
- import { installSignalHandler } from "../lifecycle/signals.mjs";
18
- import "../lifecycle/index.mjs";
19
16
  import { OptionalService, buildTransitionEmitter, noopLogger, setCyclePhase, withEventPublishingLogger } from "./wiring.mjs";
20
17
  import { acquireFullGraph, buildRegistry } from "./acquire-node.mjs";
21
18
  import { runPostAcquireHook } from "./background-tasks.mjs";
22
19
  import { teardownKeys } from "./teardown.mjs";
23
- import { allReadyOrTerminal } from "./state.mjs";
24
20
  import { commandLoop } from "./command-loop.mjs";
25
- import { Context, Deferred, Effect, Exit, Layer, Queue, Ref, SubscriptionRef, Tracer } from "effect";
21
+ import { Context, Deferred, Effect, Exit, Queue, Ref, SubscriptionRef } from "effect";
26
22
  //#region src/substrate/runtime/supervisor/start-supervisor.ts
27
23
  const loggerAccess = OptionalService(Logger$1);
28
24
  const runtimeRootAccess = OptionalService(RuntimeRoot);
29
- const sinksAccess = OptionalService(CapabilitySinksService);
30
25
  const pendingAccountProjection = (rowKey, resourceId, updatedAt) => {
31
26
  if (!resourceId.startsWith("account/")) return null;
32
27
  const name = resourceId.slice(8);
@@ -65,13 +60,13 @@ const pendingAccountProjection = (rowKey, resourceId, updatedAt) => {
65
60
  * plugin's R-channel narrows to `Scope.Scope` (then to `never` after
66
61
  * the per-plugin Scope is provided).
67
62
  *
68
- * `CapabilitySinksService` extension (ARCHITECTURE.md § Plugin-author
69
- * extension via Layer composition): if the caller layers a
70
- * `CapabilitySinksService` into `pluginContext`, the supervisor
71
- * harvests through THAT instance instead of building its own.
63
+ * Contribution dispatch: the supervisor replays each plugin's
64
+ * buffered ctx contributions through the closed `dispatcher`
65
+ * (snapshotable/routable/codegenable/projection/strategy-contributor).
66
+ * Production callers pass `buildProductionContributionDispatcher(...)`;
67
+ * bare smoke tests omit it and get the no-op dispatcher.
72
68
  */
73
- const startSupervisor = (stack, identity, state, pluginContext = Context.empty(), sinks = [], commandHandler, postAcquireHook, options = {}) => Effect.gen(function* () {
74
- yield* Effect.annotateCurrentSpan({ "devstack.stack.memberCount": stack.members.length });
69
+ const startSupervisor = (stack, identity, state, pluginContext = Context.empty(), dispatcher = noopContributionDispatcher, commandHandler, postAcquireHook, options = {}) => Effect.gen(function* () {
75
70
  const baseLogger = loggerAccess.read(pluginContext, noopLogger);
76
71
  yield* baseLogger.log("supervisor", null, {
77
72
  level: "debug",
@@ -79,7 +74,7 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
79
74
  fields: {
80
75
  app: identity.app,
81
76
  stack: identity.stack,
82
- network: identity.chain,
77
+ network: identity.network,
83
78
  memberCount: stack.members.length
84
79
  }
85
80
  });
@@ -87,7 +82,7 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
87
82
  ...setIdentity(s, {
88
83
  app: identity.app,
89
84
  stack: identity.stack,
90
- network: identity.chain
85
+ network: identity.network
91
86
  }),
92
87
  cycle: {
93
88
  ...s.cycle,
@@ -99,28 +94,42 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
99
94
  const hub = yield* Queue.unbounded();
100
95
  const commands = yield* Queue.unbounded();
101
96
  const queuedCommands = yield* Queue.unbounded();
102
- const stackRestartTask = yield* Ref.make({ tag: "idle" });
103
- const stackRestartSeq = yield* Ref.make(0);
104
- const snapshotCaptureTask = yield* Ref.make({ tag: "idle" });
105
- const snapshotCaptureSeq = yield* Ref.make(0);
97
+ const stackRestartTask = yield* Ref.make(null);
106
98
  const shutdownLatch = yield* Ref.make(false);
107
99
  const shutdownComplete = yield* Deferred.make();
108
100
  const initialAcquireStarted = yield* Ref.make(false);
109
101
  const logStore = yield* makeLogStore(options.logStore ?? {});
110
- const spanStore = yield* makeSpanStore();
111
102
  const logger = withEventPublishingLogger(baseLogger, state, hub, logStore);
112
- const traced = (eff) => Effect.provideService(eff, Tracer.Tracer, spanStore.tracer);
113
- const registry = yield* buildRegistry(graph, yield* Effect.scope, buildTransitionEmitter(state, hub));
103
+ const publishCommand = (command) => Effect.asVoid(Queue.offer(queuedCommands, {
104
+ kind: "fire-and-forget",
105
+ command
106
+ }));
107
+ const submitCommand = (command) => Effect.gen(function* () {
108
+ const completion = yield* Deferred.make();
109
+ yield* Queue.offer(queuedCommands, {
110
+ kind: "submitted",
111
+ submission: {
112
+ command,
113
+ completion
114
+ }
115
+ });
116
+ const exit = yield* Deferred.await(completion);
117
+ if (Exit.isFailure(exit)) return yield* Effect.failCause(exit.cause);
118
+ });
119
+ const supervisorScope = yield* Effect.scope;
120
+ const registry = yield* buildRegistry(graph, supervisorScope, buildTransitionEmitter(state, hub));
114
121
  const controlPlaneDomain = controlPlaneDomainFromContext({
115
122
  pluginContext,
116
123
  graph,
124
+ stackOptions: stack.options,
125
+ devstackVersion: options.devstackVersion ?? null,
117
126
  registry,
118
- logStore,
119
- spanStore
127
+ logStore
120
128
  });
121
- const pluginRuntimeContext = pluginContext.pipe(Context.add(Logger$1, Logger$1.of(logger)), Context.add(LogStore, LogStore.of(logStore)), Context.add(SpanStore, SpanStore.of(spanStore)), Context.add(Tracer.Tracer, spanStore.tracer), Context.add(ControlPlaneService, ControlPlaneService.of({
129
+ const pluginRuntimeContext = pluginContext.pipe(Context.add(Logger$1, Logger$1.of(logger)), Context.add(LogStore, LogStore.of(logStore)), Context.add(ControlPlaneService, ControlPlaneService.of({
122
130
  state,
123
- publishCommand: (command) => Effect.asVoid(Queue.offer(commands, command)),
131
+ publishCommand,
132
+ submitCommand,
124
133
  domain: controlPlaneDomain
125
134
  })));
126
135
  for (const [key, node] of graph.nodes) {
@@ -148,13 +157,10 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
148
157
  const runtimeRootResolved = runtimeRootAccess.read(pluginContext, { root: "" });
149
158
  if (runtimeRootResolved.root === "") yield* Effect.logWarning("supervisor: RuntimeRoot missing from pluginContext; falling back to empty root. Production wiring must layer `layerRuntimeRoot(...)` into pluginContext.");
150
159
  const runtimeRoot = runtimeRootResolved.root;
151
- const sinksService = yield* sinksAccess.readEffect(pluginRuntimeContext, Effect.gen(function* () {
152
- return Context.get(yield* Layer.build(layerCapabilitySinksDefault(sinks)), CapabilitySinksService);
153
- }));
154
160
  const enableCommandLoop = options.commandLoop !== false;
155
161
  if (enableCommandLoop) {
156
- yield* Effect.forkScoped(traced(installSignalHandler(commands)));
157
- yield* Effect.forkScoped(traced(Effect.gen(function* () {
162
+ yield* Effect.forkScoped(installSignalHandler(commands));
163
+ yield* Effect.forkScoped(Effect.gen(function* () {
158
164
  while (true) {
159
165
  const command = yield* Queue.take(commands);
160
166
  yield* Queue.offer(queuedCommands, {
@@ -162,7 +168,7 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
162
168
  command
163
169
  });
164
170
  }
165
- })));
171
+ }));
166
172
  }
167
173
  const supervisorState = {
168
174
  graph,
@@ -170,14 +176,12 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
170
176
  ref: state,
171
177
  hub,
172
178
  queuedCommands,
179
+ supervisorScope,
173
180
  stackRestartTask,
174
- stackRestartSeq,
175
- snapshotCaptureTask,
176
- snapshotCaptureSeq,
177
181
  shutdownLatch,
178
182
  shutdownComplete,
179
183
  pluginContext: pluginRuntimeContext,
180
- sinks: sinksService,
184
+ dispatcher,
181
185
  logger,
182
186
  identity,
183
187
  runtimeRoot,
@@ -187,13 +191,13 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
187
191
  const runInitialAcquire = Effect.gen(function* () {
188
192
  if (yield* Ref.modify(initialAcquireStarted, (started) => [started, true])) return;
189
193
  if (yield* Ref.get(shutdownLatch)) return;
190
- yield* acquireFullGraph(graph, registry, state, hub, pluginRuntimeContext, sinksService, logger, identity, runtimeRoot);
194
+ yield* acquireFullGraph(graph, registry, state, hub, pluginRuntimeContext, dispatcher, logger, identity, supervisorScope);
191
195
  if (yield* Ref.get(shutdownLatch)) return;
192
196
  if (yield* allReadyOrTerminal(graph, registry)) {
193
197
  yield* runPostAcquireHook(supervisorState);
194
198
  if (!(yield* Ref.get(shutdownLatch))) yield* setCyclePhase(state, "running");
195
199
  } else if (!(yield* Ref.get(shutdownLatch))) yield* setCyclePhase(state, "running");
196
- }).pipe(Effect.withSpan("lifecycle.supervisor.initialAcquire"), traced);
200
+ });
197
201
  const watchIndex = buildWatchIndex(graph.nodes);
198
202
  const notifyWatchFire = (path) => Effect.gen(function* () {
199
203
  const matched = /* @__PURE__ */ new Set();
@@ -206,24 +210,14 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
206
210
  tag: "selective-restart.requested",
207
211
  pluginKey: key
208
212
  });
209
- }).pipe(Effect.withSpan("lifecycle.supervisor.notifyWatchFire"));
210
- if (enableCommandLoop) yield* Effect.forkScoped(traced(commandLoop(supervisorState)));
211
- yield* Effect.addFinalizer(() => traced(Effect.gen(function* () {
212
- yield* teardownKeys(graph, registry, planFullDrain(graph).teardownOrder).pipe(Effect.catch(() => Effect.void));
213
- })));
214
- const awaitShutdown = Deferred.await(shutdownComplete).pipe(Effect.withSpan("lifecycle.supervisor.awaitShutdown"), traced);
215
- const runCommand = (command) => Effect.gen(function* () {
216
- const completion = yield* Deferred.make();
217
- yield* Queue.offer(queuedCommands, {
218
- kind: "submitted",
219
- submission: {
220
- command,
221
- completion
222
- }
223
- });
224
- const exit = yield* Deferred.await(completion);
225
- if (Exit.isFailure(exit)) return yield* Effect.failCause(exit.cause);
226
- }).pipe(Effect.withSpan("lifecycle.supervisor.runCommand"), traced);
213
+ });
214
+ if (enableCommandLoop) yield* Effect.forkScoped(commandLoop(supervisorState));
215
+ yield* Effect.addFinalizer(() => Effect.gen(function* () {
216
+ yield* teardownKeys(graph, registry, plan(graph, {
217
+ kind: "graph-keys",
218
+ keys: [...graph.nodes.keys()]
219
+ }).teardownOrder).pipe(Effect.catch(() => Effect.void));
220
+ }));
227
221
  return {
228
222
  handle: {
229
223
  identity,
@@ -231,19 +225,15 @@ const startSupervisor = (stack, identity, state, pluginContext = Context.empty()
231
225
  registry,
232
226
  events: hub,
233
227
  commands,
234
- runCommand,
228
+ runCommand: submitCommand,
235
229
  state,
236
230
  watchIndex,
237
231
  notifyWatchFire,
238
- awaitShutdown
232
+ awaitShutdown: Deferred.await(shutdownComplete)
239
233
  },
240
234
  runInitialAcquire
241
235
  };
242
- }).pipe(withStackSpan("lifecycle.supervisor.startSupervisor", {
243
- app: identity.app,
244
- stack: identity.stack,
245
- network: identity.chain
246
- }));
236
+ });
247
237
  //#endregion
248
238
  export { startSupervisor };
249
239
 
@@ -1 +1 @@
1
- {"version":3,"file":"start-supervisor.mjs","names":["Logger"],"sources":["../../../../src/substrate/runtime/supervisor/start-supervisor.ts"],"sourcesContent":["// Top-level supervisor entry — composes every per-concern module.\n//\n// Responsibilities (in order):\n// 1. Seed projection identity + booting slice so early-mounted\n// renderers see a complete baseline.\n// 2. Resolve the dep graph + boot the registry.\n// 3. Build the substrate-wiring bag: logger overlay, runtime root,\n// CapabilitySinks service (caller-pre-built or substrate-default).\n// 4. Compose the `SupervisorState` record (one bag passed to every\n// module).\n// 5. Build `runInitialAcquire` — the deferred initial-acquire body.\n// 6. Build the watch index + `notifyWatchFire`.\n// 7. Fork the command loop + signal handler.\n// 8. Install the scope-close finalizer (reverse-dep teardown).\n// 9. Return the handle.\n\nimport {\n\tContext,\n\tDeferred,\n\tEffect,\n\tExit,\n\tLayer,\n\tQueue,\n\tRef,\n\tScope,\n\tSubscriptionRef,\n\tTracer,\n} from 'effect';\n\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineCommand, EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { AccountProjection, SubscribableState } from '../../projection.ts';\nimport {\n\tCapabilitySinksService,\n\tlayerCapabilitySinksDefault,\n\ttype OrchestratorSinks,\n} from '../capability-sinks/index.ts';\nimport {\n\tLogger,\n\tLogStore,\n\tSpanStore,\n\tmakeLogStore,\n\tmakeSpanStore,\n\twithStackSpan,\n\ttype LoggerShape,\n\ttype LogStoreConfig,\n} from '../observability/index.ts';\nimport { ControlPlaneService } from '../control-plane/service.ts';\nimport { controlPlaneDomainFromContext } from '../control-plane/domain.ts';\nimport { RuntimeRoot } from '../paths.ts';\nimport { declareAccount, setIdentity } from '../projection/update.ts';\nimport {\n\tbuildWatchIndex,\n\texactPrefixMatch,\n\tinstallSignalHandler,\n\tplanFullDrain,\n\tresolveGraph,\n\ttype PluginRegistry,\n\ttype ResolvedGraph,\n\ttype UnknownDependency,\n\ttype WatchEntry,\n} from '../lifecycle/index.ts';\nimport { acquireFullGraph, buildRegistry } from './acquire-node.ts';\nimport { commandLoop } from './command-loop.ts';\nimport { runPostAcquireHook } from './background-tasks.ts';\nimport {\n\tSupervisorBootError,\n\ttype SupervisorError,\n\ttype SupervisorPostAcquireFailed,\n} from './errors.ts';\nimport {\n\tallReadyOrTerminal,\n\ttype QueuedCommand,\n\ttype SnapshotCaptureTaskState,\n\ttype StackRestartTaskState,\n\ttype SupervisorCommandHandler,\n\ttype SupervisorPostAcquireHook,\n\ttype SupervisorState,\n} from './state.ts';\nimport type { SupervisedStack } from './types.ts';\nimport { teardownKeys } from './teardown.ts';\nimport {\n\tbuildTransitionEmitter,\n\tnoopLogger,\n\tOptionalService,\n\tsetCyclePhase,\n\twithEventPublishingLogger,\n} from './wiring.ts';\n\nconst loggerAccess = OptionalService(Logger);\nconst runtimeRootAccess = OptionalService(RuntimeRoot);\nconst sinksAccess = OptionalService(CapabilitySinksService);\n\nexport interface SupervisorHandle {\n\treadonly identity: Identity;\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly events: Queue.Dequeue<EngineEvent>;\n\treadonly commands: Queue.Enqueue<EngineCommand>;\n\treadonly runCommand: (command: EngineCommand) => Effect.Effect<void, unknown>;\n\treadonly state: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly watchIndex: ReadonlyArray<WatchEntry>;\n\t/** Fire a watch event for the given path. Substrate-level glue:\n\t * the thick L0 watcher calls this; tests call it directly. */\n\treadonly notifyWatchFire: (path: string) => Effect.Effect<void>;\n\t/** Block until the supervisor's command loop sets the shutdown\n\t * latch. The outer runtime then closes the supervisor scope, which\n\t * tears down every plugin in reverse-dep order. */\n\treadonly awaitShutdown: Effect.Effect<void>;\n}\n\nexport interface SupervisorStartup {\n\treadonly handle: SupervisorHandle;\n\treadonly runInitialAcquire: Effect.Effect<void, SupervisorPostAcquireFailed, never>;\n}\n\nexport interface SupervisorStartupOptions {\n\treadonly commandLoop?: boolean;\n\t/** Per-service log-store tuning. Absent fields fall back to the\n\t * `DEVSTACK_DASHBOARD_LOG_*` env vars, then the module defaults\n\t * (2000 records/service, 256 services). Threaded into the\n\t * process-scoped `makeLogStore` below. */\n\treadonly logStore?: LogStoreConfig;\n}\n\nconst pendingAccountProjection = (\n\trowKey: PluginKey,\n\tresourceId: string,\n\tupdatedAt: number,\n): AccountProjection | null => {\n\tif (!resourceId.startsWith('account/')) return null;\n\tconst name = resourceId.slice('account/'.length);\n\tif (name.length === 0) return null;\n\treturn {\n\t\tkey: resourceId as `account/${string}`,\n\t\trowKey,\n\t\tname,\n\t\taddress: null,\n\t\tscheme: null,\n\t\tsource: null,\n\t\tfunding: { status: 'pending', balanceMist: null, requestedMist: null, entries: [] },\n\t\twalletVisible: false,\n\t\tupdatedAt,\n\t};\n};\n\n/**\n * Prepare a supervisor for `stack` without running the initial acquire.\n * The returned `SupervisorHandle` is Scope-managed; the supervisor's\n * lifecycle is the surrounding Scope's lifecycle. Signal handlers,\n * the command loop, and every plugin's scope are children of the\n * supervisor scope. Callers that mount renderers can subscribe to the\n * returned state before invoking `runInitialAcquire`.\n *\n * `pluginContext` carries the substrate-context services available to\n * each plugin's `acquire` body (`IdentityContext`,\n * `ContainerRuntimeService`, `RuntimeRoot`, `StackPathsService`, etc.).\n * Plugins declare what they need by yielding the corresponding\n * `Context.Service` tag from within `Effect.gen`; the supervisor\n * provides this context before running the acquire effect so the\n * plugin's R-channel narrows to `Scope.Scope` (then to `never` after\n * the per-plugin Scope is provided).\n *\n * `CapabilitySinksService` extension (ARCHITECTURE.md § Plugin-author\n * extension via Layer composition): if the caller layers a\n * `CapabilitySinksService` into `pluginContext`, the supervisor\n * harvests through THAT instance instead of building its own.\n */\nexport const startSupervisor = (\n\tstack: SupervisedStack,\n\tidentity: Identity,\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tpluginContext: Context.Context<never> = Context.empty(),\n\tsinks: OrchestratorSinks = [],\n\tcommandHandler?: SupervisorCommandHandler,\n\tpostAcquireHook?: SupervisorPostAcquireHook,\n\toptions: SupervisorStartupOptions = {},\n): Effect.Effect<SupervisorStartup, SupervisorBootError | UnknownDependency, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tyield* Effect.annotateCurrentSpan({\n\t\t\t'devstack.stack.memberCount': stack.members.length,\n\t\t});\n\n\t\t// Optional Logger service — pull from the plugin context if the\n\t\t// caller layered it in (CLI / e2e do). Bare smoke tests get the\n\t\t// no-op fallback so they remain log-free.\n\t\tconst baseLogger: LoggerShape = loggerAccess.read(pluginContext, noopLogger);\n\n\t\tyield* baseLogger.log('supervisor', null, {\n\t\t\tlevel: 'debug',\n\t\t\tmessage: 'supervisor boot start',\n\t\t\tfields: {\n\t\t\t\tapp: identity.app,\n\t\t\t\tstack: identity.stack,\n\t\t\t\tnetwork: identity.chain,\n\t\t\t\tmemberCount: stack.members.length,\n\t\t\t},\n\t\t});\n\n\t\t// Seed the projection's identity and booting slices before\n\t\t// acquire starts so renderers mounting early have a complete\n\t\t// baseline.\n\t\tyield* SubscriptionRef.update(\n\t\t\tstate,\n\t\t\t(s) =>\n\t\t\t\t({\n\t\t\t\t\t...setIdentity(s, {\n\t\t\t\t\t\tapp: identity.app,\n\t\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\t\tnetwork: identity.chain,\n\t\t\t\t\t}),\n\t\t\t\t\tcycle: {\n\t\t\t\t\t\t...s.cycle,\n\t\t\t\t\t\tstartedAt: s.cycle.startedAt === 0 ? Date.now() : s.cycle.startedAt,\n\t\t\t\t\t\tphase: 'booting',\n\t\t\t\t\t},\n\t\t\t\t}) satisfies SubscribableState,\n\t\t);\n\n\t\t// Resolve the dep graph.\n\t\tconst graph = yield* resolveGraph(stack.members).pipe(\n\t\t\tEffect.mapError((cause) => new SupervisorBootError({ cause })),\n\t\t);\n\n\t\t// Event hub + command channel.\n\t\tconst hub = yield* Queue.unbounded<EngineEvent>();\n\t\tconst commands = yield* Queue.unbounded<EngineCommand>();\n\t\tconst queuedCommands = yield* Queue.unbounded<QueuedCommand>();\n\t\tconst stackRestartTask = yield* Ref.make<StackRestartTaskState>({ tag: 'idle' });\n\t\tconst stackRestartSeq = yield* Ref.make(0);\n\t\tconst snapshotCaptureTask = yield* Ref.make<SnapshotCaptureTaskState>({ tag: 'idle' });\n\t\tconst snapshotCaptureSeq = yield* Ref.make(0);\n\t\tconst shutdownLatch = yield* Ref.make(false);\n\t\tconst shutdownComplete = yield* Deferred.make<void>();\n\t\tconst initialAcquireStarted = yield* Ref.make(false);\n\n\t\t// Observability stores (process-scoped, like `state`/`hub`): a\n\t\t// cross-service queryable log ring fed off the SAME logger path that\n\t\t// feeds the projection's per-row tail, and a completed-span ring fed\n\t\t// by a recording Tracer. Both survive `stack.restart` because they\n\t\t// live in this closure (only `cycle.id` bumps on restart). The\n\t\t// dashboard reads them via the control-plane `domain`.\n\t\tconst logStore = yield* makeLogStore(options.logStore ?? {});\n\t\tconst spanStore = yield* makeSpanStore();\n\t\tconst logger = withEventPublishingLogger(baseLogger, state, hub, logStore);\n\n\t\t// Provide the recording Tracer to the supervisor's OWN effects too.\n\t\t// `pluginRuntimeContext` below carries the tracer into plugin\n\t\t// acquire/boot, but the supervisor's forked fibers (command loop,\n\t\t// background snapshot/restart tasks), the teardown finalizer, and the\n\t\t// `lifecycle.supervisor.*` spans run under THIS fiber's ambient context\n\t\t// — which has no tracer unless we add one. Without this, exactly the\n\t\t// dashboard-triggered ops (restart/snapshot/prune) the Traces tab wants\n\t\t// would emit spans into the default no-op tracer and evaporate.\n\t\t// `forkScoped`/finalizers inherit the context at fork/install time, so\n\t\t// stamping the tracer onto each supervisor-owned effect captures them\n\t\t// without double-provisioning the plugin path or disturbing any\n\t\t// caller-provided OTel composition.\n\t\tconst traced = <A, E, R>(eff: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>\n\t\t\tEffect.provideService(eff, Tracer.Tracer, spanStore.tracer);\n\n\t\t// Per-plugin scopes parent off the supervisor scope.\n\t\tconst supervisorScope = yield* Effect.scope;\n\n\t\tconst emit = buildTransitionEmitter(state, hub);\n\t\tconst registry = yield* buildRegistry(graph, supervisorScope, emit);\n\n\t\t// Build the control-plane `domain` accessor surface from the data\n\t\t// the supervisor holds at wiring time: the resolved registry +\n\t\t// graph, plus the (optional) snapshot orchestrator / container\n\t\t// runtime / filesystem the caller may have layered into\n\t\t// `pluginContext`. The projection stays CLOSED — `domain` reads\n\t\t// resolved plugin VALUES via the name-blind registry seam, never\n\t\t// the projection. The registry is process-scoped, so the closure\n\t\t// stays valid across `stack.restart` (only `cycle.id` bumps).\n\t\tconst controlPlaneDomain = controlPlaneDomainFromContext({\n\t\t\tpluginContext,\n\t\t\tgraph,\n\t\t\tregistry,\n\t\t\tlogStore,\n\t\t\tspanStore,\n\t\t});\n\n\t\tconst pluginRuntimeContext = pluginContext.pipe(\n\t\t\tContext.add(Logger, Logger.of(logger)),\n\t\t\t// Observability stores + the recording Tracer. The Tracer is an\n\t\t\t// Effect `Context.Reference`, so adding it here makes every span\n\t\t\t// run with this context (all plugin acquire/boot/op spans —\n\t\t\t// `withSpan`/`spanWithLabels`) record into `spanStore` instead of\n\t\t\t// hitting the default no-op native tracer. The stores themselves\n\t\t\t// are exposed so the control-plane `domain` can query them.\n\t\t\tContext.add(LogStore, LogStore.of(logStore)),\n\t\t\tContext.add(SpanStore, SpanStore.of(spanStore)),\n\t\t\tContext.add(Tracer.Tracer, spanStore.tracer),\n\t\t\t// Expose the control plane (live projection + fire-and-forget\n\t\t\t// command dispatch + the plugin-domain accessor surface) to\n\t\t\t// in-process surfaces like the dashboard plugin. Reads the same\n\t\t\t// `state` ref and `commands` queue the supervisor itself drives.\n\t\t\tContext.add(\n\t\t\t\tControlPlaneService,\n\t\t\t\tControlPlaneService.of({\n\t\t\t\t\tstate,\n\t\t\t\t\tpublishCommand: (command) => Effect.asVoid(Queue.offer(commands, command)),\n\t\t\t\t\tdomain: controlPlaneDomain,\n\t\t\t\t}),\n\t\t\t),\n\t\t) as Context.Context<never>;\n\n\t\t// Declare a row for every plugin so the projection's\n\t\t// `lifecycle.statusChanged` events have a row to attach to.\n\t\t// `section` is plugin-declared at `definePlugin({ section })`\n\t\t// time; we stamp it onto the row here so the TUI groups rows\n\t\t// without pattern-matching on plugin-name substrings.\n\t\tfor (const [key, node] of graph.nodes) {\n\t\t\tconst declaredAccount = pendingAccountProjection(key, node.member.id, Date.now());\n\t\t\tyield* SubscriptionRef.update(state, (s) => ({\n\t\t\t\t...(declaredAccount === null ? s : declareAccount(s, declaredAccount)),\n\t\t\t\trows: s.rows.some((r) => r.key === key)\n\t\t\t\t\t? s.rows\n\t\t\t\t\t: [\n\t\t\t\t\t\t\t...s.rows,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\trole: node.member.role,\n\t\t\t\t\t\t\t\tstatus: 'pending' as LifecycleStatus,\n\t\t\t\t\t\t\t\tphase: null,\n\t\t\t\t\t\t\t\tlastError: null,\n\t\t\t\t\t\t\t\tlogTail: { lines: [], level: 'info' as const, truncated: false },\n\t\t\t\t\t\t\t\tendpoints: [],\n\t\t\t\t\t\t\t\tselectiveRestartHighlight: false,\n\t\t\t\t\t\t\t\tsection: node.member.section,\n\t\t\t\t\t\t\t\tendpointSection: node.member.endpointSection ?? node.member.section,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t}));\n\t\t}\n\n\t\t// Extract `RuntimeRoot` from the plugin context — needed to\n\t\t// build the `AcquireContext` handed to dynamic capability\n\t\t// factories. Fallback to '' for bare smoke tests that don't\n\t\t// wire RuntimeRoot; emit a logWarning when that path fires so\n\t\t// production-style misconfigurations are visible (plugins\n\t\t// computing `${runtimeRoot}/foo` would otherwise silently\n\t\t// resolve to host-filesystem root).\n\t\tconst runtimeRootResolved = runtimeRootAccess.read(pluginContext, { root: '' });\n\t\tif (runtimeRootResolved.root === '') {\n\t\t\tyield* Effect.logWarning(\n\t\t\t\t'supervisor: RuntimeRoot missing from pluginContext; falling back to empty root. ' +\n\t\t\t\t\t'Production wiring must layer `layerRuntimeRoot(...)` into pluginContext.',\n\t\t\t);\n\t\t}\n\t\tconst runtimeRoot = runtimeRootResolved.root;\n\n\t\t// Resolve the CapabilitySinks registry for this stack. Two paths:\n\t\t//\n\t\t// (a) Plugin-author / orchestrator pre-built path: the caller\n\t\t// layered a `CapabilitySinksService` into `pluginContext`\n\t\t// (typically by composing `layerCapabilitySinksDefault(...)`\n\t\t// PLUS one or more custom-sink Layers). The supervisor\n\t\t// harvests through THAT instance, so custom sinks\n\t\t// registered by plugin authors actually fire.\n\t\t//\n\t\t// (b) Bare path: no service in context — the supervisor builds\n\t\t// the substrate default with the orchestrator sinks passed\n\t\t// in. `Layer.build` opens the layer's resources on the\n\t\t// SURROUNDING scope (the supervisor's), so the sinks +\n\t\t// formatter registry live for the supervisor's lifetime\n\t\t// and reap on its scope close.\n\t\tconst sinksService = yield* sinksAccess.readEffect(\n\t\t\tpluginRuntimeContext,\n\t\t\tEffect.gen(function* () {\n\t\t\t\treturn Context.get(\n\t\t\t\t\tyield* Layer.build(layerCapabilitySinksDefault(sinks)),\n\t\t\t\t\tCapabilitySinksService,\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\n\t\tconst enableCommandLoop = options.commandLoop !== false;\n\t\tif (enableCommandLoop) {\n\t\t\tyield* Effect.forkScoped(traced(installSignalHandler(commands)));\n\t\t\tyield* Effect.forkScoped(\n\t\t\t\ttraced(\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\twhile (true) {\n\t\t\t\t\t\t\tconst command = yield* Queue.take(commands);\n\t\t\t\t\t\t\tyield* Queue.offer(queuedCommands, { kind: 'fire-and-forget', command });\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\tconst supervisorState: SupervisorState = {\n\t\t\tgraph,\n\t\t\tregistry,\n\t\t\tref: state,\n\t\t\thub,\n\t\t\tqueuedCommands,\n\t\t\tstackRestartTask,\n\t\t\tstackRestartSeq,\n\t\t\tsnapshotCaptureTask,\n\t\t\tsnapshotCaptureSeq,\n\t\t\tshutdownLatch,\n\t\t\tshutdownComplete,\n\t\t\tpluginContext: pluginRuntimeContext,\n\t\t\tsinks: sinksService,\n\t\t\tlogger,\n\t\t\tidentity,\n\t\t\truntimeRoot,\n\t\t\tcommandHandler,\n\t\t\tpostAcquireHook,\n\t\t};\n\n\t\tconst runInitialAcquire = Effect.gen(function* () {\n\t\t\tconst alreadyStarted = yield* Ref.modify(initialAcquireStarted, (started) => [started, true]);\n\t\t\tif (alreadyStarted) return;\n\t\t\tif (yield* Ref.get(shutdownLatch)) return;\n\t\t\tyield* acquireFullGraph(\n\t\t\t\tgraph,\n\t\t\t\tregistry,\n\t\t\t\tstate,\n\t\t\t\thub,\n\t\t\t\tpluginRuntimeContext,\n\t\t\t\tsinksService,\n\t\t\t\tlogger,\n\t\t\t\tidentity,\n\t\t\t\truntimeRoot,\n\t\t\t);\n\t\t\tif (yield* Ref.get(shutdownLatch)) return;\n\t\t\tconst initialReady = yield* allReadyOrTerminal(graph, registry);\n\t\t\tif (initialReady) {\n\t\t\t\tyield* runPostAcquireHook(supervisorState);\n\t\t\t\tif (!(yield* Ref.get(shutdownLatch))) {\n\t\t\t\t\tyield* setCyclePhase(state, 'running');\n\t\t\t\t}\n\t\t\t} else if (!(yield* Ref.get(shutdownLatch))) {\n\t\t\t\tyield* setCyclePhase(state, 'running');\n\t\t\t}\n\t\t}).pipe(Effect.withSpan('lifecycle.supervisor.initialAcquire'), traced);\n\n\t\t// Build the watch index up front; the supervisor exposes\n\t\t// `notifyWatchFire` so the L0 thick watcher can call into it.\n\t\tconst watchIndex = buildWatchIndex(graph.nodes);\n\n\t\tconst notifyWatchFire = (path: string): Effect.Effect<void> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst matched = new Set<PluginKey>();\n\t\t\t\tfor (const entry of watchIndex) {\n\t\t\t\t\tfor (const pat of entry.paths) {\n\t\t\t\t\t\tif (exactPrefixMatch(pat, path)) {\n\t\t\t\t\t\t\tmatched.add(entry.pluginKey);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matched.size === 0) return;\n\t\t\t\t// One `selective-restart.requested` per matched plugin, in\n\t\t\t\t// match order. (Previously the head was offered separately\n\t\t\t\t// from the tail — identical behaviour, one fewer branch.)\n\t\t\t\tfor (const key of matched) {\n\t\t\t\t\tyield* Queue.offer(commands, {\n\t\t\t\t\t\ttag: 'selective-restart.requested',\n\t\t\t\t\t\tpluginKey: key,\n\t\t\t\t\t} satisfies EngineCommand);\n\t\t\t\t}\n\t\t\t}).pipe(Effect.withSpan('lifecycle.supervisor.notifyWatchFire'));\n\n\t\t// Fork the command loop.\n\t\tif (enableCommandLoop) {\n\t\t\tyield* Effect.forkScoped(traced(commandLoop(supervisorState)));\n\t\t}\n\n\t\t// Tear-down finalizer: closes every plugin scope in reverse-dep\n\t\t// order. The supervisor scope itself closes when the surrounding\n\t\t// caller closes — `Scope.close` cascades to plugin scopes.\n\t\tyield* Effect.addFinalizer(() =>\n\t\t\ttraced(\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst plan = planFullDrain(graph);\n\t\t\t\t\tyield* teardownKeys(graph, registry, plan.teardownOrder).pipe(\n\t\t\t\t\t\tEffect.catch(() => Effect.void),\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\n\t\tconst awaitShutdown: Effect.Effect<void> = Deferred.await(shutdownComplete).pipe(\n\t\t\tEffect.withSpan('lifecycle.supervisor.awaitShutdown'),\n\t\t\ttraced,\n\t\t);\n\n\t\tconst runCommand = (command: EngineCommand): Effect.Effect<void, unknown> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst completion = yield* Deferred.make<Exit.Exit<void, unknown>>();\n\t\t\t\tyield* Queue.offer(queuedCommands, {\n\t\t\t\t\tkind: 'submitted',\n\t\t\t\t\tsubmission: { command, completion },\n\t\t\t\t});\n\t\t\t\tconst exit = yield* Deferred.await(completion);\n\t\t\t\tif (Exit.isFailure(exit)) {\n\t\t\t\t\treturn yield* Effect.failCause(exit.cause);\n\t\t\t\t}\n\t\t\t}).pipe(Effect.withSpan('lifecycle.supervisor.runCommand'), traced);\n\n\t\tconst handle = {\n\t\t\tidentity,\n\t\t\tgraph,\n\t\t\tregistry,\n\t\t\tevents: hub,\n\t\t\tcommands,\n\t\t\trunCommand,\n\t\t\tstate,\n\t\t\twatchIndex,\n\t\t\tnotifyWatchFire,\n\t\t\tawaitShutdown,\n\t\t} satisfies SupervisorHandle;\n\t\treturn { handle, runInitialAcquire } satisfies SupervisorStartup;\n\t}).pipe(\n\t\twithStackSpan('lifecycle.supervisor.startSupervisor', {\n\t\t\tapp: identity.app,\n\t\t\tstack: identity.stack,\n\t\t\tnetwork: identity.chain,\n\t\t}),\n\t);\n\n/**\n * Boot a supervisor for `stack` and wait for the initial acquire to\n * finish before returning the handle. Existing callers that only need\n * a ready-or-failed handle keep this simpler entry point; live surfaces\n * that need startup display use `startSupervisor`.\n */\nexport const supervise = (\n\tstack: SupervisedStack,\n\tidentity: Identity,\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tpluginContext: Context.Context<never> = Context.empty(),\n\tsinks: OrchestratorSinks = [],\n\tcommandHandler?: SupervisorCommandHandler,\n\tpostAcquireHook?: SupervisorPostAcquireHook,\n): Effect.Effect<SupervisorHandle, SupervisorError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst startup = yield* startSupervisor(\n\t\t\tstack,\n\t\t\tidentity,\n\t\t\tstate,\n\t\t\tpluginContext,\n\t\t\tsinks,\n\t\t\tcommandHandler,\n\t\t\tpostAcquireHook,\n\t\t\t{ commandLoop: true },\n\t\t);\n\t\tyield* startup.runInitialAcquire;\n\t\treturn startup.handle;\n\t}).pipe(\n\t\twithStackSpan('lifecycle.supervisor.supervise', {\n\t\t\tapp: identity.app,\n\t\t\tstack: identity.stack,\n\t\t\tnetwork: identity.chain,\n\t\t}),\n\t);\n\n/**\n * Block until the supervisor's shutdown latch fires OR the surrounding\n * scope is interrupted (signal-driven exit). Wraps `awaitShutdown` for\n * the common \"boot then wait\" shape.\n *\n * Returns the final supervisor state so callers (CLI, programmable\n * API) can inspect the projection after shutdown.\n */\nexport const runToShutdown = (\n\thandle: SupervisorHandle,\n): Effect.Effect<SubscribableState, never, never> =>\n\tEffect.gen(function* () {\n\t\tyield* handle.awaitShutdown;\n\t\treturn yield* SubscriptionRef.get(handle.state);\n\t}).pipe(Effect.withSpan('lifecycle.supervisor.runToShutdown'));\n"],"mappings":"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"}
1
+ {"version":3,"file":"start-supervisor.mjs","names":["Logger"],"sources":["../../../../src/substrate/runtime/supervisor/start-supervisor.ts"],"sourcesContent":["// Top-level supervisor entry — composes every per-concern module.\n//\n// Responsibilities (in order):\n// 1. Seed projection identity + booting slice so early-mounted\n// renderers see a complete baseline.\n// 2. Resolve the dep graph + boot the registry.\n// 3. Build the substrate-wiring bag: logger overlay, runtime root, and\n// the closed contribution dispatcher.\n// 4. Compose the `SupervisorState` record (one bag passed to every\n// module).\n// 5. Build `runInitialAcquire` — the deferred initial-acquire body.\n// 6. Build the watch index + `notifyWatchFire`.\n// 7. Fork the command loop + signal handler.\n// 8. Install the scope-close finalizer (reverse-dep teardown).\n// 9. Return the handle.\n\nimport {\n\tContext,\n\tDeferred,\n\tEffect,\n\tExit,\n\ttype Fiber,\n\tQueue,\n\tRef,\n\tScope,\n\tSubscriptionRef,\n} from 'effect';\n\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineCommand, EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { AccountProjection, SubscribableState } from '../../projection.ts';\nimport {\n\tnoopContributionDispatcher,\n\ttype ContributionDispatcher,\n} from './contribution-dispatcher.ts';\nimport {\n\tLogger,\n\tLogStore,\n\tmakeLogStore,\n\ttype LoggerShape,\n\ttype LogStoreConfig,\n} from '../observability/index.ts';\nimport { ControlPlaneService } from '../control-plane/service.ts';\nimport { controlPlaneDomainFromContext } from '../control-plane/domain.ts';\nimport { RuntimeRoot } from '../paths.ts';\nimport { declareAccount, setIdentity } from '../projection/update.ts';\nimport {\n\tbuildWatchIndex,\n\texactPrefixMatch,\n\tinstallSignalHandler,\n\tresolveGraph,\n\ttype PluginRegistry,\n\ttype ResolvedGraph,\n\ttype UnknownDependency,\n\ttype WatchEntry,\n} from '../lifecycle/index.ts';\nimport { acquireFullGraph, buildRegistry } from './acquire-node.ts';\nimport { commandLoop } from './command-loop.ts';\nimport { runPostAcquireHook } from './background-tasks.ts';\nimport {\n\tSupervisorBootError,\n\ttype SupervisorError,\n\ttype SupervisorPostAcquireFailed,\n} from './errors.ts';\nimport {\n\tallReadyOrTerminal,\n\ttype BackgroundTaskSlot,\n\ttype QueuedCommand,\n\ttype SupervisorCommandHandler,\n\ttype SupervisorPostAcquireHook,\n\ttype SupervisorState,\n} from './state.ts';\nimport type { SupervisedStack } from './types.ts';\nimport { teardownKeys } from './teardown.ts';\nimport { plan } from '../reconcile/graph.ts';\nimport {\n\tbuildTransitionEmitter,\n\tnoopLogger,\n\tOptionalService,\n\tsetCyclePhase,\n\twithEventPublishingLogger,\n} from './wiring.ts';\n\nconst loggerAccess = OptionalService(Logger);\nconst runtimeRootAccess = OptionalService(RuntimeRoot);\n\nexport interface SupervisorHandle {\n\treadonly identity: Identity;\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly events: Queue.Dequeue<EngineEvent>;\n\treadonly commands: Queue.Enqueue<EngineCommand>;\n\treadonly runCommand: (command: EngineCommand) => Effect.Effect<void, unknown>;\n\treadonly state: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly watchIndex: ReadonlyArray<WatchEntry>;\n\t/** Fire a watch event for the given path. Substrate-level glue:\n\t * the thick L0 watcher calls this; tests call it directly. */\n\treadonly notifyWatchFire: (path: string) => Effect.Effect<void>;\n\t/** Block until the supervisor's command loop sets the shutdown\n\t * latch. The outer runtime then closes the supervisor scope, which\n\t * tears down every plugin in reverse-dep order. */\n\treadonly awaitShutdown: Effect.Effect<void>;\n}\n\nexport interface SupervisorStartup {\n\treadonly handle: SupervisorHandle;\n\treadonly runInitialAcquire: Effect.Effect<void, SupervisorPostAcquireFailed, never>;\n}\n\nexport interface SupervisorStartupOptions {\n\treadonly commandLoop?: boolean;\n\treadonly devstackVersion?: string;\n\t/** Per-service log-store tuning. Absent fields fall back to the\n\t * `DEVSTACK_DASHBOARD_LOG_*` env vars, then the module defaults\n\t * (2000 records/service, 256 services). Threaded into the\n\t * process-scoped `makeLogStore` below. */\n\treadonly logStore?: LogStoreConfig;\n}\n\nconst pendingAccountProjection = (\n\trowKey: PluginKey,\n\tresourceId: string,\n\tupdatedAt: number,\n): AccountProjection | null => {\n\tif (!resourceId.startsWith('account/')) return null;\n\tconst name = resourceId.slice('account/'.length);\n\tif (name.length === 0) return null;\n\treturn {\n\t\tkey: resourceId as `account/${string}`,\n\t\trowKey,\n\t\tname,\n\t\taddress: null,\n\t\tscheme: null,\n\t\tsource: null,\n\t\tfunding: { status: 'pending', balanceMist: null, requestedMist: null, entries: [] },\n\t\twalletVisible: false,\n\t\tupdatedAt,\n\t};\n};\n\n/**\n * Prepare a supervisor for `stack` without running the initial acquire.\n * The returned `SupervisorHandle` is Scope-managed; the supervisor's\n * lifecycle is the surrounding Scope's lifecycle. Signal handlers,\n * the command loop, and every plugin's scope are children of the\n * supervisor scope. Callers that mount renderers can subscribe to the\n * returned state before invoking `runInitialAcquire`.\n *\n * `pluginContext` carries the substrate-context services available to\n * each plugin's `acquire` body (`IdentityContext`,\n * `ContainerRuntimeService`, `RuntimeRoot`, `StackPathsService`, etc.).\n * Plugins declare what they need by yielding the corresponding\n * `Context.Service` tag from within `Effect.gen`; the supervisor\n * provides this context before running the acquire effect so the\n * plugin's R-channel narrows to `Scope.Scope` (then to `never` after\n * the per-plugin Scope is provided).\n *\n * Contribution dispatch: the supervisor replays each plugin's\n * buffered ctx contributions through the closed `dispatcher`\n * (snapshotable/routable/codegenable/projection/strategy-contributor).\n * Production callers pass `buildProductionContributionDispatcher(...)`;\n * bare smoke tests omit it and get the no-op dispatcher.\n */\nexport const startSupervisor = (\n\tstack: SupervisedStack,\n\tidentity: Identity,\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tpluginContext: Context.Context<never> = Context.empty(),\n\tdispatcher: ContributionDispatcher = noopContributionDispatcher,\n\tcommandHandler?: SupervisorCommandHandler,\n\tpostAcquireHook?: SupervisorPostAcquireHook,\n\toptions: SupervisorStartupOptions = {},\n): Effect.Effect<SupervisorStartup, SupervisorBootError | UnknownDependency, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\t// Optional Logger service — pull from the plugin context if the\n\t\t// caller layered it in (CLI / e2e do). Bare smoke tests get the\n\t\t// no-op fallback so they remain log-free.\n\t\tconst baseLogger: LoggerShape = loggerAccess.read(pluginContext, noopLogger);\n\n\t\tyield* baseLogger.log('supervisor', null, {\n\t\t\tlevel: 'debug',\n\t\t\tmessage: 'supervisor boot start',\n\t\t\tfields: {\n\t\t\t\tapp: identity.app,\n\t\t\t\tstack: identity.stack,\n\t\t\t\tnetwork: identity.network,\n\t\t\t\tmemberCount: stack.members.length,\n\t\t\t},\n\t\t});\n\n\t\t// Seed the projection's identity and booting slices before\n\t\t// acquire starts so renderers mounting early have a complete\n\t\t// baseline.\n\t\tyield* SubscriptionRef.update(\n\t\t\tstate,\n\t\t\t(s) =>\n\t\t\t\t({\n\t\t\t\t\t...setIdentity(s, {\n\t\t\t\t\t\tapp: identity.app,\n\t\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\t\tnetwork: identity.network,\n\t\t\t\t\t}),\n\t\t\t\t\tcycle: {\n\t\t\t\t\t\t...s.cycle,\n\t\t\t\t\t\tstartedAt: s.cycle.startedAt === 0 ? Date.now() : s.cycle.startedAt,\n\t\t\t\t\t\tphase: 'booting',\n\t\t\t\t\t},\n\t\t\t\t}) satisfies SubscribableState,\n\t\t);\n\n\t\t// Resolve the dep graph.\n\t\tconst graph = yield* resolveGraph(stack.members).pipe(\n\t\t\tEffect.mapError((cause) => new SupervisorBootError({ cause })),\n\t\t);\n\n\t\t// Event hub + command channel.\n\t\tconst hub = yield* Queue.unbounded<EngineEvent>();\n\t\tconst commands = yield* Queue.unbounded<EngineCommand>();\n\t\tconst queuedCommands = yield* Queue.unbounded<QueuedCommand>();\n\t\t// Background-task fiber slot: the live stack-restart fiber (or `null`\n\t\t// when idle). The fiber IS the running state — see `BackgroundTaskSlot`.\n\t\t// Forked into `supervisorScope` (below) via `Effect.forkIn`, interrupted\n\t\t// via `Fiber.interrupt`. (Snapshot capture/restore run inline in the\n\t\t// command loop now — the bounce — so they have no forked slot.)\n\t\tconst stackRestartTask: BackgroundTaskSlot = yield* Ref.make<Fiber.Fiber<void, never> | null>(\n\t\t\tnull,\n\t\t);\n\t\tconst shutdownLatch = yield* Ref.make(false);\n\t\tconst shutdownComplete = yield* Deferred.make<void>();\n\t\tconst initialAcquireStarted = yield* Ref.make(false);\n\n\t\t// Observability store (process-scoped, like `state`/`hub`): a\n\t\t// cross-service queryable log ring fed off the SAME logger path that\n\t\t// feeds the projection's per-row tail. Survives `stack.restart`\n\t\t// because it lives in this closure (only `cycle.id` bumps on restart).\n\t\t// The dashboard reads it via the control-plane `domain`.\n\t\tconst logStore = yield* makeLogStore(options.logStore ?? {});\n\t\tconst logger = withEventPublishingLogger(baseLogger, state, hub, logStore);\n\n\t\t// The control-plane command verbs, both offering onto the SAME\n\t\t// `queuedCommands` seam the single command-loop consumer drains —\n\t\t// distinguished only by the QueuedCommand kind:\n\t\t// - `publishCommand` — fire-and-forget; offers a `fire-and-forget`\n\t\t// QueuedCommand and returns immediately.\n\t\t// - `submitCommand` — offers a `submitted` QueuedCommand carrying a\n\t\t// completion deferred, then AWAITs the real exit. So a destructive\n\t\t// command like `snapshot.restore` (which removes live managed\n\t\t// containers then re-acquires) runs in-band with the loop, never\n\t\t// racing the live supervisor out-of-band. Re-fails with the\n\t\t// handler's cause.\n\t\t// (Both feed `queuedCommands`, NOT the public `commands` queue + bridge —\n\t\t// that queue stays for the signal handler and cross-process callers.)\n\t\tconst publishCommand = (command: EngineCommand): Effect.Effect<void> =>\n\t\t\tEffect.asVoid(Queue.offer(queuedCommands, { kind: 'fire-and-forget', command }));\n\t\tconst submitCommand = (command: EngineCommand): Effect.Effect<void, unknown> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst completion = yield* Deferred.make<Exit.Exit<void, unknown>>();\n\t\t\t\tyield* Queue.offer(queuedCommands, {\n\t\t\t\t\tkind: 'submitted',\n\t\t\t\t\tsubmission: { command, completion },\n\t\t\t\t});\n\t\t\t\tconst exit = yield* Deferred.await(completion);\n\t\t\t\tif (Exit.isFailure(exit)) {\n\t\t\t\t\treturn yield* Effect.failCause(exit.cause);\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Per-plugin scopes parent off the supervisor scope.\n\t\tconst supervisorScope = yield* Effect.scope;\n\n\t\tconst emit = buildTransitionEmitter(state, hub);\n\t\tconst registry = yield* buildRegistry(graph, supervisorScope, emit);\n\n\t\t// Build the control-plane `domain` accessor surface from the data\n\t\t// the supervisor holds at wiring time: the resolved registry +\n\t\t// graph, plus the (optional) snapshot orchestrator / container\n\t\t// runtime / filesystem the caller may have layered into\n\t\t// `pluginContext`. The projection stays CLOSED — `domain` reads\n\t\t// resolved plugin VALUES via the name-blind registry seam, never\n\t\t// the projection. The registry is process-scoped, so the closure\n\t\t// stays valid across `stack.restart` (only `cycle.id` bumps).\n\t\tconst controlPlaneDomain = controlPlaneDomainFromContext({\n\t\t\tpluginContext,\n\t\t\tgraph,\n\t\t\tstackOptions: stack.options,\n\t\t\tdevstackVersion: options.devstackVersion ?? null,\n\t\t\tregistry,\n\t\t\tlogStore,\n\t\t});\n\n\t\tconst pluginRuntimeContext = pluginContext.pipe(\n\t\t\tContext.add(Logger, Logger.of(logger)),\n\t\t\t// Observability store. Exposed so the control-plane `domain` can\n\t\t\t// query the cross-service log ring.\n\t\t\tContext.add(LogStore, LogStore.of(logStore)),\n\t\t\t// Expose the control plane (live projection + fire-and-forget\n\t\t\t// command dispatch + the plugin-domain accessor surface) to\n\t\t\t// in-process surfaces like the dashboard plugin. Reads the same\n\t\t\t// `state` ref and `commands` queue the supervisor itself drives.\n\t\t\tContext.add(\n\t\t\t\tControlPlaneService,\n\t\t\t\tControlPlaneService.of({\n\t\t\t\t\tstate,\n\t\t\t\t\tpublishCommand,\n\t\t\t\t\tsubmitCommand,\n\t\t\t\t\tdomain: controlPlaneDomain,\n\t\t\t\t}),\n\t\t\t),\n\t\t) as Context.Context<never>;\n\n\t\t// Declare a row for every plugin so the projection's\n\t\t// `lifecycle.statusChanged` events have a row to attach to.\n\t\t// `section` is plugin-declared at `definePlugin({ section })`\n\t\t// time; we stamp it onto the row here so the TUI groups rows\n\t\t// without pattern-matching on plugin-name substrings.\n\t\tfor (const [key, node] of graph.nodes) {\n\t\t\tconst declaredAccount = pendingAccountProjection(key, node.member.id, Date.now());\n\t\t\tyield* SubscriptionRef.update(state, (s) => ({\n\t\t\t\t...(declaredAccount === null ? s : declareAccount(s, declaredAccount)),\n\t\t\t\trows: s.rows.some((r) => r.key === key)\n\t\t\t\t\t? s.rows\n\t\t\t\t\t: [\n\t\t\t\t\t\t\t...s.rows,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\trole: node.member.role,\n\t\t\t\t\t\t\t\tstatus: 'pending' as LifecycleStatus,\n\t\t\t\t\t\t\t\tphase: null,\n\t\t\t\t\t\t\t\tlastError: null,\n\t\t\t\t\t\t\t\tlogTail: { lines: [], level: 'info' as const, truncated: false },\n\t\t\t\t\t\t\t\tendpoints: [],\n\t\t\t\t\t\t\t\tselectiveRestartHighlight: false,\n\t\t\t\t\t\t\t\tsection: node.member.section,\n\t\t\t\t\t\t\t\tendpointSection: node.member.endpointSection ?? node.member.section,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t}));\n\t\t}\n\n\t\t// Extract `RuntimeRoot` from the plugin context — recorded on\n\t\t// `SupervisorState.runtimeRoot` and read by the post-acquire hook\n\t\t// + background tasks (NOT threaded into the acquire path, which is\n\t\t// name-blind). Fallback to '' for bare smoke tests that don't wire\n\t\t// RuntimeRoot; emit a logWarning when that path fires so\n\t\t// production-style misconfigurations are visible (plugins computing\n\t\t// `${runtimeRoot}/foo` would otherwise silently resolve to\n\t\t// host-filesystem root).\n\t\tconst runtimeRootResolved = runtimeRootAccess.read(pluginContext, { root: '' });\n\t\tif (runtimeRootResolved.root === '') {\n\t\t\tyield* Effect.logWarning(\n\t\t\t\t'supervisor: RuntimeRoot missing from pluginContext; falling back to empty root. ' +\n\t\t\t\t\t'Production wiring must layer `layerRuntimeRoot(...)` into pluginContext.',\n\t\t\t);\n\t\t}\n\t\tconst runtimeRoot = runtimeRootResolved.root;\n\n\t\tconst enableCommandLoop = options.commandLoop !== false;\n\t\tif (enableCommandLoop) {\n\t\t\tyield* Effect.forkScoped(installSignalHandler(commands));\n\t\t\tyield* Effect.forkScoped(\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\twhile (true) {\n\t\t\t\t\t\tconst command = yield* Queue.take(commands);\n\t\t\t\t\t\tyield* Queue.offer(queuedCommands, { kind: 'fire-and-forget', command });\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst supervisorState: SupervisorState = {\n\t\t\tgraph,\n\t\t\tregistry,\n\t\t\tref: state,\n\t\t\thub,\n\t\t\tqueuedCommands,\n\t\t\tsupervisorScope,\n\t\t\tstackRestartTask,\n\t\t\tshutdownLatch,\n\t\t\tshutdownComplete,\n\t\t\tpluginContext: pluginRuntimeContext,\n\t\t\tdispatcher,\n\t\t\tlogger,\n\t\t\tidentity,\n\t\t\truntimeRoot,\n\t\t\tcommandHandler,\n\t\t\tpostAcquireHook,\n\t\t};\n\n\t\tconst runInitialAcquire = Effect.gen(function* () {\n\t\t\tconst alreadyStarted = yield* Ref.modify(initialAcquireStarted, (started) => [started, true]);\n\t\t\tif (alreadyStarted) return;\n\t\t\tif (yield* Ref.get(shutdownLatch)) return;\n\t\t\tyield* acquireFullGraph(\n\t\t\t\tgraph,\n\t\t\t\tregistry,\n\t\t\t\tstate,\n\t\t\t\thub,\n\t\t\t\tpluginRuntimeContext,\n\t\t\t\tdispatcher,\n\t\t\t\tlogger,\n\t\t\t\tidentity,\n\t\t\t\tsupervisorScope,\n\t\t\t);\n\t\t\tif (yield* Ref.get(shutdownLatch)) return;\n\t\t\tconst initialReady = yield* allReadyOrTerminal(graph, registry);\n\t\t\tif (initialReady) {\n\t\t\t\tyield* runPostAcquireHook(supervisorState);\n\t\t\t\tif (!(yield* Ref.get(shutdownLatch))) {\n\t\t\t\t\tyield* setCyclePhase(state, 'running');\n\t\t\t\t}\n\t\t\t} else if (!(yield* Ref.get(shutdownLatch))) {\n\t\t\t\tyield* setCyclePhase(state, 'running');\n\t\t\t}\n\t\t});\n\n\t\t// Build the watch index up front; the supervisor exposes\n\t\t// `notifyWatchFire` so the L0 thick watcher can call into it.\n\t\tconst watchIndex = buildWatchIndex(graph.nodes);\n\n\t\tconst notifyWatchFire = (path: string): Effect.Effect<void> =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst matched = new Set<PluginKey>();\n\t\t\t\tfor (const entry of watchIndex) {\n\t\t\t\t\tfor (const pat of entry.paths) {\n\t\t\t\t\t\tif (exactPrefixMatch(pat, path)) {\n\t\t\t\t\t\t\tmatched.add(entry.pluginKey);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matched.size === 0) return;\n\t\t\t\t// One `selective-restart.requested` per matched plugin, in\n\t\t\t\t// match order. (Previously the head was offered separately\n\t\t\t\t// from the tail — identical behaviour, one fewer branch.)\n\t\t\t\tfor (const key of matched) {\n\t\t\t\t\tyield* Queue.offer(commands, {\n\t\t\t\t\t\ttag: 'selective-restart.requested',\n\t\t\t\t\t\tpluginKey: key,\n\t\t\t\t\t} satisfies EngineCommand);\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Fork the command loop.\n\t\tif (enableCommandLoop) {\n\t\t\tyield* Effect.forkScoped(commandLoop(supervisorState));\n\t\t}\n\n\t\t// Tear-down finalizer: closes every plugin scope in reverse-dep\n\t\t// order. The supervisor scope itself closes when the surrounding\n\t\t// caller closes — `Scope.close` cascades to plugin scopes.\n\t\tyield* Effect.addFinalizer(() =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst fullDrain = plan(graph, {\n\t\t\t\t\tkind: 'graph-keys',\n\t\t\t\t\tkeys: [...graph.nodes.keys()],\n\t\t\t\t});\n\t\t\t\tyield* teardownKeys(graph, registry, fullDrain.teardownOrder).pipe(\n\t\t\t\t\tEffect.catch(() => Effect.void),\n\t\t\t\t);\n\t\t\t}),\n\t\t);\n\n\t\tconst awaitShutdown: Effect.Effect<void> = Deferred.await(shutdownComplete);\n\n\t\t// The programmable `runCommand` surface is exactly the submit-and-await\n\t\t// path the control plane uses; share the one implementation.\n\t\tconst runCommand = submitCommand;\n\n\t\tconst handle = {\n\t\t\tidentity,\n\t\t\tgraph,\n\t\t\tregistry,\n\t\t\tevents: hub,\n\t\t\tcommands,\n\t\t\trunCommand,\n\t\t\tstate,\n\t\t\twatchIndex,\n\t\t\tnotifyWatchFire,\n\t\t\tawaitShutdown,\n\t\t} satisfies SupervisorHandle;\n\t\treturn { handle, runInitialAcquire } satisfies SupervisorStartup;\n\t});\n\n/**\n * Boot a supervisor for `stack` and wait for the initial acquire to\n * finish before returning the handle. Existing callers that only need\n * a ready-or-failed handle keep this simpler entry point; live surfaces\n * that need startup display use `startSupervisor`.\n */\nexport const supervise = (\n\tstack: SupervisedStack,\n\tidentity: Identity,\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tpluginContext: Context.Context<never> = Context.empty(),\n\tdispatcher: ContributionDispatcher = noopContributionDispatcher,\n\tcommandHandler?: SupervisorCommandHandler,\n\tpostAcquireHook?: SupervisorPostAcquireHook,\n): Effect.Effect<SupervisorHandle, SupervisorError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst startup = yield* startSupervisor(\n\t\t\tstack,\n\t\t\tidentity,\n\t\t\tstate,\n\t\t\tpluginContext,\n\t\t\tdispatcher,\n\t\t\tcommandHandler,\n\t\t\tpostAcquireHook,\n\t\t\t{ commandLoop: true },\n\t\t);\n\t\tyield* startup.runInitialAcquire;\n\t\treturn startup.handle;\n\t});\n\n/**\n * Block until the supervisor's shutdown latch fires OR the surrounding\n * scope is interrupted (signal-driven exit). Wraps `awaitShutdown` for\n * the common \"boot then wait\" shape.\n *\n * Returns the final supervisor state so callers (CLI, programmable\n * API) can inspect the projection after shutdown.\n */\nexport const runToShutdown = (\n\thandle: SupervisorHandle,\n): Effect.Effect<SubscribableState, never, never> =>\n\tEffect.gen(function* () {\n\t\tyield* handle.awaitShutdown;\n\t\treturn yield* SubscriptionRef.get(handle.state);\n\t});\n"],"mappings":"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"}
@@ -1 +1 @@
1
- import { Context, Deferred, Effect, Exit, Fiber, Queue, Ref, SubscriptionRef } from "effect";
1
+ import { Context, Deferred, Effect, Exit, Fiber, Queue, Ref, Scope, SubscriptionRef } from "effect";
@@ -1,4 +1,4 @@
1
- import "../capability-sinks/index.mjs";
1
+ import "./contribution-dispatcher.mjs";
2
2
  import { isReadyOrTerminal } from "../lifecycle/state-machine.mjs";
3
3
  import "../lifecycle/index.mjs";
4
4
  import { Effect } from "effect";
@@ -1 +1 @@
1
- {"version":3,"file":"state.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/state.ts"],"sourcesContent":["// Supervisor shared-state record.\n//\n// `startSupervisor`'s `Effect.gen` body closes over ~20 locals. Rather\n// than thread each one through every helper individually, we group\n// them into a typed bag here so the per-concern modules (command-loop,\n// background-tasks, shutdown) take ONE argument.\n//\n// The shape originated as `CommandLoopDeps`; the split renames it and\n// extends with the post-acquire context (graph, registry, identity,\n// runtimeRoot) so the same record satisfies every module's needs.\n\nimport {\n\tEffect,\n\ttype Context,\n\ttype Deferred,\n\ttype Exit,\n\ttype Fiber,\n\ttype Queue,\n\ttype Ref,\n\ttype SubscriptionRef,\n} from 'effect';\n\nimport type { EngineCommand, EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { type CapabilitySinksShape } from '../capability-sinks/index.ts';\nimport { isReadyOrTerminal } from '../lifecycle/index.ts';\nimport type { LoggerShape } from '../observability/index.ts';\nimport type { PluginRegistry, ResolvedGraph } from '../lifecycle/index.ts';\n\nexport type StackRestartTaskState =\n\t| { readonly tag: 'idle' }\n\t| { readonly tag: 'starting'; readonly token: number }\n\t| {\n\t\t\treadonly tag: 'running';\n\t\t\treadonly token: number;\n\t\t\treadonly fiber: Fiber.Fiber<void, never>;\n\t };\n\nexport type SnapshotCaptureTaskState =\n\t| { readonly tag: 'idle' }\n\t| { readonly tag: 'starting'; readonly token: number; readonly snapshotId: string | null }\n\t| {\n\t\t\treadonly tag: 'running';\n\t\t\treadonly token: number;\n\t\t\treadonly snapshotId: string | null;\n\t\t\treadonly fiber: Fiber.Fiber<void, never>;\n\t };\n\nexport interface SupervisorCommandHandlerContext {\n\treadonly publish: (event: EngineEvent) => Effect.Effect<void, never, never>;\n}\n\nexport type SupervisorCommandHandler = (\n\tcmd: EngineCommand,\n\tctx: SupervisorCommandHandlerContext,\n) => Effect.Effect<ReadonlyArray<EngineEvent>, unknown, never>;\n\nexport interface SupervisorPostAcquireContext {\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly identity: Identity;\n\treadonly runtimeRoot: string;\n}\n\nexport type SupervisorPostAcquireHook = (\n\tctx: SupervisorPostAcquireContext,\n) => Effect.Effect<ReadonlyArray<EngineEvent>, unknown, never>;\n\nexport interface CommandSubmission {\n\treadonly command: EngineCommand;\n\treadonly completion: Deferred.Deferred<Exit.Exit<void, unknown>>;\n}\n\nexport type QueuedCommand =\n\t| { readonly kind: 'fire-and-forget'; readonly command: EngineCommand }\n\t| { readonly kind: 'submitted'; readonly submission: CommandSubmission };\n\n/**\n * True when every node in `graph` has reached a `ready`-or-terminal\n * lifecycle status. Used by the command-loop to gate the post-acquire\n * hook after a (selective) restart and by the initial-acquire path to\n * decide whether to transition the cycle phase to `running`.\n *\n * Failed status reads collapse to `'failed'` so a transient registry\n * error doesn't block the readiness gate forever.\n */\nexport const allReadyOrTerminal = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n): Effect.Effect<boolean, never, never> =>\n\tEffect.gen(function* () {\n\t\tfor (const key of graph.nodes.keys()) {\n\t\t\tconst status = yield* registry\n\t\t\t\t.getStatus(key)\n\t\t\t\t.pipe(Effect.catch(() => Effect.succeed<LifecycleStatus>('failed')));\n\t\t\tif (!isReadyOrTerminal(status)) return false;\n\t\t}\n\t\treturn true;\n\t});\n\n/**\n * The shared-state record threaded through command-loop, background\n * tasks, and shutdown. Built once at the top of `startSupervisor`.\n */\nexport interface SupervisorState {\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly ref: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly hub: Queue.Enqueue<EngineEvent>;\n\treadonly queuedCommands: Queue.Dequeue<QueuedCommand>;\n\treadonly stackRestartTask: Ref.Ref<StackRestartTaskState>;\n\treadonly stackRestartSeq: Ref.Ref<number>;\n\treadonly snapshotCaptureTask: Ref.Ref<SnapshotCaptureTaskState>;\n\treadonly snapshotCaptureSeq: Ref.Ref<number>;\n\treadonly shutdownLatch: Ref.Ref<boolean>;\n\treadonly shutdownComplete: Deferred.Deferred<void>;\n\treadonly pluginContext: Context.Context<never>;\n\treadonly sinks: CapabilitySinksShape;\n\treadonly logger: LoggerShape;\n\treadonly identity: Identity;\n\treadonly runtimeRoot: string;\n\treadonly commandHandler?: SupervisorCommandHandler;\n\treadonly postAcquireHook?: SupervisorPostAcquireHook;\n}\n"],"mappings":";;;;;;;;;;;;;;AAwFA,MAAa,sBACZ,OACA,aAEA,OAAO,IAAI,aAAa;AACvB,MAAK,MAAM,OAAO,MAAM,MAAM,MAAM,CAInC,KAAI,CAAC,kBAAkB,OAHD,SACpB,UAAU,IAAI,CACd,KAAK,OAAO,YAAY,OAAO,QAAyB,SAAS,CAAC,CAAC,CACvC,CAAE,QAAO;AAExC,QAAO;EACN"}
1
+ {"version":3,"file":"state.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/state.ts"],"sourcesContent":["// Supervisor shared-state record.\n//\n// `startSupervisor`'s `Effect.gen` body closes over ~20 locals. Rather\n// than thread each one through every helper individually, we group\n// them into a typed bag here so the per-concern modules (command-loop,\n// background-tasks, shutdown) take ONE argument.\n//\n// The shape originated as `CommandLoopDeps`; the split renames it and\n// extends with the post-acquire context (graph, registry, identity,\n// runtimeRoot) so the same record satisfies every module's needs.\n\nimport {\n\tEffect,\n\ttype Context,\n\ttype Deferred,\n\ttype Exit,\n\ttype Fiber,\n\ttype Queue,\n\ttype Ref,\n\ttype Scope,\n\ttype SubscriptionRef,\n} from 'effect';\n\nimport type { EngineCommand, EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { type ContributionDispatcher } from './contribution-dispatcher.ts';\nimport { isReadyOrTerminal } from '../lifecycle/index.ts';\nimport type { LoggerShape } from '../observability/index.ts';\nimport type { PluginRegistry, ResolvedGraph } from '../lifecycle/index.ts';\n\n/**\n * A long-running background task forked into the supervisor-lifetime\n * scope (snapshot capture, stack restart). The slot holds the live\n * fiber while the task runs and `null` when idle. A second concurrent\n * trigger reads the slot: a non-null slot means one is already running\n * (skip-dedup); a shutdown/conflicting command reads-and-clears the\n * slot and `Fiber.interrupt`s it.\n *\n * The fiber IS the running state, `Effect.forkIn(supervisorScope)` gives\n * it the supervisor's lifetime (so it outlives the command-loop fiber\n * and does NOT wedge shutdown), and `Fiber.interrupt` is the\n * conflict-resolution primitive.\n */\nexport type BackgroundTaskSlot = Ref.Ref<Fiber.Fiber<void, never> | null>;\n\nexport interface SupervisorCommandHandlerContext {\n\treadonly publish: (event: EngineEvent) => Effect.Effect<void, never, never>;\n}\n\nexport type SupervisorCommandHandler = (\n\tcmd: EngineCommand,\n\tctx: SupervisorCommandHandlerContext,\n) => Effect.Effect<ReadonlyArray<EngineEvent>, unknown, never>;\n\nexport interface SupervisorPostAcquireContext {\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly identity: Identity;\n\treadonly runtimeRoot: string;\n}\n\nexport type SupervisorPostAcquireHook = (\n\tctx: SupervisorPostAcquireContext,\n) => Effect.Effect<ReadonlyArray<EngineEvent>, unknown, never>;\n\nexport interface CommandSubmission {\n\treadonly command: EngineCommand;\n\treadonly completion: Deferred.Deferred<Exit.Exit<void, unknown>>;\n}\n\nexport type QueuedCommand =\n\t| { readonly kind: 'fire-and-forget'; readonly command: EngineCommand }\n\t| { readonly kind: 'submitted'; readonly submission: CommandSubmission };\n\n/**\n * True when every node in `graph` has reached a `ready`-or-terminal\n * lifecycle status. Used by the command-loop to gate the post-acquire\n * hook after a (selective) restart and by the initial-acquire path to\n * decide whether to transition the cycle phase to `running`.\n *\n * Failed status reads collapse to `'failed'` so a transient registry\n * error doesn't block the readiness gate forever.\n */\nexport const allReadyOrTerminal = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n): Effect.Effect<boolean, never, never> =>\n\tEffect.gen(function* () {\n\t\tfor (const key of graph.nodes.keys()) {\n\t\t\tconst status = yield* registry\n\t\t\t\t.getStatus(key)\n\t\t\t\t.pipe(Effect.catch(() => Effect.succeed<LifecycleStatus>('failed')));\n\t\t\tif (!isReadyOrTerminal(status)) return false;\n\t\t}\n\t\treturn true;\n\t});\n\n/**\n * The shared-state record threaded through command-loop, background\n * tasks, and shutdown. Built once at the top of `startSupervisor`.\n */\nexport interface SupervisorState {\n\treadonly graph: ResolvedGraph;\n\treadonly registry: PluginRegistry;\n\treadonly ref: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly hub: Queue.Enqueue<EngineEvent>;\n\treadonly queuedCommands: Queue.Dequeue<QueuedCommand>;\n\t/** The supervisor-lifetime scope. Long-running background tasks\n\t * (snapshot capture, stack restart) are forked into THIS scope via\n\t * `Effect.forkIn` so they ride the supervisor's lifetime rather than\n\t * the command-loop fiber — a forked capture must not wedge shutdown. */\n\treadonly supervisorScope: Scope.Scope;\n\t/** Live stack-restart fiber (or `null` when idle). See {@link BackgroundTaskSlot}.\n\t * Snapshot capture/restore now run INLINE in the command loop (the bounce:\n\t * the handler stops+commits/loads + the loop converges), so there is no\n\t * forked capture fiber — only the stack-restart background task. */\n\treadonly stackRestartTask: BackgroundTaskSlot;\n\treadonly shutdownLatch: Ref.Ref<boolean>;\n\treadonly shutdownComplete: Deferred.Deferred<void>;\n\treadonly pluginContext: Context.Context<never>;\n\treadonly dispatcher: ContributionDispatcher;\n\treadonly logger: LoggerShape;\n\treadonly identity: Identity;\n\treadonly runtimeRoot: string;\n\treadonly commandHandler?: SupervisorCommandHandler;\n\treadonly postAcquireHook?: SupervisorPostAcquireHook;\n}\n"],"mappings":";;;;;;;;;;;;;;AAqFA,MAAa,sBACZ,OACA,aAEA,OAAO,IAAI,aAAa;CACvB,KAAK,MAAM,OAAO,MAAM,MAAM,KAAK,GAIlC,IAAI,CAAC,kBAAkB,OAHD,SACpB,UAAU,GAAG,CAAC,CACd,KAAK,OAAO,YAAY,OAAO,QAAyB,QAAQ,CAAC,CAAC,CACvC,GAAG,OAAO;CAExC,OAAO;AACR,CAAC"}
@@ -1,4 +1,4 @@
1
- import "../capability-sinks/index.mjs";
1
+ import "./contribution-dispatcher.mjs";
2
2
  import { planRestart } from "../lifecycle/selective-restart.mjs";
3
3
  import "../lifecycle/index.mjs";
4
4
  import { bestEffort, publish } from "./wiring.mjs";
@@ -25,32 +25,33 @@ const teardownKeys = (graph, registry, keys) => Effect.gen(function* () {
25
25
  discard: true
26
26
  });
27
27
  }
28
- }).pipe(Effect.withSpan("lifecycle.supervisor.teardownKeys"));
28
+ });
29
29
  const teardownNode = (registry, key) => Effect.gen(function* () {
30
30
  const entry = registry.entries.get(key);
31
31
  if (entry === void 0) return;
32
+ yield* registry.interruptAcquire(key).pipe(Effect.catch(() => Effect.void));
32
33
  const status = yield* registry.getStatus(key).pipe(Effect.catch(() => Effect.succeed("pending")));
33
34
  if (status === "ready") yield* bestEffort(registry.transition(key, "stopping"));
34
35
  yield* Scope.close(entry.scope, Exit.void).pipe(Effect.catch(() => Effect.void));
35
36
  if (status === "ready") yield* bestEffort(registry.transition(key, "stopped"));
36
- }).pipe(Effect.withSpan("lifecycle.supervisor.teardownNode"));
37
- const doSelectiveRestart = (graph, registry, ref, hub, roots, pluginContext, sinks, logger, identity, runtimeRoot, parentScope) => Effect.gen(function* () {
38
- const plan = yield* planRestart(graph, roots);
37
+ });
38
+ const doSelectiveRestart = (graph, registry, ref, hub, roots, pluginContext, dispatcher, logger, identity, parentScope) => Effect.gen(function* () {
39
+ const restartPlan = yield* planRestart(graph, roots);
39
40
  const at = Date.now();
40
41
  for (const root of roots) yield* publish(ref, hub, {
41
42
  tag: "restart.requested",
42
43
  target: { pluginKey: root },
43
44
  at
44
45
  });
45
- yield* teardownKeys(graph, registry, plan.teardownOrder);
46
- for (const key of plan.acquireOrder) yield* registry.resetForRestart(key, parentScope).pipe(Effect.catch(() => Effect.void));
47
- yield* acquireKeys(registry, plan.acquireOrder, ref, hub, pluginContext, sinks, logger, identity, runtimeRoot);
46
+ yield* teardownKeys(graph, registry, restartPlan.teardownOrder);
47
+ for (const key of restartPlan.acquireOrder) yield* registry.resetForRestart(key, parentScope).pipe(Effect.catch(() => Effect.void));
48
+ yield* acquireKeys(registry, restartPlan.acquireOrder, ref, hub, pluginContext, dispatcher, logger, identity, parentScope);
48
49
  for (const root of roots) yield* publish(ref, hub, {
49
50
  tag: "restart.completed",
50
51
  target: { pluginKey: root },
51
52
  at: Date.now()
52
53
  });
53
- }).pipe(Effect.withSpan("lifecycle.supervisor.selectiveRestart"));
54
+ });
54
55
  //#endregion
55
56
  export { doSelectiveRestart, teardownKeys };
56
57
 
@@ -1 +1 @@
1
- {"version":3,"file":"teardown.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/teardown.ts"],"sourcesContent":["// Teardown + selective restart.\n//\n// Plugin scopes close in reverse-dep order, parallel within each level\n// (max grace, not sum grace, per architecture § Stack lifecycle).\n// Selective restart tears a slice down then re-acquires it in\n// dependency order, reusing the per-node acquire pipeline.\n\nimport { Context, Effect, Exit, Queue, Scope, SubscriptionRef } from 'effect';\n\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { type CapabilitySinksShape } from '../capability-sinks/index.ts';\nimport type { LoggerShape } from '../observability/index.ts';\nimport {\n\tplanRestart,\n\ttype PluginRegistry,\n\ttype ResolvedGraph,\n\ttype RestartTargetMissing,\n} from '../lifecycle/index.ts';\nimport { acquireKeys } from './acquire-node.ts';\nimport { bestEffort, publish } from './wiring.ts';\n\n// -----------------------------------------------------------------------------\n// Teardown\n// -----------------------------------------------------------------------------\n\n/**\n * Tear down a slice in reverse-dep order, parallel within each level.\n * Each node's scope close runs its finalizers; status transitions\n * `ready → stopping → stopped` are emitted.\n *\n * Architecture § Stack lifecycle: \"shutdown.requested → parallel\n * teardown (max grace, not sum grace)\".\n */\nexport const teardownKeys = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n\tkeys: ReadonlyArray<PluginKey>,\n): Effect.Effect<void, never, never> =>\n\tEffect.gen(function* () {\n\t\tconst byLevel: Array<Array<PluginKey>> = graph.levels.map(() => []);\n\t\tconst keySet = new Set(keys);\n\t\tfor (let i = 0; i < graph.levels.length; i++) {\n\t\t\tfor (const key of graph.levels[i]!) {\n\t\t\t\tif (keySet.has(key)) byLevel[i]!.push(key);\n\t\t\t}\n\t\t}\n\t\tfor (let i = byLevel.length - 1; i >= 0; i--) {\n\t\t\tconst level = byLevel[i]!;\n\t\t\tif (level.length === 0) continue;\n\t\t\tyield* Effect.all(\n\t\t\t\tlevel.map((key) => teardownNode(registry, key)),\n\t\t\t\t{ concurrency: 'unbounded', discard: true },\n\t\t\t);\n\t\t}\n\t}).pipe(Effect.withSpan('lifecycle.supervisor.teardownKeys'));\n\nexport const teardownNode = (\n\tregistry: PluginRegistry,\n\tkey: PluginKey,\n): Effect.Effect<void, never, never> =>\n\tEffect.gen(function* () {\n\t\tconst entry = registry.entries.get(key);\n\t\tif (entry === undefined) return;\n\t\tconst status = yield* registry\n\t\t\t.getStatus(key)\n\t\t\t.pipe(Effect.catch(() => Effect.succeed<LifecycleStatus>('pending')));\n\t\t// Only `ready` plugins need stopping. `acquiring` plugins are\n\t\t// interrupted by the scope close. `failed` / `stopped` / `done`\n\t\t// are no-ops. `status` is a snapshot read above, so a concurrent\n\t\t// off-table move (e.g. a racing restart driving the node to\n\t\t// `failed`) can make `transition` hit `assertTransition` and\n\t\t// `Effect.die` — `bestEffort` (Effect.exit) swallows that defect\n\t\t// as well as the typed channel, keeping teardown's unbounded\n\t\t// fan-out from bubbling an unguarded die through the scope-close\n\t\t// finalizer.\n\t\tif (status === 'ready') {\n\t\t\tyield* bestEffort(registry.transition(key, 'stopping'));\n\t\t}\n\t\tyield* Scope.close(entry.scope, Exit.void).pipe(Effect.catch(() => Effect.void));\n\t\tif (status === 'ready') {\n\t\t\tyield* bestEffort(registry.transition(key, 'stopped'));\n\t\t}\n\t}).pipe(Effect.withSpan('lifecycle.supervisor.teardownNode'));\n\n// -----------------------------------------------------------------------------\n// Selective restart\n// -----------------------------------------------------------------------------\n\nexport const doSelectiveRestart = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\troots: ReadonlySet<PluginKey>,\n\tpluginContext: Context.Context<never>,\n\tsinks: CapabilitySinksShape,\n\tlogger: LoggerShape,\n\tidentity: Identity,\n\truntimeRoot: string,\n\tparentScope: Scope.Scope,\n): Effect.Effect<void, RestartTargetMissing> =>\n\tEffect.gen(function* () {\n\t\tconst plan = yield* planRestart(graph, roots);\n\t\tconst at = Date.now();\n\t\tfor (const root of roots) {\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'restart.requested',\n\t\t\t\ttarget: { pluginKey: root },\n\t\t\t\tat,\n\t\t\t});\n\t\t}\n\t\tyield* teardownKeys(graph, registry, plan.teardownOrder);\n\t\t// Re-acquire the slice in parallel. Each node waits on its own\n\t\t// upstream ready gate, so a downstream node in the slice can't\n\t\t// acquire until its upstream is back to `ready`; unrelated\n\t\t// siblings do not act as a level barrier. Nodes outside the\n\t\t// slice are already `ready`. `resetForRestart` rebuilds each\n\t\t// node's scope + ready gate AND authoritatively resets its\n\t\t// status to `pending` regardless of prior state (a node may\n\t\t// still be `acquiring` when its scope close interrupts it), so\n\t\t// the acquire below performs a clean `pending → acquiring`\n\t\t// transition for every slice node.\n\t\tfor (const key of plan.acquireOrder) {\n\t\t\tyield* registry.resetForRestart(key, parentScope).pipe(Effect.catch(() => Effect.void));\n\t\t}\n\t\tyield* acquireKeys(\n\t\t\tregistry,\n\t\t\tplan.acquireOrder,\n\t\t\tref,\n\t\t\thub,\n\t\t\tpluginContext,\n\t\t\tsinks,\n\t\t\tlogger,\n\t\t\tidentity,\n\t\t\truntimeRoot,\n\t\t);\n\t\tfor (const root of roots) {\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'restart.completed',\n\t\t\t\ttarget: { pluginKey: root },\n\t\t\t\tat: Date.now(),\n\t\t\t});\n\t\t}\n\t}).pipe(Effect.withSpan('lifecycle.supervisor.selectiveRestart'));\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,MAAa,gBACZ,OACA,UACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,UAAmC,MAAM,OAAO,UAAU,EAAE,CAAC;CACnE,MAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,MAAK,IAAI,IAAI,GAAG,IAAI,MAAM,OAAO,QAAQ,IACxC,MAAK,MAAM,OAAO,MAAM,OAAO,GAC9B,KAAI,OAAO,IAAI,IAAI,CAAE,SAAQ,GAAI,KAAK,IAAI;AAG5C,MAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,QAAQ,QAAQ;AACtB,MAAI,MAAM,WAAW,EAAG;AACxB,SAAO,OAAO,IACb,MAAM,KAAK,QAAQ,aAAa,UAAU,IAAI,CAAC,EAC/C;GAAE,aAAa;GAAa,SAAS;GAAM,CAC3C;;EAED,CAAC,KAAK,OAAO,SAAS,oCAAoC,CAAC;AAE9D,MAAa,gBACZ,UACA,QAEA,OAAO,IAAI,aAAa;CACvB,MAAM,QAAQ,SAAS,QAAQ,IAAI,IAAI;AACvC,KAAI,UAAU,KAAA,EAAW;CACzB,MAAM,SAAS,OAAO,SACpB,UAAU,IAAI,CACd,KAAK,OAAO,YAAY,OAAO,QAAyB,UAAU,CAAC,CAAC;AAUtE,KAAI,WAAW,QACd,QAAO,WAAW,SAAS,WAAW,KAAK,WAAW,CAAC;AAExD,QAAO,MAAM,MAAM,MAAM,OAAO,KAAK,KAAK,CAAC,KAAK,OAAO,YAAY,OAAO,KAAK,CAAC;AAChF,KAAI,WAAW,QACd,QAAO,WAAW,SAAS,WAAW,KAAK,UAAU,CAAC;EAEtD,CAAC,KAAK,OAAO,SAAS,oCAAoC,CAAC;AAM9D,MAAa,sBACZ,OACA,UACA,KACA,KACA,OACA,eACA,OACA,QACA,UACA,aACA,gBAEA,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,OAAO,YAAY,OAAO,MAAM;CAC7C,MAAM,KAAK,KAAK,KAAK;AACrB,MAAK,MAAM,QAAQ,MAClB,QAAO,QAAQ,KAAK,KAAK;EACxB,KAAK;EACL,QAAQ,EAAE,WAAW,MAAM;EAC3B;EACA,CAAC;AAEH,QAAO,aAAa,OAAO,UAAU,KAAK,cAAc;AAWxD,MAAK,MAAM,OAAO,KAAK,aACtB,QAAO,SAAS,gBAAgB,KAAK,YAAY,CAAC,KAAK,OAAO,YAAY,OAAO,KAAK,CAAC;AAExF,QAAO,YACN,UACA,KAAK,cACL,KACA,KACA,eACA,OACA,QACA,UACA,YACA;AACD,MAAK,MAAM,QAAQ,MAClB,QAAO,QAAQ,KAAK,KAAK;EACxB,KAAK;EACL,QAAQ,EAAE,WAAW,MAAM;EAC3B,IAAI,KAAK,KAAK;EACd,CAAC;EAEF,CAAC,KAAK,OAAO,SAAS,wCAAwC,CAAC"}
1
+ {"version":3,"file":"teardown.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/teardown.ts"],"sourcesContent":["// Teardown + selective restart.\n//\n// Plugin scopes close in reverse-dep order, parallel within each level\n// (max grace, not sum grace, per architecture § Stack lifecycle).\n// Selective restart tears a slice down then re-acquires it in\n// dependency order, reusing the per-node acquire pipeline.\n\nimport { Context, Effect, Exit, Queue, Scope, SubscriptionRef } from 'effect';\n\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineEvent } from '../../events.ts';\nimport type { Identity } from '../../identity.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { acquireKeys } from './acquire-node.ts';\nimport { type ContributionDispatcher } from './contribution-dispatcher.ts';\nimport type { LoggerShape } from '../observability/index.ts';\nimport {\n\tplanRestart,\n\ttype PluginRegistry,\n\ttype ResolvedGraph,\n\ttype RestartTargetMissing,\n} from '../lifecycle/index.ts';\nimport { bestEffort, publish } from './wiring.ts';\n\n// -----------------------------------------------------------------------------\n// Teardown\n// -----------------------------------------------------------------------------\n\n/**\n * Tear down a slice in reverse-dep order, parallel within each level.\n * Each node's scope close runs its finalizers; status transitions\n * `ready → stopping → stopped` are emitted.\n *\n * Architecture § Stack lifecycle: \"shutdown.requested → parallel\n * teardown (max grace, not sum grace)\".\n */\nexport const teardownKeys = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n\tkeys: ReadonlyArray<PluginKey>,\n): Effect.Effect<void, never, never> =>\n\tEffect.gen(function* () {\n\t\tconst byLevel: Array<Array<PluginKey>> = graph.levels.map(() => []);\n\t\tconst keySet = new Set(keys);\n\t\tfor (let i = 0; i < graph.levels.length; i++) {\n\t\t\tfor (const key of graph.levels[i]!) {\n\t\t\t\tif (keySet.has(key)) byLevel[i]!.push(key);\n\t\t\t}\n\t\t}\n\t\tfor (let i = byLevel.length - 1; i >= 0; i--) {\n\t\t\tconst level = byLevel[i]!;\n\t\t\tif (level.length === 0) continue;\n\t\t\tyield* Effect.all(\n\t\t\t\tlevel.map((key) => teardownNode(registry, key)),\n\t\t\t\t{ concurrency: 'unbounded', discard: true },\n\t\t\t);\n\t\t}\n\t});\n\nexport const teardownNode = (\n\tregistry: PluginRegistry,\n\tkey: PluginKey,\n): Effect.Effect<void, never, never> =>\n\tEffect.gen(function* () {\n\t\tconst entry = registry.entries.get(key);\n\t\tif (entry === undefined) return;\n\t\tyield* registry.interruptAcquire(key).pipe(Effect.catch(() => Effect.void));\n\t\tconst status = yield* registry\n\t\t\t.getStatus(key)\n\t\t\t.pipe(Effect.catch(() => Effect.succeed<LifecycleStatus>('pending')));\n\t\t// Only `ready` plugins need stopping. `acquiring` plugins are\n\t\t// interrupted by the scope close. `failed` / `stopped` / `done`\n\t\t// are no-ops. `status` is a snapshot read above, so a concurrent\n\t\t// off-table move (e.g. a racing restart driving the node to\n\t\t// `failed`) can make `transition` hit `assertTransition` and\n\t\t// `Effect.die` — `bestEffort` (Effect.exit) swallows that defect\n\t\t// as well as the typed channel, keeping teardown's unbounded\n\t\t// fan-out from bubbling an unguarded die through the scope-close\n\t\t// finalizer.\n\t\tif (status === 'ready') {\n\t\t\tyield* bestEffort(registry.transition(key, 'stopping'));\n\t\t}\n\t\tyield* Scope.close(entry.scope, Exit.void).pipe(Effect.catch(() => Effect.void));\n\t\tif (status === 'ready') {\n\t\t\tyield* bestEffort(registry.transition(key, 'stopped'));\n\t\t}\n\t});\n\n// -----------------------------------------------------------------------------\n// Selective restart\n// -----------------------------------------------------------------------------\n\nexport const doSelectiveRestart = (\n\tgraph: ResolvedGraph,\n\tregistry: PluginRegistry,\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\troots: ReadonlySet<PluginKey>,\n\tpluginContext: Context.Context<never>,\n\tdispatcher: ContributionDispatcher,\n\tlogger: LoggerShape,\n\tidentity: Identity,\n\tparentScope: Scope.Scope,\n): Effect.Effect<void, RestartTargetMissing> =>\n\tEffect.gen(function* () {\n\t\t// `planRestart` computes the downstream-closure slice (and validates\n\t\t// every root is in the graph → `RestartTargetMissing`). The reconcile\n\t\t// of that slice is then a `drain ∘ converge` over the SAME slice: the\n\t\t// kept `teardownKeys` over reverse-dep order, then `acquireKeys` over\n\t\t// forward-dep order. The `restart.*` settle events + the\n\t\t// `resetForRestart` reset between drain and converge stay HERE — that\n\t\t// choreography is selective-restart-specific.\n\t\tconst restartPlan = yield* planRestart(graph, roots);\n\t\tconst at = Date.now();\n\t\tfor (const root of roots) {\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'restart.requested',\n\t\t\t\ttarget: { pluginKey: root },\n\t\t\t\tat,\n\t\t\t});\n\t\t}\n\t\t// Drain: tear the slice down in reverse-dep order.\n\t\tyield* teardownKeys(graph, registry, restartPlan.teardownOrder);\n\t\t// Re-acquire the slice in parallel. Each node waits on its own\n\t\t// upstream ready gate, so a downstream node in the slice can't\n\t\t// acquire until its upstream is back to `ready`; unrelated\n\t\t// siblings do not act as a level barrier. Nodes outside the\n\t\t// slice are already `ready`. `resetForRestart` rebuilds each\n\t\t// node's scope + ready gate AND authoritatively resets its\n\t\t// status to `pending` regardless of prior state (a node may\n\t\t// still be `acquiring` when its scope close interrupts it), so\n\t\t// the acquire below performs a clean `pending → acquiring`\n\t\t// transition for every slice node.\n\t\tfor (const key of restartPlan.acquireOrder) {\n\t\t\tyield* registry.resetForRestart(key, parentScope).pipe(Effect.catch(() => Effect.void));\n\t\t}\n\t\t// Converge: re-acquire the slice in forward-dep order.\n\t\tyield* acquireKeys(\n\t\t\tregistry,\n\t\t\trestartPlan.acquireOrder,\n\t\t\tref,\n\t\t\thub,\n\t\t\tpluginContext,\n\t\t\tdispatcher,\n\t\t\tlogger,\n\t\t\tidentity,\n\t\t\tparentScope,\n\t\t);\n\t\tfor (const root of roots) {\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'restart.completed',\n\t\t\t\ttarget: { pluginKey: root },\n\t\t\t\tat: Date.now(),\n\t\t\t});\n\t\t}\n\t});\n"],"mappings":";;;;;;;;;;;;;;;AAqCA,MAAa,gBACZ,OACA,UACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,UAAmC,MAAM,OAAO,UAAU,CAAC,CAAC;CAClE,MAAM,SAAS,IAAI,IAAI,IAAI;CAC3B,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM,OAAO,QAAQ,KACxC,KAAK,MAAM,OAAO,MAAM,OAAO,IAC9B,IAAI,OAAO,IAAI,GAAG,GAAG,QAAQ,EAAE,CAAE,KAAK,GAAG;CAG3C,KAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,QAAQ,QAAQ;EACtB,IAAI,MAAM,WAAW,GAAG;EACxB,OAAO,OAAO,IACb,MAAM,KAAK,QAAQ,aAAa,UAAU,GAAG,CAAC,GAC9C;GAAE,aAAa;GAAa,SAAS;EAAK,CAC3C;CACD;AACD,CAAC;AAEF,MAAa,gBACZ,UACA,QAEA,OAAO,IAAI,aAAa;CACvB,MAAM,QAAQ,SAAS,QAAQ,IAAI,GAAG;CACtC,IAAI,UAAU,KAAA,GAAW;CACzB,OAAO,SAAS,iBAAiB,GAAG,CAAC,CAAC,KAAK,OAAO,YAAY,OAAO,IAAI,CAAC;CAC1E,MAAM,SAAS,OAAO,SACpB,UAAU,GAAG,CAAC,CACd,KAAK,OAAO,YAAY,OAAO,QAAyB,SAAS,CAAC,CAAC;CAUrE,IAAI,WAAW,SACd,OAAO,WAAW,SAAS,WAAW,KAAK,UAAU,CAAC;CAEvD,OAAO,MAAM,MAAM,MAAM,OAAO,KAAK,IAAI,CAAC,CAAC,KAAK,OAAO,YAAY,OAAO,IAAI,CAAC;CAC/E,IAAI,WAAW,SACd,OAAO,WAAW,SAAS,WAAW,KAAK,SAAS,CAAC;AAEvD,CAAC;AAMF,MAAa,sBACZ,OACA,UACA,KACA,KACA,OACA,eACA,YACA,QACA,UACA,gBAEA,OAAO,IAAI,aAAa;CAQvB,MAAM,cAAc,OAAO,YAAY,OAAO,KAAK;CACnD,MAAM,KAAK,KAAK,IAAI;CACpB,KAAK,MAAM,QAAQ,OAClB,OAAO,QAAQ,KAAK,KAAK;EACxB,KAAK;EACL,QAAQ,EAAE,WAAW,KAAK;EAC1B;CACD,CAAC;CAGF,OAAO,aAAa,OAAO,UAAU,YAAY,aAAa;CAW9D,KAAK,MAAM,OAAO,YAAY,cAC7B,OAAO,SAAS,gBAAgB,KAAK,WAAW,CAAC,CAAC,KAAK,OAAO,YAAY,OAAO,IAAI,CAAC;CAGvF,OAAO,YACN,UACA,YAAY,cACZ,KACA,KACA,eACA,YACA,QACA,UACA,WACD;CACA,KAAK,MAAM,QAAQ,OAClB,OAAO,QAAQ,KAAK,KAAK;EACxB,KAAK;EACL,QAAQ,EAAE,WAAW,KAAK;EAC1B,IAAI,KAAK,IAAI;CACd,CAAC;AAEH,CAAC"}
@@ -19,19 +19,11 @@ import { Context, Effect, Option, Queue, SubscriptionRef } from "effect";
19
19
  const bestEffort = (effect) => Effect.exit(effect);
20
20
  /**
21
21
  * Read an optional service from a `Context.Context<never>` or fall back
22
- * to a default. The supervisor's `pluginContext` is name-blind: a
22
+ * to a default value. The supervisor's `pluginContext` is name-blind: a
23
23
  * caller may or may not have layered a `Logger`, `RuntimeRoot`, or
24
- * `CapabilitySinksService`. The lookup pattern was open-coded in three
24
+ * `StrategyRegistry`. The lookup pattern was open-coded in three
25
25
  * sites until backlog #40 lifted it here.
26
26
  *
27
- * Two surfaces, mirroring the prior `getOrDefault` / `getOrDefaultEffect`
28
- * helpers:
29
- *
30
- * - `read(ctx)` — value fallback (Logger, RuntimeRoot).
31
- * - `readEffect(ctx)` — Effect fallback so the substrate only pays the
32
- * "build the default Layer" cost when nothing is in context
33
- * (CapabilitySinksService).
34
- *
35
27
  * Upstream-watch (Phase 5 reviewer): Effect v4 exposes `Context.getOption`
36
28
  * (returns `Option<S>`) and `Context.getUnsafe` (throws on missing), but
37
29
  * NO `getOptionUnchecked`-style variant that returns `Option<S>` over a
@@ -39,16 +31,10 @@ const bestEffort = (effect) => Effect.exit(effect);
39
31
  * stays until upstream adds an unchecked optional getter — at which
40
32
  * point the body collapses to a thin alias.
41
33
  */
42
- const OptionalService = (tag) => ({
43
- read: (ctx, fallback) => {
44
- const opt = Context.getOption(ctx, tag);
45
- return Option.isSome(opt) ? opt.value : fallback;
46
- },
47
- readEffect: (ctx, fallback) => {
48
- const opt = Context.getOption(ctx, tag);
49
- return Option.isSome(opt) ? Effect.succeed(opt.value) : fallback;
50
- }
51
- });
34
+ const OptionalService = (tag) => ({ read: (ctx, fallback) => {
35
+ const opt = Context.getOption(ctx, tag);
36
+ return Option.isSome(opt) ? opt.value : fallback;
37
+ } });
52
38
  /** Fallback used when the supervisor's `pluginContext` doesn't carry a
53
39
  * Logger service. Swallows every line — the trade-off is that bare
54
40
  * `supervise()` smoke tests stay log-free, while the wired CLI / e2e
@@ -1 +1 @@
1
- {"version":3,"file":"wiring.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/wiring.ts"],"sourcesContent":["// Supervisor wiring helpers.\n//\n// Tiny support module for the supervisor's substrate-wiring concerns:\n// fallback Logger, fallback StrategyRegistry, event publishing helpers,\n// projection-level mapping, the transition emitter builder, and the\n// OptionalService<T> helper that centralises the \"look up an optional\n// service in pluginContext, fall back if absent\" pattern endemic to\n// the supervisor boundary.\n//\n// Split out of the monolith per backlog #38 + #40.\n\nimport { Context, Effect, type Exit, Option, Queue, SubscriptionRef } from 'effect';\n\nimport type { StrategyRegistry } from '../../../contracts/strategy-contributor.ts';\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineEvent } from '../../events.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { StrategyNotFoundError } from '../errors.ts';\nimport type { LoggerShape, LogStoreShape } from '../observability/index.ts';\nimport { serviceKeyFor } from '../observability/index.ts';\nimport { updateRef } from '../projection/update.ts';\n\n// -----------------------------------------------------------------------------\n// Best-effort lifecycle mutation\n// -----------------------------------------------------------------------------\n\n/**\n * Swallow BOTH the typed failure and any defect of a best-effort\n * effect, discarding its outcome. Lifecycle mutations\n * (`registry.transition` / `markReady` / `markFailed`) validate against\n * the transition table via `assertTransition`, which `Effect.die`s (a\n * DEFECT, not a typed failure) on an off-table move — reachable when a\n * concurrent selective-restart races an in-flight acquire. `Effect.catch`\n * only intercepts the typed `E` channel, so a die would escape and bubble\n * unguarded through the unbounded acquire fan-out (supervisor wedge).\n * `Effect.exit` captures failure AND defect into an `Exit` we discard,\n * keeping these mutations genuinely best-effort.\n */\nexport const bestEffort = <A, E, R>(\n\teffect: Effect.Effect<A, E, R>,\n): Effect.Effect<Exit.Exit<A, E>, never, R> => Effect.exit(effect);\n\n// -----------------------------------------------------------------------------\n// OptionalService<T> — substrate-wide \"service-or-default\" helper\n// -----------------------------------------------------------------------------\n\n/**\n * Read an optional service from a `Context.Context<never>` or fall back\n * to a default. The supervisor's `pluginContext` is name-blind: a\n * caller may or may not have layered a `Logger`, `RuntimeRoot`, or\n * `CapabilitySinksService`. The lookup pattern was open-coded in three\n * sites until backlog #40 lifted it here.\n *\n * Two surfaces, mirroring the prior `getOrDefault` / `getOrDefaultEffect`\n * helpers:\n *\n * - `read(ctx)` — value fallback (Logger, RuntimeRoot).\n * - `readEffect(ctx)` — Effect fallback so the substrate only pays the\n * \"build the default Layer\" cost when nothing is in context\n * (CapabilitySinksService).\n *\n * Upstream-watch (Phase 5 reviewer): Effect v4 exposes `Context.getOption`\n * (returns `Option<S>`) and `Context.getUnsafe` (throws on missing), but\n * NO `getOptionUnchecked`-style variant that returns `Option<S>` over a\n * `Context<never>` without the typed cast we perform here. The wrapper\n * stays until upstream adds an unchecked optional getter — at which\n * point the body collapses to a thin alias.\n */\nexport const OptionalService = <S, I>(tag: Context.Key<I, S>) => ({\n\tread: (ctx: Context.Context<never>, fallback: S): S => {\n\t\tconst opt = Context.getOption(ctx as Context.Context<I>, tag);\n\t\treturn Option.isSome(opt) ? opt.value : fallback;\n\t},\n\treadEffect: <E, R>(\n\t\tctx: Context.Context<never>,\n\t\tfallback: Effect.Effect<S, E, R>,\n\t): Effect.Effect<S, E, R> => {\n\t\tconst opt = Context.getOption(ctx as Context.Context<I>, tag);\n\t\treturn Option.isSome(opt) ? Effect.succeed(opt.value) : fallback;\n\t},\n});\n\n// -----------------------------------------------------------------------------\n// Fallback services for bare smoke-test `supervise()` paths\n// -----------------------------------------------------------------------------\n\n/** Fallback used when the supervisor's `pluginContext` doesn't carry a\n * Logger service. Swallows every line — the trade-off is that bare\n * `supervise()` smoke tests stay log-free, while the wired CLI / e2e\n * layer stack picks up the real Logger. */\nexport const noopLogger: LoggerShape = {\n\tlog: () => Effect.void,\n\treadTag: () => Effect.succeed({ lines: [], truncated: false }),\n\treadAll: Effect.succeed(new Map()),\n\tclearTag: () => Effect.void,\n};\n\nexport const noopStrategyRegistry: StrategyRegistry = {\n\tget: (key) =>\n\t\tEffect.fail(\n\t\t\tnew StrategyNotFoundError({\n\t\t\t\tcapabilityKey: key,\n\t\t\t\tregisteredKeys: [],\n\t\t\t}),\n\t\t),\n\tlist: () => Effect.succeed([]),\n\tregister: () => Effect.void,\n};\n\n// -----------------------------------------------------------------------------\n// Event publishing\n// -----------------------------------------------------------------------------\n\n/** Publishing helper: writes the event to the projection ref AND\n * enqueues it onto the live event hub for renderers that subscribe to\n * the raw stream. */\nexport const publish = (\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\tevent: EngineEvent,\n): Effect.Effect<void> =>\n\tEffect.gen(function* () {\n\t\tyield* updateRef(ref, event);\n\t\tyield* Queue.offer(hub, event);\n\t});\n\nexport const setCyclePhase = (\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tphase: SubscribableState['cycle']['phase'],\n): Effect.Effect<void> =>\n\tSubscriptionRef.update(ref, (state) => ({\n\t\t...state,\n\t\tcycle: {\n\t\t\t...state.cycle,\n\t\t\tstartedAt: state.cycle.startedAt === 0 ? Date.now() : state.cycle.startedAt,\n\t\t\tphase,\n\t\t},\n\t}));\n\n// -----------------------------------------------------------------------------\n// Logger overlay — projects structured log lines into `log.appended`\n// -----------------------------------------------------------------------------\n\nexport const projectionLevel = (\n\tlevel: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal',\n): Extract<EngineEvent, { tag: 'log.appended' }>['level'] | null => {\n\tswitch (level) {\n\t\tcase 'trace':\n\t\tcase 'debug':\n\t\t\treturn null;\n\t\tcase 'info':\n\t\t\treturn 'info';\n\t\tcase 'warn':\n\t\t\treturn 'warn';\n\t\tcase 'error':\n\t\tcase 'fatal':\n\t\t\treturn 'error';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = level;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'info';\n\t\t}\n\t}\n};\n\nexport const withEventPublishingLogger = (\n\tbase: LoggerShape,\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\t/** Optional cross-service queryable store. Every logged line is teed\n\t * into it (the SAME source that feeds the projection's per-row tail —\n\t * see log-store.ts), so the dashboard's \"Logs\" tab gets a filterable\n\t * cross-service history without a second log reader. Absent in bare\n\t * smoke-test paths that don't wire a LogStore. */\n\tlogStore: LogStoreShape | null = null,\n): LoggerShape => ({\n\t...base,\n\tlog: (tag, pluginKey, payload) =>\n\t\tEffect.gen(function* () {\n\t\t\tyield* base.log(tag, pluginKey, payload);\n\t\t\t// Tee into the cross-service store regardless of plugin key —\n\t\t\t// the queryable surface keeps supervisor-level lines too (the\n\t\t\t// projection tail below is row-scoped, so it only takes\n\t\t\t// plugin-attributed lines).\n\t\t\tif (logStore !== null) {\n\t\t\t\tyield* logStore.append({\n\t\t\t\t\tlevel: payload.level,\n\t\t\t\t\tservice: serviceKeyFor(tag, pluginKey),\n\t\t\t\t\tmessage: payload.message,\n\t\t\t\t\tfields: payload.fields,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (pluginKey === null) return;\n\t\t\tconst level = projectionLevel(payload.level);\n\t\t\tif (level === null) return;\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'log.appended',\n\t\t\t\tpluginKey,\n\t\t\t\tline: payload.message,\n\t\t\t\tlevel,\n\t\t\t\tat: Date.now(),\n\t\t\t});\n\t\t}),\n});\n\n// -----------------------------------------------------------------------------\n// Transition emitter\n// -----------------------------------------------------------------------------\n\n/** Build the registry's `onTransition` callback — turns status changes\n * into typed events. */\nexport const buildTransitionEmitter =\n\t(\n\t\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\t\thub: Queue.Enqueue<EngineEvent>,\n\t): ((key: PluginKey, from: LifecycleStatus, to: LifecycleStatus) => Effect.Effect<void>) =>\n\t(key, from, to) =>\n\t\tpublish(ref, hub, {\n\t\t\ttag: 'lifecycle.statusChanged',\n\t\t\tpluginKey: key,\n\t\t\tfrom,\n\t\t\tto,\n\t\t\tat: Date.now(),\n\t\t});\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,MAAa,cACZ,WAC8C,OAAO,KAAK,OAAO;;;;;;;;;;;;;;;;;;;;;;;AA4BlE,MAAa,mBAAyB,SAA4B;CACjE,OAAO,KAA6B,aAAmB;EACtD,MAAM,MAAM,QAAQ,UAAU,KAA2B,IAAI;AAC7D,SAAO,OAAO,OAAO,IAAI,GAAG,IAAI,QAAQ;;CAEzC,aACC,KACA,aAC4B;EAC5B,MAAM,MAAM,QAAQ,UAAU,KAA2B,IAAI;AAC7D,SAAO,OAAO,OAAO,IAAI,GAAG,OAAO,QAAQ,IAAI,MAAM,GAAG;;CAEzD;;;;;AAUD,MAAa,aAA0B;CACtC,WAAW,OAAO;CAClB,eAAe,OAAO,QAAQ;EAAE,OAAO,EAAE;EAAE,WAAW;EAAO,CAAC;CAC9D,SAAS,OAAO,wBAAQ,IAAI,KAAK,CAAC;CAClC,gBAAgB,OAAO;CACvB;AAED,MAAa,uBAAyC;CACrD,MAAM,QACL,OAAO,KACN,IAAI,sBAAsB;EACzB,eAAe;EACf,gBAAgB,EAAE;EAClB,CAAC,CACF;CACF,YAAY,OAAO,QAAQ,EAAE,CAAC;CAC9B,gBAAgB,OAAO;CACvB;;;;AASD,MAAa,WACZ,KACA,KACA,UAEA,OAAO,IAAI,aAAa;AACvB,QAAO,UAAU,KAAK,MAAM;AAC5B,QAAO,MAAM,MAAM,KAAK,MAAM;EAC7B;AAEH,MAAa,iBACZ,KACA,UAEA,gBAAgB,OAAO,MAAM,WAAW;CACvC,GAAG;CACH,OAAO;EACN,GAAG,MAAM;EACT,WAAW,MAAM,MAAM,cAAc,IAAI,KAAK,KAAK,GAAG,MAAM,MAAM;EAClE;EACA;CACD,EAAE;AAMJ,MAAa,mBACZ,UACmE;AACnE,SAAQ,OAAR;EACC,KAAK;EACL,KAAK,QACJ,QAAO;EACR,KAAK,OACJ,QAAO;EACR,KAAK,OACJ,QAAO;EACR,KAAK;EACL,KAAK,QACJ,QAAO;EACR,QAGC,QAAO;;;AAKV,MAAa,6BACZ,MACA,KACA,KAMA,WAAiC,UACf;CAClB,GAAG;CACH,MAAM,KAAK,WAAW,YACrB,OAAO,IAAI,aAAa;AACvB,SAAO,KAAK,IAAI,KAAK,WAAW,QAAQ;AAKxC,MAAI,aAAa,KAChB,QAAO,SAAS,OAAO;GACtB,OAAO,QAAQ;GACf,SAAS,cAAc,KAAK,UAAU;GACtC,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,CAAC;AAEH,MAAI,cAAc,KAAM;EACxB,MAAM,QAAQ,gBAAgB,QAAQ,MAAM;AAC5C,MAAI,UAAU,KAAM;AACpB,SAAO,QAAQ,KAAK,KAAK;GACxB,KAAK;GACL;GACA,MAAM,QAAQ;GACd;GACA,IAAI,KAAK,KAAK;GACd,CAAC;GACD;CACH;;;AAQD,MAAa,0BAEX,KACA,SAEA,KAAK,MAAM,OACX,QAAQ,KAAK,KAAK;CACjB,KAAK;CACL,WAAW;CACX;CACA;CACA,IAAI,KAAK,KAAK;CACd,CAAC"}
1
+ {"version":3,"file":"wiring.mjs","names":[],"sources":["../../../../src/substrate/runtime/supervisor/wiring.ts"],"sourcesContent":["// Supervisor wiring helpers.\n//\n// Tiny support module for the supervisor's substrate-wiring concerns:\n// fallback Logger, fallback StrategyRegistry, event publishing helpers,\n// projection-level mapping, the transition emitter builder, and the\n// OptionalService<T> helper that centralises the \"look up an optional\n// service in pluginContext, fall back if absent\" pattern endemic to\n// the supervisor boundary.\n//\n// Split out of the monolith per backlog #38 + #40.\n\nimport { Context, Effect, type Exit, Option, Queue, SubscriptionRef } from 'effect';\n\nimport type { StrategyRegistry } from '../../../contracts/strategy-contributor.ts';\nimport type { PluginKey } from '../../brand.ts';\nimport type { EngineEvent } from '../../events.ts';\nimport type { LifecycleStatus } from '../../lifecycle.ts';\nimport type { SubscribableState } from '../../projection.ts';\nimport { StrategyNotFoundError } from '../errors.ts';\nimport type { LoggerShape, LogStoreShape } from '../observability/index.ts';\nimport { serviceKeyFor } from '../observability/index.ts';\nimport { updateRef } from '../projection/update.ts';\n\n// -----------------------------------------------------------------------------\n// Best-effort lifecycle mutation\n// -----------------------------------------------------------------------------\n\n/**\n * Swallow BOTH the typed failure and any defect of a best-effort\n * effect, discarding its outcome. Lifecycle mutations\n * (`registry.transition` / `markReady` / `markFailed`) validate against\n * the transition table via `assertTransition`, which `Effect.die`s (a\n * DEFECT, not a typed failure) on an off-table move — reachable when a\n * concurrent selective-restart races an in-flight acquire. `Effect.catch`\n * only intercepts the typed `E` channel, so a die would escape and bubble\n * unguarded through the unbounded acquire fan-out (supervisor wedge).\n * `Effect.exit` captures failure AND defect into an `Exit` we discard,\n * keeping these mutations genuinely best-effort.\n */\nexport const bestEffort = <A, E, R>(\n\teffect: Effect.Effect<A, E, R>,\n): Effect.Effect<Exit.Exit<A, E>, never, R> => Effect.exit(effect);\n\n// -----------------------------------------------------------------------------\n// OptionalService<T> — substrate-wide \"service-or-default\" helper\n// -----------------------------------------------------------------------------\n\n/**\n * Read an optional service from a `Context.Context<never>` or fall back\n * to a default value. The supervisor's `pluginContext` is name-blind: a\n * caller may or may not have layered a `Logger`, `RuntimeRoot`, or\n * `StrategyRegistry`. The lookup pattern was open-coded in three\n * sites until backlog #40 lifted it here.\n *\n * Upstream-watch (Phase 5 reviewer): Effect v4 exposes `Context.getOption`\n * (returns `Option<S>`) and `Context.getUnsafe` (throws on missing), but\n * NO `getOptionUnchecked`-style variant that returns `Option<S>` over a\n * `Context<never>` without the typed cast we perform here. The wrapper\n * stays until upstream adds an unchecked optional getter — at which\n * point the body collapses to a thin alias.\n */\nexport const OptionalService = <S, I>(tag: Context.Key<I, S>) => ({\n\tread: (ctx: Context.Context<never>, fallback: S): S => {\n\t\tconst opt = Context.getOption(ctx as Context.Context<I>, tag);\n\t\treturn Option.isSome(opt) ? opt.value : fallback;\n\t},\n});\n\n// -----------------------------------------------------------------------------\n// Fallback services for bare smoke-test `supervise()` paths\n// -----------------------------------------------------------------------------\n\n/** Fallback used when the supervisor's `pluginContext` doesn't carry a\n * Logger service. Swallows every line — the trade-off is that bare\n * `supervise()` smoke tests stay log-free, while the wired CLI / e2e\n * layer stack picks up the real Logger. */\nexport const noopLogger: LoggerShape = {\n\tlog: () => Effect.void,\n\treadTag: () => Effect.succeed({ lines: [], truncated: false }),\n\treadAll: Effect.succeed(new Map()),\n\tclearTag: () => Effect.void,\n};\n\nexport const noopStrategyRegistry: StrategyRegistry = {\n\tget: (key) =>\n\t\tEffect.fail(\n\t\t\tnew StrategyNotFoundError({\n\t\t\t\tcapabilityKey: key,\n\t\t\t\tregisteredKeys: [],\n\t\t\t}),\n\t\t),\n\tlist: () => Effect.succeed([]),\n\tregister: () => Effect.void,\n};\n\n// -----------------------------------------------------------------------------\n// Event publishing\n// -----------------------------------------------------------------------------\n\n/** Publishing helper: writes the event to the projection ref AND\n * enqueues it onto the live event hub for renderers that subscribe to\n * the raw stream. */\nexport const publish = (\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\tevent: EngineEvent,\n): Effect.Effect<void> =>\n\tEffect.gen(function* () {\n\t\tyield* updateRef(ref, event);\n\t\tyield* Queue.offer(hub, event);\n\t});\n\nexport const setCyclePhase = (\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\tphase: SubscribableState['cycle']['phase'],\n): Effect.Effect<void> =>\n\tSubscriptionRef.update(ref, (state) => ({\n\t\t...state,\n\t\tcycle: {\n\t\t\t...state.cycle,\n\t\t\tstartedAt: state.cycle.startedAt === 0 ? Date.now() : state.cycle.startedAt,\n\t\t\tphase,\n\t\t},\n\t}));\n\n// -----------------------------------------------------------------------------\n// Logger overlay — projects structured log lines into `log.appended`\n// -----------------------------------------------------------------------------\n\nexport const projectionLevel = (\n\tlevel: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal',\n): Extract<EngineEvent, { tag: 'log.appended' }>['level'] | null => {\n\tswitch (level) {\n\t\tcase 'trace':\n\t\tcase 'debug':\n\t\t\treturn null;\n\t\tcase 'info':\n\t\t\treturn 'info';\n\t\tcase 'warn':\n\t\t\treturn 'warn';\n\t\tcase 'error':\n\t\tcase 'fatal':\n\t\t\treturn 'error';\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = level;\n\t\t\tvoid _exhaustive;\n\t\t\treturn 'info';\n\t\t}\n\t}\n};\n\nexport const withEventPublishingLogger = (\n\tbase: LoggerShape,\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\thub: Queue.Enqueue<EngineEvent>,\n\t/** Optional cross-service queryable store. Every logged line is teed\n\t * into it (the SAME source that feeds the projection's per-row tail —\n\t * see log-store.ts), so the dashboard's \"Logs\" tab gets a filterable\n\t * cross-service history without a second log reader. Absent in bare\n\t * smoke-test paths that don't wire a LogStore. */\n\tlogStore: LogStoreShape | null = null,\n): LoggerShape => ({\n\t...base,\n\tlog: (tag, pluginKey, payload) =>\n\t\tEffect.gen(function* () {\n\t\t\tyield* base.log(tag, pluginKey, payload);\n\t\t\t// Tee into the cross-service store regardless of plugin key —\n\t\t\t// the queryable surface keeps supervisor-level lines too (the\n\t\t\t// projection tail below is row-scoped, so it only takes\n\t\t\t// plugin-attributed lines).\n\t\t\tif (logStore !== null) {\n\t\t\t\tyield* logStore.append({\n\t\t\t\t\tlevel: payload.level,\n\t\t\t\t\tservice: serviceKeyFor(tag, pluginKey),\n\t\t\t\t\tmessage: payload.message,\n\t\t\t\t\tfields: payload.fields,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (pluginKey === null) return;\n\t\t\tconst level = projectionLevel(payload.level);\n\t\t\tif (level === null) return;\n\t\t\tyield* publish(ref, hub, {\n\t\t\t\ttag: 'log.appended',\n\t\t\t\tpluginKey,\n\t\t\t\tline: payload.message,\n\t\t\t\tlevel,\n\t\t\t\tat: Date.now(),\n\t\t\t});\n\t\t}),\n});\n\n// -----------------------------------------------------------------------------\n// Transition emitter\n// -----------------------------------------------------------------------------\n\n/** Build the registry's `onTransition` callback — turns status changes\n * into typed events. */\nexport const buildTransitionEmitter =\n\t(\n\t\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n\t\thub: Queue.Enqueue<EngineEvent>,\n\t): ((key: PluginKey, from: LifecycleStatus, to: LifecycleStatus) => Effect.Effect<void>) =>\n\t(key, from, to) =>\n\t\tpublish(ref, hub, {\n\t\t\ttag: 'lifecycle.statusChanged',\n\t\t\tpluginKey: key,\n\t\t\tfrom,\n\t\t\tto,\n\t\t\tat: Date.now(),\n\t\t});\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,MAAa,cACZ,WAC8C,OAAO,KAAK,MAAM;;;;;;;;;;;;;;;AAoBjE,MAAa,mBAAyB,SAA4B,EACjE,OAAO,KAA6B,aAAmB;CACtD,MAAM,MAAM,QAAQ,UAAU,KAA2B,GAAG;CAC5D,OAAO,OAAO,OAAO,GAAG,IAAI,IAAI,QAAQ;AACzC,EACD;;;;;AAUA,MAAa,aAA0B;CACtC,WAAW,OAAO;CAClB,eAAe,OAAO,QAAQ;EAAE,OAAO,CAAC;EAAG,WAAW;CAAM,CAAC;CAC7D,SAAS,OAAO,wBAAQ,IAAI,IAAI,CAAC;CACjC,gBAAgB,OAAO;AACxB;AAEA,MAAa,uBAAyC;CACrD,MAAM,QACL,OAAO,KACN,IAAI,sBAAsB;EACzB,eAAe;EACf,gBAAgB,CAAC;CAClB,CAAC,CACF;CACD,YAAY,OAAO,QAAQ,CAAC,CAAC;CAC7B,gBAAgB,OAAO;AACxB;;;;AASA,MAAa,WACZ,KACA,KACA,UAEA,OAAO,IAAI,aAAa;CACvB,OAAO,UAAU,KAAK,KAAK;CAC3B,OAAO,MAAM,MAAM,KAAK,KAAK;AAC9B,CAAC;AAEF,MAAa,iBACZ,KACA,UAEA,gBAAgB,OAAO,MAAM,WAAW;CACvC,GAAG;CACH,OAAO;EACN,GAAG,MAAM;EACT,WAAW,MAAM,MAAM,cAAc,IAAI,KAAK,IAAI,IAAI,MAAM,MAAM;EAClE;CACD;AACD,EAAE;AAMH,MAAa,mBACZ,UACmE;CACnE,QAAQ,OAAR;EACC,KAAK;EACL,KAAK,SACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK,QACJ,OAAO;EACR,KAAK;EACL,KAAK,SACJ,OAAO;EACR,SAGC,OAAO;CAET;AACD;AAEA,MAAa,6BACZ,MACA,KACA,KAMA,WAAiC,UACf;CAClB,GAAG;CACH,MAAM,KAAK,WAAW,YACrB,OAAO,IAAI,aAAa;EACvB,OAAO,KAAK,IAAI,KAAK,WAAW,OAAO;EAKvC,IAAI,aAAa,MAChB,OAAO,SAAS,OAAO;GACtB,OAAO,QAAQ;GACf,SAAS,cAAc,KAAK,SAAS;GACrC,SAAS,QAAQ;GACjB,QAAQ,QAAQ;EACjB,CAAC;EAEF,IAAI,cAAc,MAAM;EACxB,MAAM,QAAQ,gBAAgB,QAAQ,KAAK;EAC3C,IAAI,UAAU,MAAM;EACpB,OAAO,QAAQ,KAAK,KAAK;GACxB,KAAK;GACL;GACA,MAAM,QAAQ;GACd;GACA,IAAI,KAAK,IAAI;EACd,CAAC;CACF,CAAC;AACH;;;AAQA,MAAa,0BAEX,KACA,SAEA,KAAK,MAAM,OACX,QAAQ,KAAK,KAAK;CACjB,KAAK;CACL,WAAW;CACX;CACA;CACA,IAAI,KAAK,IAAI;AACd,CAAC"}