@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,8 +1,8 @@
1
1
  import { definePlugin, resource } from "../../substrate/plugin.mjs";
2
2
  import "../../api/define-plugin.mjs";
3
- import { IdentityContext } from "../../substrate/runtime/paths.mjs";
4
3
  import { ControlPlaneService } from "../../substrate/runtime/control-plane/service.mjs";
5
- import { ContainerRuntimeService } from "../../runtime/docker/service.mjs";
4
+ import { IdentityContext } from "../../substrate/runtime/paths.mjs";
5
+ import { PluginContext } from "../../substrate/plugin-ctx.mjs";
6
6
  import { StrategyRegistryService } from "../../substrate/runtime/strategy-registry/service.mjs";
7
7
  import { PortBrokerService } from "../../substrate/runtime/port-broker/service.mjs";
8
8
  import "../../substrate/runtime/port-broker/index.mjs";
@@ -23,18 +23,16 @@ function dashboard(opts = {}) {
23
23
  id: dashboardResource.id,
24
24
  role: "service",
25
25
  section: "service",
26
+ keepAliveOnRestore: true,
26
27
  start: () => Effect.gen(function* () {
28
+ const ctx = yield* PluginContext;
27
29
  const portBroker = yield* PortBrokerService;
28
30
  const control = yield* ControlPlaneService;
29
31
  const identity = yield* IdentityContext;
30
- const containerRuntimeOpt = yield* Effect.serviceOption(ContainerRuntimeService);
31
- const containerRuntime = containerRuntimeOpt._tag === "Some" ? containerRuntimeOpt.value : null;
32
32
  const strategyRegistryOpt = yield* Effect.serviceOption(StrategyRegistryService);
33
33
  const strategyRegistry = strategyRegistryOpt._tag === "Some" ? strategyRegistryOpt.value : null;
34
34
  const pluginDomain = buildDashboardDomain({
35
35
  control: control.domain,
36
- identity,
37
- containerRuntime,
38
36
  strategyRegistry
39
37
  });
40
38
  const bindAddress = opts.bindAddress ?? DASHBOARD_DEFAULT_BIND;
@@ -60,7 +58,7 @@ function dashboard(opts = {}) {
60
58
  directOrigins,
61
59
  extraOrigins: opts.allowedOrigins ?? []
62
60
  });
63
- return {
61
+ const resolved = {
64
62
  url: (yield* listenScopedHttpServer({
65
63
  bindAddress,
66
64
  port: allocated.port,
@@ -69,6 +67,7 @@ function dashboard(opts = {}) {
69
67
  context: {
70
68
  state: control.state,
71
69
  publishCommand: control.publishCommand,
70
+ submitCommand: control.submitCommand,
72
71
  domain: control.domain,
73
72
  pluginDomain
74
73
  }
@@ -77,12 +76,13 @@ function dashboard(opts = {}) {
77
76
  })).url,
78
77
  localPort: allocated.port
79
78
  };
80
- }),
81
- capabilities: ({ value, runtime }) => [makeDashboardRoutable({
82
- app: runtime.identity.app,
83
- stack: runtime.identity.stack,
84
- port: value.localPort
85
- })]
79
+ ctx.endpoint(makeDashboardRoutable({
80
+ app: identity.app,
81
+ stack: identity.stack,
82
+ port: resolved.localPort
83
+ }));
84
+ return resolved;
85
+ })
86
86
  });
87
87
  }
88
88
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/dashboard/index.ts"],"sourcesContent":["// Dashboard plugin.\n//\n// Runs an in-process GraphQL server (Pothos schema + graphql-yoga) that\n// exposes the live projection, control commands, and the projection\n// subscription. Modeled on the `wallet` plugin: allocate a loopback port\n// from the port broker, start a scoped HTTP server, and contribute a\n// Routable so the router fronts it under `dashboard.<app>.<stack>.localhost`.\n//\n// Data access is pure control plane: the projection (`state`) and command\n// publisher (`publishCommand`) come from `ControlPlaneService`, handed to\n// the server as the GraphQL context.\n\nimport { Effect } from 'effect';\nimport { type AnyPlugin, definePlugin, resource } from '../../api/define-plugin.ts';\nimport { ContainerRuntimeService } from '../../runtime/docker/service.ts';\nimport type { ContainerRuntime } from '../../contracts/container-runtime.ts';\nimport type { StrategyRegistry } from '../../contracts/strategy-contributor.ts';\nimport { StrategyRegistryService } from '../../substrate/runtime/strategy-registry/index.ts';\nimport { ControlPlaneService } from '../../substrate/runtime/control-plane/service.ts';\nimport { IdentityContext } from '../../substrate/runtime/paths.ts';\nimport { PortBrokerService } from '../../substrate/runtime/port-broker/index.ts';\nimport { renderUrl, routedHostname } from '../../substrate/runtime/routed-url.ts';\nimport { listenScopedHttpServer } from '../../substrate/runtime/scoped-http-server.ts';\nimport { buildDashboardDomain } from './domain.ts';\nimport { resolveOriginPolicy } from './origin-policy.ts';\nimport {\n\tDASHBOARD_ENTRYPOINT_PORT,\n\tDASHBOARD_ROUTE_ROLE,\n\tmakeDashboardRoutable,\n} from './routable.ts';\nimport { makeDashboardListener } from './server.ts';\n\nexport interface DashboardOptions {\n\t/** Preferred loopback port; the broker forward-scans if it's busy. */\n\treadonly port?: number;\n\t/** NIC the HTTP server binds. Defaults to `'0.0.0.0'` because the router\n\t * runs in Docker and must reach this host process through the host-gateway\n\t * address on native Linux (a `127.0.0.1`-only listener is unreachable from\n\t * the host-gateway IP). The public dashboard URL stays router-fronted and\n\t * stack-scoped. */\n\treadonly bindAddress?: string;\n\t/** Extra origins merged on top of the dashboard's own router-fronted origin\n\t * for this stack (and the direct loopback origins). Useful for headless\n\t * test runners and custom dev hosts. The dashboard does NOT auto-allowlist\n\t * a bare `*.localhost` form — that is not stack-scoped, so a sibling stack\n\t * could drive the destructive control-plane mutations cross-origin. */\n\treadonly allowedOrigins?: ReadonlyArray<string>;\n\t// Note on log retention: the queryable cross-service log store the\n\t// dashboard reads is process-scoped and owned by the SUPERVISOR (not this\n\t// plugin), so its capacity is configured there. Tune it with the\n\t// `DEVSTACK_DASHBOARD_LOG_CAPACITY` (per-service record cap, default 2000)\n\t// and `DEVSTACK_DASHBOARD_LOG_MAX_SERVICES` (distinct-ring cap, default\n\t// 256) env vars, or programmatically via `SupervisorStartupOptions.logStore`.\n\t// See substrate/runtime/observability/log-store.ts.\n}\n\nexport interface DashboardValue {\n\t/** Loopback URL of the dashboard server. */\n\treadonly url: string;\n\t/** The allocated loopback port. */\n\treadonly localPort: number;\n}\n\nconst dashboardResource = resource<'dashboard', DashboardValue>('dashboard');\n// `0.0.0.0`: the router runs in Docker, so on native Linux it reaches this\n// host process through the Docker host-gateway address instead of host\n// loopback — a `127.0.0.1`-only listener is unreachable from that IP, which\n// produced a 502 from Traefik and the `RouteReadinessProbeFailed` WARN. The\n// published dashboard URL remains stack-scoped through the router. Mirrors\n// `WALLET_DEFAULT_BIND_ADDRESS`.\nconst DASHBOARD_DEFAULT_BIND = '0.0.0.0';\n\n/** Construct the devstack dashboard plugin. */\nexport function dashboard(opts: DashboardOptions = {}): AnyPlugin {\n\treturn definePlugin({\n\t\tid: dashboardResource.id,\n\t\trole: 'service',\n\t\tsection: 'service',\n\t\tstart: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst portBroker = yield* PortBrokerService;\n\t\t\t\tconst control = yield* ControlPlaneService;\n\t\t\t\tconst identity = yield* IdentityContext;\n\t\t\t\t// The ContainerRuntime drives the Postgres `psql` exec-probe.\n\t\t\t\t// It is in the base substrate plugin context in production\n\t\t\t\t// wiring; read it optionally so bare smoke-test paths that\n\t\t\t\t// don't layer it degrade `postgresStats` to unavailable\n\t\t\t\t// rather than failing acquisition.\n\t\t\t\tconst containerRuntimeOpt = yield* Effect.serviceOption(ContainerRuntimeService);\n\t\t\t\tconst containerRuntime: ContainerRuntime | null =\n\t\t\t\t\tcontainerRuntimeOpt._tag === 'Some' ? containerRuntimeOpt.value : null;\n\n\t\t\t\t// The scope-local strategy registry — the SAME registry the\n\t\t\t\t// boot-time account funding pass dispatches through. Drives the\n\t\t\t\t// Faucet panel's `fundableCoins` + `fundAccount` (SUI via the\n\t\t\t\t// faucet strategy, WAL/DEEP via the coin-specific funding\n\t\t\t\t// strategies). Read optionally so bare smoke-test paths that don't\n\t\t\t\t// layer it degrade the fund accessors to unavailable.\n\t\t\t\tconst strategyRegistryOpt = yield* Effect.serviceOption(StrategyRegistryService);\n\t\t\t\tconst strategyRegistry: StrategyRegistry | null =\n\t\t\t\t\tstrategyRegistryOpt._tag === 'Some' ? strategyRegistryOpt.value : null;\n\n\t\t\t\t// Plugin-name-aware shaping lives HERE (the plugin layer is\n\t\t\t\t// allowed to name plugins), built off the generic, name-blind\n\t\t\t\t// control-plane `resolvedValues` seam + the container runtime.\n\t\t\t\tconst pluginDomain = buildDashboardDomain({\n\t\t\t\t\tcontrol: control.domain,\n\t\t\t\t\tidentity,\n\t\t\t\t\tcontainerRuntime,\n\t\t\t\t\tstrategyRegistry,\n\t\t\t\t});\n\n\t\t\t\tconst bindAddress = opts.bindAddress ?? DASHBOARD_DEFAULT_BIND;\n\t\t\t\tconst allocated = yield* portBroker.allocate({\n\t\t\t\t\towner: 'dashboard',\n\t\t\t\t\twindowHint: { start: 39300, size: 1000 },\n\t\t\t\t\tprobeHost: bindAddress === '0.0.0.0' ? '0.0.0.0' : '127.0.0.1',\n\t\t\t\t\t...(opts.port === undefined ? {} : { preferredPort: opts.port }),\n\t\t\t\t});\n\n\t\t\t\t// Derive the dashboard's OWN router-fronted origin for this stack.\n\t\t\t\t// The bundled SPA is served same-origin from this hostname, so the\n\t\t\t\t// browser's `Origin` on `/graphql` is exactly this value — it MUST\n\t\t\t\t// be in the allowlist. Host = `<role:api>.<app>.<stack>.localhost`\n\t\t\t\t// (per `routedHostname`), port = the router entrypoint port (9810),\n\t\t\t\t// which is the port the browser actually uses, NOT the broker\n\t\t\t\t// loopback port. Router-derivation failure → `null` (allowlist still\n\t\t\t\t// includes the direct loopback + caller origins).\n\t\t\t\tconst routedDashboardOrigin = yield* routedHostname(identity, DASHBOARD_ROUTE_ROLE).pipe(\n\t\t\t\t\tEffect.map((hostname) =>\n\t\t\t\t\t\trenderUrl({ protocol: 'http', hostname, port: DASHBOARD_ENTRYPOINT_PORT }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.orElseSucceed(() => null),\n\t\t\t\t);\n\n\t\t\t\t// Direct loopback origins: when the dashboard is reached on the raw\n\t\t\t\t// broker port (host-loopback fallback / direct tooling) the SPA's\n\t\t\t\t// same-origin `Origin` is the loopback form. Both 127.0.0.1 and\n\t\t\t\t// localhost name the same listener; allow both for this stack's port.\n\t\t\t\tconst directOrigins = [\n\t\t\t\t\t`http://127.0.0.1:${allocated.port}`,\n\t\t\t\t\t`http://localhost:${allocated.port}`,\n\t\t\t\t];\n\n\t\t\t\tconst originPolicy = yield* resolveOriginPolicy({\n\t\t\t\t\tapp: identity.app,\n\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\troutedDashboardOrigin,\n\t\t\t\t\tdirectOrigins,\n\t\t\t\t\textraOrigins: opts.allowedOrigins ?? [],\n\t\t\t\t});\n\n\t\t\t\tconst server = yield* listenScopedHttpServer({\n\t\t\t\t\tbindAddress,\n\t\t\t\t\tport: allocated.port,\n\t\t\t\t\tlistener: makeDashboardListener({\n\t\t\t\t\t\toriginPolicy,\n\t\t\t\t\t\tcontext: {\n\t\t\t\t\t\t\tstate: control.state,\n\t\t\t\t\t\t\tpublishCommand: control.publishCommand,\n\t\t\t\t\t\t\tdomain: control.domain,\n\t\t\t\t\t\t\tpluginDomain,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tonListenError: (cause) =>\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`dashboard HTTP server listen failed on ${bindAddress}:${allocated.port}: ${String(cause)}`,\n\t\t\t\t\t\t),\n\t\t\t\t});\n\n\t\t\t\treturn { url: server.url, localPort: allocated.port } satisfies DashboardValue;\n\t\t\t}),\n\t\tcapabilities: ({ value, runtime }) => [\n\t\t\tmakeDashboardRoutable({\n\t\t\t\tapp: runtime.identity.app,\n\t\t\t\tstack: runtime.identity.stack,\n\t\t\t\tport: value.localPort,\n\t\t\t}),\n\t\t],\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA+DA,MAAM,oBAAoB,SAAsC,YAAY;AAO5E,MAAM,yBAAyB;;AAG/B,SAAgB,UAAU,OAAyB,EAAE,EAAa;AACjE,QAAO,aAAa;EACnB,IAAI,kBAAkB;EACtB,MAAM;EACN,SAAS;EACT,aACC,OAAO,IAAI,aAAa;GACvB,MAAM,aAAa,OAAO;GAC1B,MAAM,UAAU,OAAO;GACvB,MAAM,WAAW,OAAO;GAMxB,MAAM,sBAAsB,OAAO,OAAO,cAAc,wBAAwB;GAChF,MAAM,mBACL,oBAAoB,SAAS,SAAS,oBAAoB,QAAQ;GAQnE,MAAM,sBAAsB,OAAO,OAAO,cAAc,wBAAwB;GAChF,MAAM,mBACL,oBAAoB,SAAS,SAAS,oBAAoB,QAAQ;GAKnE,MAAM,eAAe,qBAAqB;IACzC,SAAS,QAAQ;IACjB;IACA;IACA;IACA,CAAC;GAEF,MAAM,cAAc,KAAK,eAAe;GACxC,MAAM,YAAY,OAAO,WAAW,SAAS;IAC5C,OAAO;IACP,YAAY;KAAE,OAAO;KAAO,MAAM;KAAM;IACxC,WAAW,gBAAgB,YAAY,YAAY;IACnD,GAAI,KAAK,SAAS,KAAA,IAAY,EAAE,GAAG,EAAE,eAAe,KAAK,MAAM;IAC/D,CAAC;GAUF,MAAM,wBAAwB,OAAO,eAAe,UAAA,MAA+B,CAAC,KACnF,OAAO,KAAK,aACX,UAAU;IAAE,UAAU;IAAQ;IAAU,MAAM;IAA2B,CAAC,CAC1E,EACD,OAAO,oBAAoB,KAAK,CAChC;GAMD,MAAM,gBAAgB,CACrB,oBAAoB,UAAU,QAC9B,oBAAoB,UAAU,OAC9B;GAED,MAAM,eAAe,OAAO,oBAAoB;IAC/C,KAAK,SAAS;IACd,OAAO,SAAS;IAChB;IACA;IACA,cAAc,KAAK,kBAAkB,EAAE;IACvC,CAAC;AAoBF,UAAO;IAAE,MAAK,OAlBQ,uBAAuB;KAC5C;KACA,MAAM,UAAU;KAChB,UAAU,sBAAsB;MAC/B;MACA,SAAS;OACR,OAAO,QAAQ;OACf,gBAAgB,QAAQ;OACxB,QAAQ,QAAQ;OAChB;OACA;MACD,CAAC;KACF,gBAAgB,0BACf,IAAI,MACH,0CAA0C,YAAY,GAAG,UAAU,KAAK,IAAI,OAAO,MAAM,GACzF;KACF,CAAC,EAEmB;IAAK,WAAW,UAAU;IAAM;IACpD;EACH,eAAe,EAAE,OAAO,cAAc,CACrC,sBAAsB;GACrB,KAAK,QAAQ,SAAS;GACtB,OAAO,QAAQ,SAAS;GACxB,MAAM,MAAM;GACZ,CAAC,CACF;EACD,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/dashboard/index.ts"],"sourcesContent":["// Dashboard plugin.\n//\n// Runs an in-process GraphQL server (Pothos schema + graphql-yoga) that\n// exposes the live projection, control commands, and the projection\n// subscription. Modeled on the `wallet` plugin: allocate a loopback port\n// from the port broker, start a scoped HTTP server, and contribute a\n// Routable so the router fronts it under `dashboard.<app>.<stack>.localhost`.\n//\n// Data access is pure control plane: the projection (`state`) and command\n// publisher (`publishCommand`) come from `ControlPlaneService`, handed to\n// the server as the GraphQL context.\n\nimport { Effect } from 'effect';\nimport { type AnyPlugin, definePlugin, resource } from '../../api/define-plugin.ts';\nimport { PluginContext } from '../../substrate/plugin-ctx.ts';\nimport type { StrategyRegistry } from '../../contracts/strategy-contributor.ts';\nimport { StrategyRegistryService } from '../../substrate/runtime/strategy-registry/index.ts';\nimport { ControlPlaneService } from '../../substrate/runtime/control-plane/service.ts';\nimport { IdentityContext } from '../../substrate/runtime/paths.ts';\nimport { PortBrokerService } from '../../substrate/runtime/port-broker/index.ts';\nimport { renderUrl, routedHostname } from '../../substrate/runtime/routed-url.ts';\nimport { listenScopedHttpServer } from '../../substrate/runtime/scoped-http-server.ts';\nimport { buildDashboardDomain } from './domain.ts';\nimport { resolveOriginPolicy } from './origin-policy.ts';\nimport {\n\tDASHBOARD_ENTRYPOINT_PORT,\n\tDASHBOARD_ROUTE_ROLE,\n\tmakeDashboardRoutable,\n} from './routable.ts';\nimport { makeDashboardListener } from './server.ts';\n\nexport interface DashboardOptions {\n\t/** Preferred loopback port; the broker forward-scans if it's busy. */\n\treadonly port?: number;\n\t/** NIC the HTTP server binds. Defaults to `'0.0.0.0'` because the router\n\t * runs in Docker and must reach this host process through the host-gateway\n\t * address on native Linux (a `127.0.0.1`-only listener is unreachable from\n\t * the host-gateway IP). The public dashboard URL stays router-fronted and\n\t * stack-scoped. */\n\treadonly bindAddress?: string;\n\t/** Extra origins merged on top of the dashboard's own router-fronted origin\n\t * for this stack (and the direct loopback origins). Useful for headless\n\t * test runners and custom dev hosts. The dashboard does NOT auto-allowlist\n\t * a bare `*.localhost` form — that is not stack-scoped, so a sibling stack\n\t * could drive the destructive control-plane mutations cross-origin. */\n\treadonly allowedOrigins?: ReadonlyArray<string>;\n\t// Note on log retention: the queryable cross-service log store the\n\t// dashboard reads is process-scoped and owned by the SUPERVISOR (not this\n\t// plugin), so its capacity is configured there. Tune it with the\n\t// `DEVSTACK_DASHBOARD_LOG_CAPACITY` (per-service record cap, default 2000)\n\t// and `DEVSTACK_DASHBOARD_LOG_MAX_SERVICES` (distinct-ring cap, default\n\t// 256) env vars, or programmatically via `SupervisorStartupOptions.logStore`.\n\t// See substrate/runtime/observability/log-store.ts.\n}\n\nexport interface DashboardValue {\n\t/** Loopback URL of the dashboard server. */\n\treadonly url: string;\n\t/** The allocated loopback port. */\n\treadonly localPort: number;\n}\n\nconst dashboardResource = resource<'dashboard', DashboardValue>('dashboard');\n// `0.0.0.0`: the router runs in Docker, so on native Linux it reaches this\n// host process through the Docker host-gateway address instead of host\n// loopback — a `127.0.0.1`-only listener is unreachable from that IP, which\n// produced a 502 from Traefik and the `RouteReadinessProbeFailed` WARN. The\n// published dashboard URL remains stack-scoped through the router. Mirrors\n// `WALLET_DEFAULT_BIND_ADDRESS`.\nconst DASHBOARD_DEFAULT_BIND = '0.0.0.0';\n\n/** Construct the devstack dashboard plugin. */\nexport function dashboard(opts: DashboardOptions = {}): AnyPlugin {\n\treturn definePlugin({\n\t\tid: dashboardResource.id,\n\t\trole: 'service',\n\t\tsection: 'service',\n\t\t// Operator transport: a live snapshot-restore re-acquire must leave\n\t\t// this plugin running, or a dashboard-initiated restore would tear\n\t\t// down the very HTTP connection it's answering on (502). It holds no\n\t\t// restorable chain state, so staying live is safe.\n\t\tkeepAliveOnRestore: true,\n\t\tstart: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst ctx = yield* PluginContext;\n\t\t\t\tconst portBroker = yield* PortBrokerService;\n\t\t\t\tconst control = yield* ControlPlaneService;\n\t\t\t\tconst identity = yield* IdentityContext;\n\n\t\t\t\t// The scope-local strategy registry — the SAME registry the\n\t\t\t\t// boot-time account funding pass dispatches through. Drives the\n\t\t\t\t// Faucet panel's `fundableCoins` + `fundAccount` (SUI via the\n\t\t\t\t// faucet strategy, WAL/DEEP via the coin-specific funding\n\t\t\t\t// strategies). Read optionally so bare smoke-test paths that don't\n\t\t\t\t// layer it degrade the fund accessors to unavailable.\n\t\t\t\tconst strategyRegistryOpt = yield* Effect.serviceOption(StrategyRegistryService);\n\t\t\t\tconst strategyRegistry: StrategyRegistry | null =\n\t\t\t\t\tstrategyRegistryOpt._tag === 'Some' ? strategyRegistryOpt.value : null;\n\n\t\t\t\t// Plugin-name-aware shaping lives HERE (the plugin layer is\n\t\t\t\t// allowed to name plugins), built off the generic, name-blind\n\t\t\t\t// control-plane `resolvedValues` seam.\n\t\t\t\tconst pluginDomain = buildDashboardDomain({\n\t\t\t\t\tcontrol: control.domain,\n\t\t\t\t\tstrategyRegistry,\n\t\t\t\t});\n\n\t\t\t\tconst bindAddress = opts.bindAddress ?? DASHBOARD_DEFAULT_BIND;\n\t\t\t\tconst allocated = yield* portBroker.allocate({\n\t\t\t\t\towner: 'dashboard',\n\t\t\t\t\twindowHint: { start: 39300, size: 1000 },\n\t\t\t\t\tprobeHost: bindAddress === '0.0.0.0' ? '0.0.0.0' : '127.0.0.1',\n\t\t\t\t\t...(opts.port === undefined ? {} : { preferredPort: opts.port }),\n\t\t\t\t});\n\n\t\t\t\t// Derive the dashboard's OWN router-fronted origin for this stack.\n\t\t\t\t// The bundled SPA is served same-origin from this hostname, so the\n\t\t\t\t// browser's `Origin` on `/graphql` is exactly this value — it MUST\n\t\t\t\t// be in the allowlist. Host = `<role:api>.<app>.<stack>.localhost`\n\t\t\t\t// (per `routedHostname`), port = the router entrypoint port (9810),\n\t\t\t\t// which is the port the browser actually uses, NOT the broker\n\t\t\t\t// loopback port. Router-derivation failure → `null` (allowlist still\n\t\t\t\t// includes the direct loopback + caller origins).\n\t\t\t\tconst routedDashboardOrigin = yield* routedHostname(identity, DASHBOARD_ROUTE_ROLE).pipe(\n\t\t\t\t\tEffect.map((hostname) =>\n\t\t\t\t\t\trenderUrl({ protocol: 'http', hostname, port: DASHBOARD_ENTRYPOINT_PORT }),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.orElseSucceed(() => null),\n\t\t\t\t);\n\n\t\t\t\t// Direct loopback origins: when the dashboard is reached on the raw\n\t\t\t\t// broker port (host-loopback fallback / direct tooling) the SPA's\n\t\t\t\t// same-origin `Origin` is the loopback form. Both 127.0.0.1 and\n\t\t\t\t// localhost name the same listener; allow both for this stack's port.\n\t\t\t\tconst directOrigins = [\n\t\t\t\t\t`http://127.0.0.1:${allocated.port}`,\n\t\t\t\t\t`http://localhost:${allocated.port}`,\n\t\t\t\t];\n\n\t\t\t\tconst originPolicy = yield* resolveOriginPolicy({\n\t\t\t\t\tapp: identity.app,\n\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\troutedDashboardOrigin,\n\t\t\t\t\tdirectOrigins,\n\t\t\t\t\textraOrigins: opts.allowedOrigins ?? [],\n\t\t\t\t});\n\n\t\t\t\tconst server = yield* listenScopedHttpServer({\n\t\t\t\t\tbindAddress,\n\t\t\t\t\tport: allocated.port,\n\t\t\t\t\tlistener: makeDashboardListener({\n\t\t\t\t\t\toriginPolicy,\n\t\t\t\t\t\tcontext: {\n\t\t\t\t\t\t\tstate: control.state,\n\t\t\t\t\t\t\tpublishCommand: control.publishCommand,\n\t\t\t\t\t\t\tsubmitCommand: control.submitCommand,\n\t\t\t\t\t\t\tdomain: control.domain,\n\t\t\t\t\t\t\tpluginDomain,\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t\tonListenError: (cause) =>\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`dashboard HTTP server listen failed on ${bindAddress}:${allocated.port}: ${String(cause)}`,\n\t\t\t\t\t\t),\n\t\t\t\t});\n\n\t\t\t\tconst resolved = { url: server.url, localPort: allocated.port } satisfies DashboardValue;\n\n\t\t\t\t// Emit the Routable via the ctx verb before returning.\n\t\t\t\t// `value.localPort` is this resolved `localPort`;\n\t\t\t\t// `runtime.identity.app`/`.stack` is the `identity` this\n\t\t\t\t// `start` already holds from `IdentityContext`.\n\t\t\t\tctx.endpoint(\n\t\t\t\t\tmakeDashboardRoutable({\n\t\t\t\t\t\tapp: identity.app,\n\t\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\t\tport: resolved.localPort,\n\t\t\t\t\t}),\n\t\t\t\t);\n\n\t\t\t\treturn resolved;\n\t\t\t}),\n\t});\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA8DA,MAAM,oBAAoB,SAAsC,WAAW;AAO3E,MAAM,yBAAyB;;AAG/B,SAAgB,UAAU,OAAyB,CAAC,GAAc;CACjE,OAAO,aAAa;EACnB,IAAI,kBAAkB;EACtB,MAAM;EACN,SAAS;EAKT,oBAAoB;EACpB,aACC,OAAO,IAAI,aAAa;GACvB,MAAM,MAAM,OAAO;GACnB,MAAM,aAAa,OAAO;GAC1B,MAAM,UAAU,OAAO;GACvB,MAAM,WAAW,OAAO;GAQxB,MAAM,sBAAsB,OAAO,OAAO,cAAc,uBAAuB;GAC/E,MAAM,mBACL,oBAAoB,SAAS,SAAS,oBAAoB,QAAQ;GAKnE,MAAM,eAAe,qBAAqB;IACzC,SAAS,QAAQ;IACjB;GACD,CAAC;GAED,MAAM,cAAc,KAAK,eAAe;GACxC,MAAM,YAAY,OAAO,WAAW,SAAS;IAC5C,OAAO;IACP,YAAY;KAAE,OAAO;KAAO,MAAM;IAAK;IACvC,WAAW,gBAAgB,YAAY,YAAY;IACnD,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,KAAK,KAAK;GAC/D,CAAC;GAUD,MAAM,wBAAwB,OAAO,eAAe,UAAA,KAA8B,CAAC,CAAC,KACnF,OAAO,KAAK,aACX,UAAU;IAAE,UAAU;IAAQ;IAAU,MAAM;GAA0B,CAAC,CAC1E,GACA,OAAO,oBAAoB,IAAI,CAChC;GAMA,MAAM,gBAAgB,CACrB,oBAAoB,UAAU,QAC9B,oBAAoB,UAAU,MAC/B;GAEA,MAAM,eAAe,OAAO,oBAAoB;IAC/C,KAAK,SAAS;IACd,OAAO,SAAS;IAChB;IACA;IACA,cAAc,KAAK,kBAAkB,CAAC;GACvC,CAAC;GAqBD,MAAM,WAAW;IAAE,MAAK,OAnBF,uBAAuB;KAC5C;KACA,MAAM,UAAU;KAChB,UAAU,sBAAsB;MAC/B;MACA,SAAS;OACR,OAAO,QAAQ;OACf,gBAAgB,QAAQ;OACxB,eAAe,QAAQ;OACvB,QAAQ,QAAQ;OAChB;MACD;KACD,CAAC;KACD,gBAAgB,0BACf,IAAI,MACH,0CAA0C,YAAY,GAAG,UAAU,KAAK,IAAI,OAAO,KAAK,GACzF;IACF,CAAC,EAAA,CAE8B;IAAK,WAAW,UAAU;GAAK;GAM9D,IAAI,SACH,sBAAsB;IACrB,KAAK,SAAS;IACd,OAAO,SAAS;IAChB,MAAM,SAAS;GAChB,CAAC,CACF;GAEA,OAAO;EACR,CAAC;CACH,CAAC;AACF"}
@@ -1,4 +1,4 @@
1
- import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
1
+ import { LogAttr } from "../../substrate/runtime/observability/log-attrs.mjs";
2
2
  import { Effect } from "effect";
3
3
  //#region src/plugins/dashboard/origin-policy.ts
4
4
  /**
@@ -21,8 +21,8 @@ const resolveOriginPolicy = (inputs) => Effect.gen(function* () {
21
21
  for (const o of inputs.directOrigins) allowed.add(o);
22
22
  for (const o of inputs.extraOrigins) allowed.add(o);
23
23
  if (allowed.size === 0) yield* Effect.logWarning("dashboard origin allowlist is empty").pipe(Effect.annotateLogs({
24
- [SpanAttr.app]: inputs.app,
25
- [SpanAttr.stack]: inputs.stack
24
+ [LogAttr.app]: inputs.app,
25
+ [LogAttr.stack]: inputs.stack
26
26
  }));
27
27
  return { allowed };
28
28
  });
@@ -1 +1 @@
1
- {"version":3,"file":"origin-policy.mjs","names":[],"sources":["../../../src/plugins/dashboard/origin-policy.ts"],"sourcesContent":["// Dashboard plugin — CORS / origin allowlist policy.\n//\n// This MIRRORS the wallet's `plugins/wallet/origin-policy.ts` pattern\n// (stack-scoped allowlist, `resolveOriginPolicy` / `checkOrigin`) rather\n// than importing it, to avoid coupling dashboard→wallet. The two policies\n// are intentionally small and self-contained; the wallet copy carries\n// bearer-specific history that does not apply here.\n//\n// The allowed set is built from real, substrate-wired sources:\n//\n// - the dashboard's OWN router-fronted origin for THIS stack\n// (`routedDashboardOrigin`) — the SPA is served same-origin from this\n// hostname, so the browser's `Origin` on `/graphql` IS this value;\n// - the direct loopback origin(s) the bundled SPA might be loaded from\n// when reached on the raw broker port (`directOrigins`);\n// - any explicit caller-supplied origins (`extraOrigins` →\n// `DashboardOptions.allowedOrigins`).\n//\n// We deliberately do NOT auto-allow a bare `*.localhost` / `localhost:<port>`\n// form: `localhost` is not stack-scoped, so a sibling stack on the same\n// port could drive the destructive control-plane mutations cross-origin.\n\nimport { Effect } from 'effect';\n\nimport { SpanAttr } from '../../substrate/runtime/observability/spans.ts';\n\n/** Result of resolving the origin allowlist at boot. Captured into the\n * server closure so per-request checks are pure string comparison. */\nexport interface OriginPolicy {\n\treadonly allowed: ReadonlySet<string>;\n}\n\n/** Per-stack inputs the policy resolver needs. Supplied by the plugin at\n * start time (identity + routed-url derivation); this module does not\n * reach into the broker or router itself. */\nexport interface OriginPolicyInputs {\n\treadonly app: string;\n\treadonly stack: string;\n\t/** The dashboard's router-fronted origin for this stack\n\t * (`http://api.<app>.<stack>.localhost:<entrypoint-port>`). `null`\n\t * only in tests that bypass the router derivation. */\n\treadonly routedDashboardOrigin: string | null;\n\t/** Direct loopback origins the SPA may be loaded from when reached on\n\t * the raw broker port (host-loopback fallback / direct tooling). */\n\treadonly directOrigins: ReadonlyArray<string>;\n\t/** Explicit caller-supplied origins (`DashboardOptions.allowedOrigins`). */\n\treadonly extraOrigins: ReadonlyArray<string>;\n}\n\n/**\n * Resolve the per-stack origin allowlist.\n *\n * - Always allowlisted: the dashboard's router-fronted origin for this\n * stack (`routedDashboardOrigin`), when the router derivation produced\n * one — this is the same-origin the bundled SPA loads from.\n * - Always allowlisted: the direct loopback origins + any explicit\n * caller-supplied `extraOrigins`.\n *\n * Empty-allowlist policy: allowed. The dashboard boots normally; with an\n * empty allowlist the per-request gate refuses every cross-origin request\n * (every Origin lands in `forbidden`). A `logWarning` surfaces the\n * configuration for operator visibility.\n */\nexport const resolveOriginPolicy = (inputs: OriginPolicyInputs): Effect.Effect<OriginPolicy> =>\n\tEffect.gen(function* () {\n\t\tconst allowed = new Set<string>();\n\n\t\tif (inputs.routedDashboardOrigin !== null) {\n\t\t\tallowed.add(inputs.routedDashboardOrigin);\n\t\t}\n\t\tfor (const o of inputs.directOrigins) {\n\t\t\tallowed.add(o);\n\t\t}\n\t\tfor (const o of inputs.extraOrigins) {\n\t\t\tallowed.add(o);\n\t\t}\n\n\t\tif (allowed.size === 0) {\n\t\t\tyield* Effect.logWarning('dashboard origin allowlist is empty').pipe(\n\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t[SpanAttr.app]: inputs.app,\n\t\t\t\t\t[SpanAttr.stack]: inputs.stack,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn { allowed } satisfies OriginPolicy;\n\t});\n\n/** Per-request origin gate. Returns `'missing'` for absent Origin,\n * `'forbidden'` for an Origin not in the allowlist, `'ok'` for accepted.\n *\n * `'missing'` is its OWN shape: a request with no Origin (server-side\n * tooling, the route-readiness probe, curl) is NOT a cross-origin browser\n * request, so CORS does not govern it — the caller emits a normal response\n * with no `Access-Control-Allow-Origin` header. */\nexport type OriginCheckResult = 'missing' | 'forbidden' | 'ok';\n\nexport const checkOrigin = (\n\tpolicy: OriginPolicy,\n\theaderValue: string | null | undefined,\n): OriginCheckResult => {\n\tif (headerValue === undefined || headerValue === null || headerValue.length === 0) {\n\t\treturn 'missing';\n\t}\n\treturn policy.allowed.has(headerValue) ? 'ok' : 'forbidden';\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA+DA,MAAa,uBAAuB,WACnC,OAAO,IAAI,aAAa;CACvB,MAAM,0BAAU,IAAI,KAAa;AAEjC,KAAI,OAAO,0BAA0B,KACpC,SAAQ,IAAI,OAAO,sBAAsB;AAE1C,MAAK,MAAM,KAAK,OAAO,cACtB,SAAQ,IAAI,EAAE;AAEf,MAAK,MAAM,KAAK,OAAO,aACtB,SAAQ,IAAI,EAAE;AAGf,KAAI,QAAQ,SAAS,EACpB,QAAO,OAAO,WAAW,sCAAsC,CAAC,KAC/D,OAAO,aAAa;GAClB,SAAS,MAAM,OAAO;GACtB,SAAS,QAAQ,OAAO;EACzB,CAAC,CACF;AAGF,QAAO,EAAE,SAAS;EACjB;AAWH,MAAa,eACZ,QACA,gBACuB;AACvB,KAAI,gBAAgB,KAAA,KAAa,gBAAgB,QAAQ,YAAY,WAAW,EAC/E,QAAO;AAER,QAAO,OAAO,QAAQ,IAAI,YAAY,GAAG,OAAO"}
1
+ {"version":3,"file":"origin-policy.mjs","names":[],"sources":["../../../src/plugins/dashboard/origin-policy.ts"],"sourcesContent":["// Dashboard plugin — CORS / origin allowlist policy.\n//\n// This MIRRORS the wallet's `plugins/wallet/origin-policy.ts` pattern\n// (stack-scoped allowlist, `resolveOriginPolicy` / `checkOrigin`) rather\n// than importing it, to avoid coupling dashboard→wallet. The two policies\n// are intentionally small and self-contained; the wallet copy carries\n// bearer-specific history that does not apply here.\n//\n// The allowed set is built from real, substrate-wired sources:\n//\n// - the dashboard's OWN router-fronted origin for THIS stack\n// (`routedDashboardOrigin`) — the SPA is served same-origin from this\n// hostname, so the browser's `Origin` on `/graphql` IS this value;\n// - the direct loopback origin(s) the bundled SPA might be loaded from\n// when reached on the raw broker port (`directOrigins`);\n// - any explicit caller-supplied origins (`extraOrigins` →\n// `DashboardOptions.allowedOrigins`).\n//\n// We deliberately do NOT auto-allow a bare `*.localhost` / `localhost:<port>`\n// form: `localhost` is not stack-scoped, so a sibling stack on the same\n// port could drive the destructive control-plane mutations cross-origin.\n\nimport { Effect } from 'effect';\n\nimport { LogAttr } from '../../substrate/runtime/observability/log-attrs.ts';\n\n/** Result of resolving the origin allowlist at boot. Captured into the\n * server closure so per-request checks are pure string comparison. */\nexport interface OriginPolicy {\n\treadonly allowed: ReadonlySet<string>;\n}\n\n/** Per-stack inputs the policy resolver needs. Supplied by the plugin at\n * start time (identity + routed-url derivation); this module does not\n * reach into the broker or router itself. */\nexport interface OriginPolicyInputs {\n\treadonly app: string;\n\treadonly stack: string;\n\t/** The dashboard's router-fronted origin for this stack\n\t * (`http://api.<app>.<stack>.localhost:<entrypoint-port>`). `null`\n\t * only in tests that bypass the router derivation. */\n\treadonly routedDashboardOrigin: string | null;\n\t/** Direct loopback origins the SPA may be loaded from when reached on\n\t * the raw broker port (host-loopback fallback / direct tooling). */\n\treadonly directOrigins: ReadonlyArray<string>;\n\t/** Explicit caller-supplied origins (`DashboardOptions.allowedOrigins`). */\n\treadonly extraOrigins: ReadonlyArray<string>;\n}\n\n/**\n * Resolve the per-stack origin allowlist.\n *\n * - Always allowlisted: the dashboard's router-fronted origin for this\n * stack (`routedDashboardOrigin`), when the router derivation produced\n * one — this is the same-origin the bundled SPA loads from.\n * - Always allowlisted: the direct loopback origins + any explicit\n * caller-supplied `extraOrigins`.\n *\n * Empty-allowlist policy: allowed. The dashboard boots normally; with an\n * empty allowlist the per-request gate refuses every cross-origin request\n * (every Origin lands in `forbidden`). A `logWarning` surfaces the\n * configuration for operator visibility.\n */\nexport const resolveOriginPolicy = (inputs: OriginPolicyInputs): Effect.Effect<OriginPolicy> =>\n\tEffect.gen(function* () {\n\t\tconst allowed = new Set<string>();\n\n\t\tif (inputs.routedDashboardOrigin !== null) {\n\t\t\tallowed.add(inputs.routedDashboardOrigin);\n\t\t}\n\t\tfor (const o of inputs.directOrigins) {\n\t\t\tallowed.add(o);\n\t\t}\n\t\tfor (const o of inputs.extraOrigins) {\n\t\t\tallowed.add(o);\n\t\t}\n\n\t\tif (allowed.size === 0) {\n\t\t\tyield* Effect.logWarning('dashboard origin allowlist is empty').pipe(\n\t\t\t\tEffect.annotateLogs({\n\t\t\t\t\t[LogAttr.app]: inputs.app,\n\t\t\t\t\t[LogAttr.stack]: inputs.stack,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\treturn { allowed } satisfies OriginPolicy;\n\t});\n\n/** Per-request origin gate. Returns `'missing'` for absent Origin,\n * `'forbidden'` for an Origin not in the allowlist, `'ok'` for accepted.\n *\n * `'missing'` is its OWN shape: a request with no Origin (server-side\n * tooling, the route-readiness probe, curl) is NOT a cross-origin browser\n * request, so CORS does not govern it — the caller emits a normal response\n * with no `Access-Control-Allow-Origin` header. */\nexport type OriginCheckResult = 'missing' | 'forbidden' | 'ok';\n\nexport const checkOrigin = (\n\tpolicy: OriginPolicy,\n\theaderValue: string | null | undefined,\n): OriginCheckResult => {\n\tif (headerValue === undefined || headerValue === null || headerValue.length === 0) {\n\t\treturn 'missing';\n\t}\n\treturn policy.allowed.has(headerValue) ? 'ok' : 'forbidden';\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA+DA,MAAa,uBAAuB,WACnC,OAAO,IAAI,aAAa;CACvB,MAAM,0BAAU,IAAI,IAAY;CAEhC,IAAI,OAAO,0BAA0B,MACpC,QAAQ,IAAI,OAAO,qBAAqB;CAEzC,KAAK,MAAM,KAAK,OAAO,eACtB,QAAQ,IAAI,CAAC;CAEd,KAAK,MAAM,KAAK,OAAO,cACtB,QAAQ,IAAI,CAAC;CAGd,IAAI,QAAQ,SAAS,GACpB,OAAO,OAAO,WAAW,qCAAqC,CAAC,CAAC,KAC/D,OAAO,aAAa;GAClB,QAAQ,MAAM,OAAO;GACrB,QAAQ,QAAQ,OAAO;CACzB,CAAC,CACF;CAGD,OAAO,EAAE,QAAQ;AAClB,CAAC;AAWF,MAAa,eACZ,QACA,gBACuB;CACvB,IAAI,gBAAgB,KAAA,KAAa,gBAAgB,QAAQ,YAAY,WAAW,GAC/E,OAAO;CAER,OAAO,OAAO,QAAQ,IAAI,WAAW,IAAI,OAAO;AACjD"}
@@ -1 +1 @@
1
- {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/dashboard/routable.ts"],"sourcesContent":["// Dashboard plugin — Routable contribution.\n//\n// The dashboard's HTTP/GraphQL server is a host process (not a docker\n// container) listening on a loopback port the substrate's port broker\n// hands us. The router (Traefik) fronts the loopback port under a\n// stack-scoped hostname like `dashboard.<app>.localhost:<router-port>`.\n//\n// Mirrors `plugins/wallet/routable.ts`. The entrypoint declared here must\n// be aggregated into `plugins/router-entrypoints.ts` so Traefik opens the\n// listener port.\n\nimport type { EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\nexport const DASHBOARD_ENDPOINT_NAME = 'dashboard';\nexport const DASHBOARD_ROUTE_ROLE = 'api' as const;\nexport const DASHBOARD_ENTRYPOINT_PORT = 9810;\n\nexport const DASHBOARD_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{ name: DASHBOARD_ENDPOINT_NAME, port: DASHBOARD_ENTRYPOINT_PORT, protocol: 'http' },\n];\n\n/** Construct the Routable decl for the stack-scoped dashboard endpoint. */\nexport const makeDashboardRoutable = (parts: {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly port: number;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: DASHBOARD_ENDPOINT_NAME,\n\tdispatchId: {\n\t\tserviceKey: `dashboard.${parts.app}.${parts.stack}`,\n\t\trole: DASHBOARD_ROUTE_ROLE,\n\t},\n\tupstream: { type: 'host-loopback', port: parts.port },\n\t// CORS is owned by the dashboard server itself (`server.ts` `corsOptionsFor`\n\t// + `origin-policy.ts`): a STACK-SCOPED origin allowlist (this dashboard's\n\t// own router-fronted origin + direct loopback origins + caller-supplied\n\t// `allowedOrigins`) that guards the destructive control-plane mutations and\n\t// closes the cross-stack `*.localhost` hole. We deliberately do NOT attach\n\t// the shared `devstack-cors` Traefik middleware here — that middleware is\n\t// permissive (`*` allow-origin, allow-credentials) and, when the dashboard\n\t// is reached via the router hostname, would overwrite the server's allowlist\n\t// headers and re-open the cross-origin hole. `false` keeps the in-process\n\t// policy authoritative on both the direct loopback port and the router-\n\t// fronted hostname.\n\t//\n\t// The upstream host process binds `0.0.0.0` (see `DASHBOARD_DEFAULT_BIND` in\n\t// `index.ts`) so the Docker-hosted router reaches it via the host-gateway IP\n\t// on native Linux — a `127.0.0.1`-only listener would 502 and trip the route\n\t// readiness probe.\n\tcors: false,\n\twireProtocol: 'http',\n});\n"],"mappings":";AAaA,MAAa,0BAA0B;AAEvC,MAAa,4BAA4B;AAEzC,MAAa,wBAAuD,CACnE;CAAE,MAAM;CAAyB,MAAM;CAA2B,UAAU;CAAQ,CACpF;;AAGD,MAAa,yBAAyB,WAIjB;CACpB,MAAM;CACN,cAAc;CACd,YAAY;EACX,YAAY,aAAa,MAAM,IAAI,GAAG,MAAM;EAC5C,MAAA;EACA;CACD,UAAU;EAAE,MAAM;EAAiB,MAAM,MAAM;EAAM;CAiBrD,MAAM;CACN,cAAc;CACd"}
1
+ {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/dashboard/routable.ts"],"sourcesContent":["// Dashboard plugin — Routable contribution.\n//\n// The dashboard's HTTP/GraphQL server is a host process (not a docker\n// container) listening on a loopback port the substrate's port broker\n// hands us. The router (Traefik) fronts the loopback port under a\n// stack-scoped hostname like `dashboard.<app>.localhost:<router-port>`.\n//\n// Mirrors `plugins/wallet/routable.ts`. The entrypoint declared here must\n// be aggregated into `plugins/router-entrypoints.ts` so Traefik opens the\n// listener port.\n\nimport type { EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\nexport const DASHBOARD_ENDPOINT_NAME = 'dashboard';\nexport const DASHBOARD_ROUTE_ROLE = 'api' as const;\nexport const DASHBOARD_ENTRYPOINT_PORT = 9810;\n\nexport const DASHBOARD_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{ name: DASHBOARD_ENDPOINT_NAME, port: DASHBOARD_ENTRYPOINT_PORT, protocol: 'http' },\n];\n\n/** Construct the Routable decl for the stack-scoped dashboard endpoint. */\nexport const makeDashboardRoutable = (parts: {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly port: number;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: DASHBOARD_ENDPOINT_NAME,\n\tdispatchId: {\n\t\tserviceKey: `dashboard.${parts.app}.${parts.stack}`,\n\t\trole: DASHBOARD_ROUTE_ROLE,\n\t},\n\tupstream: { type: 'host-loopback', port: parts.port },\n\t// CORS is owned by the dashboard server itself (`server.ts` `corsOptionsFor`\n\t// + `origin-policy.ts`): a STACK-SCOPED origin allowlist (this dashboard's\n\t// own router-fronted origin + direct loopback origins + caller-supplied\n\t// `allowedOrigins`) that guards the destructive control-plane mutations and\n\t// closes the cross-stack `*.localhost` hole. We deliberately do NOT attach\n\t// the shared `devstack-cors` Traefik middleware here — that middleware is\n\t// permissive (`*` allow-origin, allow-credentials) and, when the dashboard\n\t// is reached via the router hostname, would overwrite the server's allowlist\n\t// headers and re-open the cross-origin hole. `false` keeps the in-process\n\t// policy authoritative on both the direct loopback port and the router-\n\t// fronted hostname.\n\t//\n\t// The upstream host process binds `0.0.0.0` (see `DASHBOARD_DEFAULT_BIND` in\n\t// `index.ts`) so the Docker-hosted router reaches it via the host-gateway IP\n\t// on native Linux — a `127.0.0.1`-only listener would 502 and trip the route\n\t// readiness probe.\n\tcors: false,\n\twireProtocol: 'http',\n});\n"],"mappings":";AAaA,MAAa,0BAA0B;AAEvC,MAAa,4BAA4B;AAEzC,MAAa,wBAAuD,CACnE;CAAE,MAAM;CAAyB,MAAM;CAA2B,UAAU;AAAO,CACpF;;AAGA,MAAa,yBAAyB,WAIjB;CACpB,MAAM;CACN,cAAc;CACd,YAAY;EACX,YAAY,aAAa,MAAM,IAAI,GAAG,MAAM;EAC5C,MAAA;CACD;CACA,UAAU;EAAE,MAAM;EAAiB,MAAM,MAAM;CAAK;CAiBpD,MAAM;CACN,cAAc;AACf"}
@@ -1 +1 @@
1
- {"version":3,"file":"builder.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/builder.ts"],"sourcesContent":["// Dashboard Pothos `SchemaBuilder` — the single module-level instance.\n//\n// One typed schema covers the control plane: the live projection (`state`),\n// relay node/connection access over the snapshot arrays, control mutations,\n// and the projection subscription. The builder is parameterized with the\n// relay, simple-objects, and with-input plugins (Pothos v4 defaults).\n//\n// Dependencies (the `state` ref + a `publishCommand`) are supplied per\n// request through the GraphQL context (`DashboardContext`), so the schema is\n// a single module-level value with no per-instance closure state. Resolvers\n// read deps from the 3rd resolver argument.\n\nimport SchemaBuilder from '@pothos/core';\nimport RelayPlugin from '@pothos/plugin-relay';\nimport SimpleObjectsPlugin from '@pothos/plugin-simple-objects';\nimport WithInputPlugin from '@pothos/plugin-with-input';\nimport type { Effect, SubscriptionRef } from 'effect';\nimport type { EngineCommand } from '../../../substrate/events.ts';\nimport type { SubscribableState } from '../../../substrate/projection.ts';\nimport type { ControlPlaneDomain } from '../../../substrate/runtime/control-plane/service.ts';\nimport type { DashboardDomain } from '../domain.ts';\n\n/** Per-request GraphQL context for the dashboard control plane. Resolvers\n * read the live projection ref, the command publisher, and the\n * plugin-domain accessor surfaces from here (3rd resolver arg), so the\n * schema carries no closed-over state. */\nexport interface DashboardContext {\n\treadonly state: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly publishCommand: (command: EngineCommand) => Effect.Effect<void>;\n\t/** Generic, name-blind control-plane accessors: snapshot catalog +\n\t * restore/delete, the observability rings, and the resolved-values\n\t * seam. (Plugin-name-aware shaping lives in `pluginDomain`.) */\n\treadonly domain: ControlPlaneDomain;\n\t/** Plugin-name-aware accessors the dashboard plugin shapes from the\n\t * generic control-plane `resolvedValues`: fork-vs-local mode,\n\t * deepbook/seal/coin capability ids, postgres wire-protocol stats,\n\t * and the coin mint action. */\n\treadonly pluginDomain: DashboardDomain;\n}\n\ninterface SchemaTypes {\n\tContext: DashboardContext;\n\t// Output fields are non-nullable unless a resolver opts in with\n\t// `nullable: true` — the projection always resolves a concrete value.\n\tDefaultFieldNullability: false;\n}\n\n/** The single module-level builder. Object types, enums, and root types are\n * defined against this instance across the sibling `schema/*` modules; the\n * built schema is `dashboardSchema` (see `../schema.ts`). */\nexport const builder = new SchemaBuilder<SchemaTypes>({\n\tplugins: [SimpleObjectsPlugin, RelayPlugin, WithInputPlugin],\n\trelay: {},\n\tdefaultFieldNullability: false,\n});\n"],"mappings":";;;;;;;;AAkDA,MAAa,UAAU,IAAI,cAA2B;CACrD,SAAS;EAAC;EAAqB;EAAa;EAAgB;CAC5D,OAAO,EAAE;CACT,yBAAyB;CACzB,CAAC"}
1
+ {"version":3,"file":"builder.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/builder.ts"],"sourcesContent":["// Dashboard Pothos `SchemaBuilder` — the single module-level instance.\n//\n// One typed schema covers the control plane: the live projection (`state`),\n// relay node/connection access over the snapshot arrays, control mutations,\n// and the projection subscription. The builder is parameterized with the\n// relay, simple-objects, and with-input plugins (Pothos v4 defaults).\n//\n// Dependencies (the `state` ref + a `publishCommand`) are supplied per\n// request through the GraphQL context (`DashboardContext`), so the schema is\n// a single module-level value with no per-instance closure state. Resolvers\n// read deps from the 3rd resolver argument.\n\nimport SchemaBuilder from '@pothos/core';\nimport RelayPlugin from '@pothos/plugin-relay';\nimport SimpleObjectsPlugin from '@pothos/plugin-simple-objects';\nimport WithInputPlugin from '@pothos/plugin-with-input';\nimport type { Effect, SubscriptionRef } from 'effect';\nimport type { EngineCommand } from '../../../substrate/events.ts';\nimport type { SubscribableState } from '../../../substrate/projection.ts';\nimport type { ControlPlaneDomain } from '../../../substrate/runtime/control-plane/service.ts';\nimport type { DashboardDomain } from '../domain.ts';\n\n/** Per-request GraphQL context for the dashboard control plane. Resolvers\n * read the live projection ref, the command publisher, and the\n * plugin-domain accessor surfaces from here (3rd resolver arg), so the\n * schema carries no closed-over state. */\nexport interface DashboardContext {\n\treadonly state: SubscriptionRef.SubscriptionRef<SubscribableState>;\n\treadonly publishCommand: (command: EngineCommand) => Effect.Effect<void>;\n\t/** Submit a command to the supervisor's command-loop and AWAIT its real\n\t * exit (unlike the fire-and-forget `publishCommand`). The restore\n\t * mutation routes through this so the destructive restore + re-acquire\n\t * runs in-band with the single command-loop consumer and the mutation\n\t * only resolves once services are actually back. */\n\treadonly submitCommand: (command: EngineCommand) => Effect.Effect<void, unknown>;\n\t/** Generic, name-blind control-plane accessors: snapshot catalog +\n\t * restore/delete, the observability rings, and the resolved-values\n\t * seam. (Plugin-name-aware shaping lives in `pluginDomain`.) */\n\treadonly domain: ControlPlaneDomain;\n\t/** Plugin-name-aware accessors the dashboard plugin shapes from the\n\t * generic control-plane `resolvedValues`: fork-vs-local mode,\n\t * deepbook/seal/coin capability ids, and the coin mint action. */\n\treadonly pluginDomain: DashboardDomain;\n}\n\ninterface SchemaTypes {\n\tContext: DashboardContext;\n\t// Output fields are non-nullable unless a resolver opts in with\n\t// `nullable: true` — the projection always resolves a concrete value.\n\tDefaultFieldNullability: false;\n}\n\n/** The single module-level builder. Object types, enums, and root types are\n * defined against this instance across the sibling `schema/*` modules; the\n * built schema is `dashboardSchema` (see `../schema.ts`). */\nexport const builder = new SchemaBuilder<SchemaTypes>({\n\tplugins: [SimpleObjectsPlugin, RelayPlugin, WithInputPlugin],\n\trelay: {},\n\tdefaultFieldNullability: false,\n});\n"],"mappings":";;;;;;;;AAuDA,MAAa,UAAU,IAAI,cAA2B;CACrD,SAAS;EAAC;EAAqB;EAAa;CAAe;CAC3D,OAAO,CAAC;CACR,yBAAyB;AAC1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"enums.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/enums.ts"],"sourcesContent":["// Pothos enums mirroring the closed unions in projection.ts / lifecycle.ts.\n//\n// Each `values` array is the EXACT string union from the source type — if\n// a substrate union gains a member, the corresponding `satisfies` below\n// stops compiling until this list is updated. That keeps the GraphQL\n// vocabulary in lockstep with the projection vocabulary.\n\nimport { builder } from './builder.ts';\nimport type {\n\tLifecycleStatus as LifecycleStatusUnion,\n\tPluginRole as PluginRoleUnion,\n} from '../../../substrate/lifecycle.ts';\nimport type {\n\tAccountProjection,\n\tEndpoint,\n\tLogTail,\n\tPackageProjection,\n\tRowSection as RowSectionUnion,\n\tStructuredError,\n} from '../../../substrate/projection.ts';\n\n// NOTE: CyclePhase ('shutting-down') and FundingEntryStatus ('already-satisfied')\n// are intentionally NOT GraphQL enums — their values contain hyphens, which are\n// illegal in GraphQL enum value names. Those fields are exposed as String (the\n// raw union string is the wire contract). See schema/types.ts.\ntype WireProtocol = Endpoint['wireProtocol'];\ntype LogLevel = LogTail['level'];\ntype ErrorSeverity = StructuredError['severity'];\ntype AccountScheme = NonNullable<AccountProjection['scheme']>;\ntype AccountSource = NonNullable<AccountProjection['source']>;\ntype FundingStatus = AccountProjection['funding']['status'];\ntype PackageKind = PackageProjection['kind'];\n\n/** Derived health classification for a single service row + the stack. */\nexport type Health = 'ready' | 'active' | 'blocked' | 'empty';\n\nexport const LifecycleStatus = builder.enumType('LifecycleStatus', {\n\tvalues: [\n\t\t'pending',\n\t\t'acquiring',\n\t\t'ready',\n\t\t'failed',\n\t\t'stopping',\n\t\t'stopped',\n\t\t'done',\n\t] satisfies LifecycleStatusUnion[],\n});\n\nexport const PluginRole = builder.enumType('PluginRole', {\n\tvalues: ['service', 'task'] satisfies PluginRoleUnion[],\n});\n\nexport const RowSection = builder.enumType('RowSection', {\n\tvalues: ['service', 'package', 'account', 'action', 'app', 'other'] satisfies RowSectionUnion[],\n});\n\nexport const WireProtocol = builder.enumType('WireProtocol', {\n\tvalues: ['http', 'h2c', 'tcp'] satisfies WireProtocol[],\n});\n\nexport const LogLevel = builder.enumType('LogLevel', {\n\tvalues: ['info', 'warn', 'error'] satisfies LogLevel[],\n});\n\nexport const ErrorSeverity = builder.enumType('ErrorSeverity', {\n\tvalues: ['warn', 'error', 'fatal'] satisfies ErrorSeverity[],\n});\n\nexport const AccountScheme = builder.enumType('AccountScheme', {\n\tvalues: ['ed25519', 'secp256k1', 'secp256r1'] satisfies AccountScheme[],\n});\n\nexport const AccountSource = builder.enumType('AccountSource', {\n\tvalues: ['real', 'impersonate'] satisfies AccountSource[],\n});\n\nexport const FundingStatus = builder.enumType('FundingStatus', {\n\tvalues: ['pending', 'funded', 'skipped', 'failed', 'unknown'] satisfies FundingStatus[],\n});\n\nexport const PackageKind = builder.enumType('PackageKind', {\n\tvalues: ['local', 'known'] satisfies PackageKind[],\n});\n\nexport const Health = builder.enumType('Health', {\n\tvalues: ['ready', 'active', 'blocked', 'empty'] satisfies Health[],\n});\n\n// --- Plugin-domain enums (control-plane `domain` surface) ------------------\n//\n// These mirror the closed unions on the control-plane domain shapes. They\n// carry no hyphenated members EXCEPT seal's `fork-known` / `local-keygen`,\n// which would be illegal GraphQL enum names — so SealMode is exposed as a\n// raw String field (see schema/types.ts), NOT an enum.\n\n/** Fork-vs-local stack mode (advance-clock gating). Derived from the sui\n * plugin's resolved mode; `local-rpc` collapses to `local`. */\nexport const StackMode = builder.enumType('StackMode', {\n\tvalues: ['fork', 'local', 'live'] as const,\n});\n\n/** DeepBook deployment mode. */\nexport const DeepbookMode = builder.enumType('DeepbookMode', {\n\tvalues: ['local', 'override', 'known'] as const,\n});\n\n// NOTE: CoinSource ('on-chain') and SealMode ('local-keygen' / 'fork-known')\n// are intentionally NOT GraphQL enums — their values contain hyphens, which\n// are illegal in GraphQL enum value names. Those fields are exposed as String\n// (the raw union string is the wire contract). See schema/types.ts.\n"],"mappings":";;AAoCA,MAAa,kBAAkB,QAAQ,SAAS,mBAAmB,EAClE,QAAQ;CACP;CACA;CACA;CACA;CACA;CACA;CACA;CACA,EACD,CAAC;AAEF,MAAa,aAAa,QAAQ,SAAS,cAAc,EACxD,QAAQ,CAAC,WAAW,OAAO,EAC3B,CAAC;AAEF,MAAa,aAAa,QAAQ,SAAS,cAAc,EACxD,QAAQ;CAAC;CAAW;CAAW;CAAW;CAAU;CAAO;CAAQ,EACnE,CAAC;AAEF,MAAa,eAAe,QAAQ,SAAS,gBAAgB,EAC5D,QAAQ;CAAC;CAAQ;CAAO;CAAM,EAC9B,CAAC;AAEF,MAAa,WAAW,QAAQ,SAAS,YAAY,EACpD,QAAQ;CAAC;CAAQ;CAAQ;CAAQ,EACjC,CAAC;AAEF,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAQ;CAAS;CAAQ,EAClC,CAAC;AAEF,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAW;CAAa;CAAY,EAC7C,CAAC;AAEF,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ,CAAC,QAAQ,cAAc,EAC/B,CAAC;AAEF,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAW;CAAU;CAAW;CAAU;CAAU,EAC7D,CAAC;AAEF,MAAa,cAAc,QAAQ,SAAS,eAAe,EAC1D,QAAQ,CAAC,SAAS,QAAQ,EAC1B,CAAC;AAEF,MAAa,SAAS,QAAQ,SAAS,UAAU,EAChD,QAAQ;CAAC;CAAS;CAAU;CAAW;CAAQ,EAC/C,CAAC;;;AAWF,MAAa,YAAY,QAAQ,SAAS,aAAa,EACtD,QAAQ;CAAC;CAAQ;CAAS;CAAO,EACjC,CAAC;;AAGF,MAAa,eAAe,QAAQ,SAAS,gBAAgB,EAC5D,QAAQ;CAAC;CAAS;CAAY;CAAQ,EACtC,CAAC"}
1
+ {"version":3,"file":"enums.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/enums.ts"],"sourcesContent":["// Pothos enums mirroring the closed unions in projection.ts / lifecycle.ts.\n//\n// Each `values` array is the EXACT string union from the source type — if\n// a substrate union gains a member, the corresponding `satisfies` below\n// stops compiling until this list is updated. That keeps the GraphQL\n// vocabulary in lockstep with the projection vocabulary.\n\nimport { builder } from './builder.ts';\nimport type {\n\tLifecycleStatus as LifecycleStatusUnion,\n\tPluginRole as PluginRoleUnion,\n} from '../../../substrate/lifecycle.ts';\nimport type {\n\tAccountProjection,\n\tEndpoint,\n\tLogTail,\n\tPackageProjection,\n\tRowSection as RowSectionUnion,\n\tStructuredError,\n} from '../../../substrate/projection.ts';\n\n// NOTE: CyclePhase ('shutting-down') and FundingEntryStatus ('already-satisfied')\n// are intentionally NOT GraphQL enums — their values contain hyphens, which are\n// illegal in GraphQL enum value names. Those fields are exposed as String (the\n// raw union string is the wire contract). See schema/types.ts.\ntype WireProtocol = Endpoint['wireProtocol'];\ntype LogLevel = LogTail['level'];\ntype ErrorSeverity = StructuredError['severity'];\ntype AccountScheme = NonNullable<AccountProjection['scheme']>;\ntype AccountSource = NonNullable<AccountProjection['source']>;\ntype FundingStatus = AccountProjection['funding']['status'];\ntype PackageKind = PackageProjection['kind'];\n\n/** Derived health classification for a single service row + the stack. */\nexport type Health = 'ready' | 'active' | 'blocked' | 'empty';\n\nexport const LifecycleStatus = builder.enumType('LifecycleStatus', {\n\tvalues: [\n\t\t'pending',\n\t\t'acquiring',\n\t\t'ready',\n\t\t'failed',\n\t\t'stopping',\n\t\t'stopped',\n\t\t'done',\n\t] satisfies LifecycleStatusUnion[],\n});\n\nexport const PluginRole = builder.enumType('PluginRole', {\n\tvalues: ['service', 'task'] satisfies PluginRoleUnion[],\n});\n\nexport const RowSection = builder.enumType('RowSection', {\n\tvalues: ['service', 'package', 'account', 'action', 'app', 'other'] satisfies RowSectionUnion[],\n});\n\nexport const WireProtocol = builder.enumType('WireProtocol', {\n\tvalues: ['http', 'h2c', 'tcp'] satisfies WireProtocol[],\n});\n\nexport const LogLevel = builder.enumType('LogLevel', {\n\tvalues: ['info', 'warn', 'error'] satisfies LogLevel[],\n});\n\nexport const ErrorSeverity = builder.enumType('ErrorSeverity', {\n\tvalues: ['warn', 'error', 'fatal'] satisfies ErrorSeverity[],\n});\n\nexport const AccountScheme = builder.enumType('AccountScheme', {\n\tvalues: ['ed25519', 'secp256k1', 'secp256r1'] satisfies AccountScheme[],\n});\n\nexport const AccountSource = builder.enumType('AccountSource', {\n\tvalues: ['real', 'impersonate'] satisfies AccountSource[],\n});\n\nexport const FundingStatus = builder.enumType('FundingStatus', {\n\tvalues: ['pending', 'funded', 'skipped', 'failed', 'unknown'] satisfies FundingStatus[],\n});\n\nexport const PackageKind = builder.enumType('PackageKind', {\n\tvalues: ['local', 'known'] satisfies PackageKind[],\n});\n\nexport const Health = builder.enumType('Health', {\n\tvalues: ['ready', 'active', 'blocked', 'empty'] satisfies Health[],\n});\n\n// --- Plugin-domain enums (control-plane `domain` surface) ------------------\n//\n// These mirror the closed unions on the control-plane domain shapes. They\n// carry no hyphenated members EXCEPT seal's `fork-known` / `local-keygen`,\n// which would be illegal GraphQL enum names — so SealMode is exposed as a\n// raw String field (see schema/types.ts), NOT an enum.\n\n/** Fork-vs-local stack mode (advance-clock gating). Derived from the sui\n * plugin's resolved mode; `local-rpc` collapses to `local`. */\nexport const StackMode = builder.enumType('StackMode', {\n\tvalues: ['fork', 'local', 'live'] as const,\n});\n\n/** DeepBook deployment mode. */\nexport const DeepbookMode = builder.enumType('DeepbookMode', {\n\tvalues: ['local', 'override', 'known'] as const,\n});\n\n// NOTE: CoinSource ('on-chain') and SealMode ('local-keygen' / 'fork-known')\n// are intentionally NOT GraphQL enums — their values contain hyphens, which\n// are illegal in GraphQL enum value names. Those fields are exposed as String\n// (the raw union string is the wire contract). See schema/types.ts.\n"],"mappings":";;AAoCA,MAAa,kBAAkB,QAAQ,SAAS,mBAAmB,EAClE,QAAQ;CACP;CACA;CACA;CACA;CACA;CACA;CACA;AACD,EACD,CAAC;AAED,MAAa,aAAa,QAAQ,SAAS,cAAc,EACxD,QAAQ,CAAC,WAAW,MAAM,EAC3B,CAAC;AAED,MAAa,aAAa,QAAQ,SAAS,cAAc,EACxD,QAAQ;CAAC;CAAW;CAAW;CAAW;CAAU;CAAO;AAAO,EACnE,CAAC;AAED,MAAa,eAAe,QAAQ,SAAS,gBAAgB,EAC5D,QAAQ;CAAC;CAAQ;CAAO;AAAK,EAC9B,CAAC;AAED,MAAa,WAAW,QAAQ,SAAS,YAAY,EACpD,QAAQ;CAAC;CAAQ;CAAQ;AAAO,EACjC,CAAC;AAED,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAQ;CAAS;AAAO,EAClC,CAAC;AAED,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAW;CAAa;AAAW,EAC7C,CAAC;AAED,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ,CAAC,QAAQ,aAAa,EAC/B,CAAC;AAED,MAAa,gBAAgB,QAAQ,SAAS,iBAAiB,EAC9D,QAAQ;CAAC;CAAW;CAAU;CAAW;CAAU;AAAS,EAC7D,CAAC;AAED,MAAa,cAAc,QAAQ,SAAS,eAAe,EAC1D,QAAQ,CAAC,SAAS,OAAO,EAC1B,CAAC;AAED,MAAa,SAAS,QAAQ,SAAS,UAAU,EAChD,QAAQ;CAAC;CAAS;CAAU;CAAW;AAAO,EAC/C,CAAC;;;AAWD,MAAa,YAAY,QAAQ,SAAS,aAAa,EACtD,QAAQ;CAAC;CAAQ;CAAS;AAAM,EACjC,CAAC;;AAGD,MAAa,eAAe,QAAQ,SAAS,gBAAgB,EAC5D,QAAQ;CAAC;CAAS;CAAY;AAAO,EACtC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { builder } from "./builder.mjs";
2
2
  import { StackMode } from "./enums.mjs";
3
- import { Account, CoinCap, DeepbookInfo, FundableCoin, LogFilterInput, LogRecordType, Package, PostgresStats, SealInfo, Service, SnapshotEntry, SpanFilterInput, SpanRecordType, StackState } from "./types.mjs";
3
+ import { Account, CoinCap, DeepbookInfo, FundableCoin, LogFilterInput, LogRecordType, Package, SealInfo, Service, SnapshotEntry, StackState } from "./types.mjs";
4
4
  import { Effect, Fiber, Queue, Stream, SubscriptionRef } from "effect";
5
5
  import { resolveArrayConnection } from "@pothos/plugin-relay";
6
6
  //#region src/plugins/dashboard/schema/root.ts
@@ -48,11 +48,7 @@ const FundResult = builder.objectRef("FundResult").implement({
48
48
  description: "The outcome of a faucet fund request (real result — ok reflects whether the in-process funding strategy completed).",
49
49
  fields: (t) => ({
50
50
  ok: t.exposeBoolean("ok"),
51
- detail: t.exposeString("detail"),
52
- digest: t.string({
53
- nullable: true,
54
- resolve: (r) => r.digest
55
- })
51
+ detail: t.exposeString("detail")
56
52
  })
57
53
  });
58
54
  builder.queryType({ fields: (t) => ({
@@ -128,12 +124,6 @@ builder.queryType({ fields: (t) => ({
128
124
  type: [FundableCoin],
129
125
  resolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.fundableCoins)
130
126
  }),
131
- /** Postgres wire-protocol stats per instance (db size, connections,
132
- * per-table rows/size). The browser cannot speak the PG protocol. */
133
- postgresStats: t.field({
134
- type: [PostgresStats],
135
- resolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.postgresStats)
136
- }),
137
127
  /** Cross-service queryable log history. Filterable server-side by
138
128
  * service / level / substring / time window; returns most-recent
139
129
  * first, capped by `filter.limit` (default = ring capacity). */
@@ -149,21 +139,6 @@ builder.queryType({ fields: (t) => ({
149
139
  logServices: t.field({
150
140
  type: ["String"],
151
141
  resolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.logServices)
152
- }),
153
- /** Completed-span ring. Filterable server-side by service / status /
154
- * substring / time window; most-recent first. */
155
- spans: t.field({
156
- type: [SpanRecordType],
157
- args: { filter: t.arg({
158
- type: SpanFilterInput,
159
- required: false
160
- }) },
161
- resolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.spans(toSpanFilter(args.filter)))
162
- }),
163
- /** Distinct services currently in the span ring (filter dropdown). */
164
- spanServices: t.field({
165
- type: ["String"],
166
- resolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.spanServices)
167
142
  })
168
143
  }) });
169
144
  /** Closed log-level set used to narrow the String[] filter input back onto
@@ -196,19 +171,6 @@ const toLogFilter = (input) => {
196
171
  ...input.limit != null ? { limit: input.limit } : {}
197
172
  };
198
173
  };
199
- /** Map the nullable GraphQL `SpanFilter` input onto the store's `SpanFilter`. */
200
- const toSpanFilter = (input) => {
201
- if (input == null) return void 0;
202
- const services = nonEmpty(input.services);
203
- const statuses = nonEmpty(input.statuses)?.filter((s) => s === "ok" || s === "error");
204
- return {
205
- ...services ? { services } : {},
206
- ...statuses && statuses.length > 0 ? { statuses } : {},
207
- ...input.search != null ? { search: input.search } : {},
208
- ...input.sinceMillis != null ? { sinceMillis: input.sinceMillis } : {},
209
- ...input.limit != null ? { limit: input.limit } : {}
210
- };
211
- };
212
174
  builder.mutationType({ fields: (t) => ({
213
175
  /** Restart the whole stack. */
214
176
  restart: t.field({
@@ -271,13 +233,30 @@ builder.mutationType({ fields: (t) => ({
271
233
  type: CommandResult,
272
234
  resolve: (_parent, _args, ctx) => run(ctx, "shutdown.requested", { tag: "shutdown.requested" })
273
235
  }),
274
- /** Restore a snapshot by id. Routes through the control-plane
275
- * `domain` so the dashboard gets a real ok/detail outcome (the void
276
- * `publishCommand` could not carry the orchestrator's result). */
236
+ /** Restore a snapshot by id. Routes through the supervisor
237
+ * command-loop via `submitCommand` (NOT the in-process
238
+ * `domain.restoreSnapshot`): restore is destructive it removes the
239
+ * live managed containers and relies on a follow-on re-acquire to
240
+ * rebuild them. Running it in-process against a live supervisor would
241
+ * race the single command-queue consumer and leave services dead until
242
+ * a manual Restart. The command-loop's `snapshot.restore` case applies
243
+ * the restored tree, publishes `snapshot.restored`, THEN drains +
244
+ * re-acquires every service (the manual-restart sequence) — and the
245
+ * submitted-command completion deferred lets this mutation await the
246
+ * real ok/detail outcome the void `publishCommand` could not carry. */
277
247
  restoreSnapshot: t.fieldWithInput({
278
248
  type: SnapshotActionResult,
279
249
  input: { id: t.input.string({ required: true }) },
280
- resolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.restoreSnapshot(args.input.id))
250
+ resolve: (_parent, args, ctx) => Effect.runPromise(ctx.submitCommand({
251
+ tag: "snapshot.restore",
252
+ snapshotId: args.input.id
253
+ }).pipe(Effect.as({
254
+ ok: true,
255
+ detail: null
256
+ }), Effect.catchCause((cause) => Effect.succeed({
257
+ ok: false,
258
+ detail: String(cause)
259
+ }))))
281
260
  }),
282
261
  /** Delete a snapshot by id (via the control-plane `domain`). */
283
262
  deleteSnapshot: t.fieldWithInput({
@@ -1 +1 @@
1
- {"version":3,"file":"root.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/root.ts"],"sourcesContent":["// Dashboard root types — Query / Mutation / Subscription.\n//\n// Queries expose the live projection (`state`), relay node/connection\n// access over the snapshot arrays, and a liveness `ping`. Mutations map to\n// `EngineCommand`s. The single subscription streams the projection over the\n// SubscriptionRef→async-generator bridge. Dependencies (the `state` ref +\n// `publishCommand`) come from the GraphQL context (`ctx`), not closure — the\n// dashboard is a pure control plane (no chain reads).\n\nimport { Effect, Fiber, Queue, Stream, SubscriptionRef } from 'effect';\nimport { resolveArrayConnection } from '@pothos/plugin-relay';\nimport { builder } from './builder.ts';\nimport {\n\tAccount,\n\tCoinCap,\n\tDeepbookInfo,\n\tFundableCoin,\n\tLogFilterInput,\n\tLogRecordType,\n\tPackage,\n\tPostgresStats,\n\tSealInfo,\n\tService,\n\tSnapshotEntry,\n\tSpanFilterInput,\n\tSpanRecordType,\n\tStackState,\n\ttype ServiceSource,\n} from './types.ts';\nimport { StackMode } from './enums.ts';\nimport type { DashboardContext } from './builder.ts';\nimport type { PluginKey } from '../../../substrate/brand.ts';\nimport type { EngineCommand } from '../../../substrate/events.ts';\nimport type { SubscribableState } from '../../../substrate/projection.ts';\nimport type {\n\tLogFilter,\n\tLogLevel,\n\tSpanFilter,\n} from '../../../substrate/runtime/observability/index.ts';\n\nconst readSnapshot = (\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n): Promise<SubscribableState> => Effect.runPromise(SubscriptionRef.get(state));\n\n// --- CommandResult ------------------------------------------------------\ninterface CommandResultShape {\n\treadonly ok: boolean;\n\treadonly command: string;\n\treadonly message?: string | null;\n}\n\nconst CommandResult = builder.objectRef<CommandResultShape>('CommandResult').implement({\n\tdescription: 'The outcome of dispatching an engine command.',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tcommand: t.exposeString('command'),\n\t\tmessage: t.string({ nullable: true, resolve: (r) => r.message ?? null }),\n\t}),\n});\n\nconst run = async (\n\tctx: DashboardContext,\n\ttag: string,\n\tcommand: EngineCommand,\n): Promise<CommandResultShape> => {\n\tawait Effect.runPromise(ctx.publishCommand(command));\n\treturn { ok: true, command: tag };\n};\n\n// --- SnapshotActionResult -----------------------------------------------\n//\n// Restore/delete go through the control-plane `domain` (NOT the void\n// `publishCommand`), so the dashboard gets a real ok/detail outcome the\n// fire-and-forget command channel cannot carry.\ninterface SnapshotActionResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string | null;\n}\n\nconst SnapshotActionResult = builder\n\t.objectRef<SnapshotActionResultShape>('SnapshotActionResult')\n\t.implement({\n\t\tdescription: 'The outcome of a snapshot restore/delete (real result, not fire-and-forget).',\n\t\tfields: (t) => ({\n\t\t\tok: t.exposeBoolean('ok'),\n\t\t\tdetail: t.string({ nullable: true, resolve: (r) => r.detail }),\n\t\t}),\n\t});\n\n// --- MintResult ---------------------------------------------------------\n//\n// The coin Mint action goes through the control-plane `domain` (NOT the\n// void `publishCommand`): the supervisor holds the treasury-cap-owning\n// signer in-process and returns a real ok/detail outcome plus the on-chain\n// tx `digest` on success.\ninterface MintResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string;\n\treadonly digest: string | null;\n}\n\nconst MintResult = builder.objectRef<MintResultShape>('MintResult').implement({\n\tdescription: 'The outcome of a coin mint (real result, with the on-chain tx digest on success).',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tdetail: t.exposeString('detail'),\n\t\tdigest: t.string({ nullable: true, resolve: (r) => r.digest }),\n\t}),\n});\n\n// --- FundResult ---------------------------------------------------------\n//\n// The Faucet `fund` action routes through the control-plane `pluginDomain`,\n// reusing devstack's IN-PROCESS funding strategies (the same registry the\n// boot-time account funding pass uses): SUI via the chain faucet strategy\n// (fixed-amount), WAL/DEEP via the coin-specific account-signed swap. The\n// strategies return `void` (no digest), so `digest` is always null here —\n// kept for shape-parity with `MintResult`. `ok` reflects whether the\n// strategy's `request(...)` actually completed.\ninterface FundResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string;\n\treadonly digest: string | null;\n}\n\nconst FundResult = builder.objectRef<FundResultShape>('FundResult').implement({\n\tdescription:\n\t\t'The outcome of a faucet fund request (real result — ok reflects whether the ' +\n\t\t'in-process funding strategy completed).',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tdetail: t.exposeString('detail'),\n\t\tdigest: t.string({ nullable: true, resolve: (r) => r.digest }),\n\t}),\n});\n\n// --- Query --------------------------------------------------------------\nbuilder.queryType({\n\tfields: (t) => ({\n\t\t/** Liveness probe. */\n\t\tping: t.string({ resolve: () => 'pong' }),\n\t\t/** Full live projection snapshot (status, services, endpoints, …). */\n\t\tstate: t.field({\n\t\t\ttype: StackState,\n\t\t\tresolve: (_parent, _args, ctx) => readSnapshot(ctx.state),\n\t\t}),\n\t\t/** Relay connection over the current snapshot's service rows. */\n\t\tservices: t.connection({\n\t\t\ttype: Service,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\tconst sources: ServiceSource[] = snapshot.rows.map((row) => ({ row, snapshot }));\n\t\t\t\treturn resolveArrayConnection({ args }, sources);\n\t\t\t},\n\t\t}),\n\t\t/** Relay connection over the current snapshot's accounts. */\n\t\taccounts: t.connection({\n\t\t\ttype: Account,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\treturn resolveArrayConnection({ args }, [...snapshot.accounts]);\n\t\t\t},\n\t\t}),\n\t\t/** Relay connection over the current snapshot's packages. */\n\t\tpackages: t.connection({\n\t\t\ttype: Package,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\treturn resolveArrayConnection({ args }, [...snapshot.packages]);\n\t\t\t},\n\t\t}),\n\n\t\t// --- Plugin-domain queries (data the browser cannot reach) --------\n\t\t/** Fork-vs-local stack mode (advance-clock gating). `null` when no\n\t\t * sui plugin is present. */\n\t\tmode: t.field({\n\t\t\ttype: StackMode,\n\t\t\tnullable: true,\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.mode),\n\t\t}),\n\t\t/** Snapshot catalog: id/label/created/participants/containers. */\n\t\tsnapshots: t.field({\n\t\t\ttype: [SnapshotEntry],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.snapshots),\n\t\t}),\n\t\t/** DeepBook deployments: registry/admin/pool ids + market-maker\n\t\t * state. (Pool prices / order books are chain-direct.) */\n\t\tdeepbookInfo: t.field({\n\t\t\ttype: [DeepbookInfo],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.deepbook),\n\t\t}),\n\t\t/** Seal key-server deployments: objectId/threshold/mode/keyServers. */\n\t\tsealInfo: t.field({\n\t\t\ttype: [SealInfo],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.seal),\n\t\t}),\n\t\t/** Coin treasury caps (drives Mint) + addressing facts. (Supply /\n\t\t * metadata are chain-direct.) */\n\t\tcoinCaps: t.field({\n\t\t\ttype: [CoinCap],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.coinCaps),\n\t\t}),\n\t\t/** Coins the faucet can actually fund right now (drives the Faucet\n\t\t * panel's coin pills + amount gating). SUI is always present when a\n\t\t * faucet strategy is registered; WAL/DEEP appear only when their\n\t\t * plugin contributed a funding strategy. */\n\t\tfundableCoins: t.field({\n\t\t\ttype: [FundableCoin],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.fundableCoins),\n\t\t}),\n\t\t/** Postgres wire-protocol stats per instance (db size, connections,\n\t\t * per-table rows/size). The browser cannot speak the PG protocol. */\n\t\tpostgresStats: t.field({\n\t\t\ttype: [PostgresStats],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.postgresStats),\n\t\t}),\n\n\t\t// --- Observability (Console \"Logs\" + \"Traces\" tabs) ---------------\n\t\t/** Cross-service queryable log history. Filterable server-side by\n\t\t * service / level / substring / time window; returns most-recent\n\t\t * first, capped by `filter.limit` (default = ring capacity). */\n\t\tlogs: t.field({\n\t\t\ttype: [LogRecordType],\n\t\t\targs: { filter: t.arg({ type: LogFilterInput, required: false }) },\n\t\t\tresolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.logs(toLogFilter(args.filter))),\n\t\t}),\n\t\t/** Distinct services currently in the log ring (filter dropdown). */\n\t\tlogServices: t.field({\n\t\t\ttype: ['String'],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.logServices),\n\t\t}),\n\t\t/** Completed-span ring. Filterable server-side by service / status /\n\t\t * substring / time window; most-recent first. */\n\t\tspans: t.field({\n\t\t\ttype: [SpanRecordType],\n\t\t\targs: { filter: t.arg({ type: SpanFilterInput, required: false }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(ctx.domain.spans(toSpanFilter(args.filter))),\n\t\t}),\n\t\t/** Distinct services currently in the span ring (filter dropdown). */\n\t\tspanServices: t.field({\n\t\t\ttype: ['String'],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.spanServices),\n\t\t}),\n\t}),\n});\n\n/** Closed log-level set used to narrow the String[] filter input back onto\n * the store's `LogLevel` union. Unknown strings are dropped (the store would\n * just never match them anyway). */\nconst LOG_LEVELS: ReadonlySet<LogLevel> = new Set<LogLevel>([\n\t'trace',\n\t'debug',\n\t'info',\n\t'warn',\n\t'error',\n\t'fatal',\n]);\n\nconst nonEmpty = (xs: readonly (string | null)[] | null | undefined): string[] | undefined => {\n\tif (xs == null) return undefined;\n\tconst out = xs.filter((x): x is string => x != null && x.length > 0);\n\treturn out.length > 0 ? out : undefined;\n};\n\n/** Map the nullable GraphQL `LogFilter` input onto the store's `LogFilter`,\n * dropping nulls and unknown levels. */\nconst toLogFilter = (\n\tinput:\n\t\t| {\n\t\t\t\tservices?: readonly (string | null)[] | null;\n\t\t\t\tlevels?: readonly (string | null)[] | null;\n\t\t\t\tsearch?: string | null;\n\t\t\t\tsinceMillis?: number | null;\n\t\t\t\tlimit?: number | null;\n\t\t }\n\t\t| null\n\t\t| undefined,\n): LogFilter | undefined => {\n\tif (input == null) return undefined;\n\tconst services = nonEmpty(input.services);\n\tconst levelStrings = nonEmpty(input.levels);\n\tconst levels = levelStrings?.filter((l): l is LogLevel => LOG_LEVELS.has(l as LogLevel));\n\treturn {\n\t\t...(services ? { services } : {}),\n\t\t...(levels && levels.length > 0 ? { levels } : {}),\n\t\t...(input.search != null ? { search: input.search } : {}),\n\t\t...(input.sinceMillis != null ? { sinceMillis: input.sinceMillis } : {}),\n\t\t...(input.limit != null ? { limit: input.limit } : {}),\n\t};\n};\n\n/** Map the nullable GraphQL `SpanFilter` input onto the store's `SpanFilter`. */\nconst toSpanFilter = (\n\tinput:\n\t\t| {\n\t\t\t\tservices?: readonly (string | null)[] | null;\n\t\t\t\tstatuses?: readonly (string | null)[] | null;\n\t\t\t\tsearch?: string | null;\n\t\t\t\tsinceMillis?: number | null;\n\t\t\t\tlimit?: number | null;\n\t\t }\n\t\t| null\n\t\t| undefined,\n): SpanFilter | undefined => {\n\tif (input == null) return undefined;\n\tconst services = nonEmpty(input.services);\n\tconst statusStrings = nonEmpty(input.statuses);\n\tconst statuses = statusStrings?.filter((s): s is 'ok' | 'error' => s === 'ok' || s === 'error');\n\treturn {\n\t\t...(services ? { services } : {}),\n\t\t...(statuses && statuses.length > 0 ? { statuses } : {}),\n\t\t...(input.search != null ? { search: input.search } : {}),\n\t\t...(input.sinceMillis != null ? { sinceMillis: input.sinceMillis } : {}),\n\t\t...(input.limit != null ? { limit: input.limit } : {}),\n\t};\n};\n\n// --- Mutation -----------------------------------------------------------\nbuilder.mutationType({\n\tfields: (t) => ({\n\t\t/** Restart the whole stack. */\n\t\trestart: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'stack.restart', { tag: 'stack.restart' }),\n\t\t}),\n\t\t/** Selectively restart a single plugin subgraph. */\n\t\trestartPlugin: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { pluginKey: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'selective-restart.requested', {\n\t\t\t\t\ttag: 'selective-restart.requested',\n\t\t\t\t\tpluginKey: args.input.pluginKey as PluginKey,\n\t\t\t\t}),\n\t\t}),\n\t\t/** Capture a snapshot, optionally naming it. */\n\t\tcaptureSnapshot: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { name: t.input.string({ required: false }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'snapshot.capture', {\n\t\t\t\t\ttag: 'snapshot.capture',\n\t\t\t\t\t...(args.input.name == null ? {} : { name: args.input.name }),\n\t\t\t\t}),\n\t\t}),\n\t\t/** Re-run codegen against the live manifest. */\n\t\tcodegen: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'codegen.requested', { tag: 'codegen.requested' }),\n\t\t}),\n\t\t/** Re-apply the manifest, optionally scoped to a single plugin. */\n\t\tapply: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { pluginKey: t.input.string({ required: false }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'apply.requested', {\n\t\t\t\t\ttag: 'apply.requested',\n\t\t\t\t\t...(args.input.pluginKey == null ? {} : { pluginKey: args.input.pluginKey as PluginKey }),\n\t\t\t\t}),\n\t\t}),\n\t\t/** Wipe the live stack footprint (preserves the snapshot catalog). */\n\t\twipe: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'wipe.requested', { tag: 'wipe.requested' }),\n\t\t}),\n\t\t/** Prune the snapshot catalog + sweep byproduct images. */\n\t\tprune: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'prune.requested', { tag: 'prune.requested' }),\n\t\t}),\n\t\t/** Advance the (fork/local) chain clock to an absolute epoch-ms. */\n\t\tadvanceClock: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { toMillis: t.input.float({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'advance-clock.requested', {\n\t\t\t\t\ttag: 'advance-clock.requested',\n\t\t\t\t\ttoMillis: args.input.toMillis,\n\t\t\t\t}),\n\t\t}),\n\t\t/** Request a graceful stack shutdown. */\n\t\tshutdown: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) =>\n\t\t\t\trun(ctx, 'shutdown.requested', { tag: 'shutdown.requested' }),\n\t\t}),\n\t\t/** Restore a snapshot by id. Routes through the control-plane\n\t\t * `domain` so the dashboard gets a real ok/detail outcome (the void\n\t\t * `publishCommand` could not carry the orchestrator's result). */\n\t\trestoreSnapshot: t.fieldWithInput({\n\t\t\ttype: SnapshotActionResult,\n\t\t\tinput: { id: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.restoreSnapshot(args.input.id)),\n\t\t}),\n\t\t/** Delete a snapshot by id (via the control-plane `domain`). */\n\t\tdeleteSnapshot: t.fieldWithInput({\n\t\t\ttype: SnapshotActionResult,\n\t\t\tinput: { id: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.deleteSnapshot(args.input.id)),\n\t\t}),\n\t\t/** Mint a custom coin. Routes through the control-plane `domain`:\n\t\t * the supervisor holds the treasury-cap-owning publisher signer\n\t\t * in-process and returns a real ok/detail/digest result (the void\n\t\t * `publishCommand` could not carry the tx digest). `amountBaseUnits`\n\t\t * is the raw integer amount in the coin's smallest unit (string so\n\t\t * large u64 values survive the wire without precision loss). */\n\t\tmint: t.fieldWithInput({\n\t\t\ttype: MintResult,\n\t\t\tinput: {\n\t\t\t\tcoinType: t.input.string({ required: true }),\n\t\t\t\trecipient: t.input.string({ required: true }),\n\t\t\t\tamountBaseUnits: t.input.string({ required: true }),\n\t\t\t},\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(\n\t\t\t\t\tctx.pluginDomain.mintCoin({\n\t\t\t\t\t\tcoinType: args.input.coinType,\n\t\t\t\t\t\trecipient: args.input.recipient,\n\t\t\t\t\t\tamountBaseUnits: args.input.amountBaseUnits,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t}),\n\t\t/** Fund an account/address. Routes through the control-plane\n\t\t * `pluginDomain`, reusing devstack's in-process funding strategies:\n\t\t * SUI (absent / canonical `coinType`) via the chain faucet strategy\n\t\t * (fixed-amount — `amountBaseUnits` is ignored); WAL/DEEP via the\n\t\t * coin-specific account-signed swap (`amountBaseUnits` honored, and\n\t\t * the recipient must be a resolved account). Real result — `ok`\n\t\t * reflects whether the strategy completed. */\n\t\tfund: t.fieldWithInput({\n\t\t\ttype: FundResult,\n\t\t\tinput: {\n\t\t\t\trecipient: t.input.string({ required: true }),\n\t\t\t\tcoinType: t.input.string({ required: false }),\n\t\t\t\tamountBaseUnits: t.input.string({ required: false }),\n\t\t\t},\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(\n\t\t\t\t\tctx.pluginDomain.fundAccount({\n\t\t\t\t\t\trecipient: args.input.recipient,\n\t\t\t\t\t\tcoinType: args.input.coinType,\n\t\t\t\t\t\tamountBaseUnits: args.input.amountBaseUnits,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t}),\n\t}),\n});\n\n// --- Subscription -------------------------------------------------------\nbuilder.subscriptionType({\n\tfields: (t) => ({\n\t\t/** Stream the projection on every change (current value first). */\n\t\tstate: t.field({\n\t\t\ttype: StackState,\n\t\t\tsubscribe: (_parent, _args, ctx) => subscribeState(ctx.state),\n\t\t\tresolve: (payload) => payload,\n\t\t}),\n\t}),\n});\n\n/** Bridge an Effect `SubscriptionRef` to an async iterable for GraphQL\n * subscriptions. `SubscriptionRef.changes` emits the current value first,\n * then each subsequent update. The pump fiber is interrupted when the\n * consumer (yoga) stops iterating. */\nasync function* subscribeState(\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n): AsyncGenerator<SubscribableState> {\n\tconst queue = Effect.runSync(Queue.unbounded<SubscribableState>());\n\tconst pump = Effect.runFork(\n\t\tStream.runForEach(SubscriptionRef.changes(ref), (snapshot) => Queue.offer(queue, snapshot)),\n\t);\n\ttry {\n\t\twhile (true) {\n\t\t\tyield await Effect.runPromise(Queue.take(queue));\n\t\t}\n\t} finally {\n\t\tEffect.runFork(Fiber.interrupt(pump));\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"root.mjs","names":[],"sources":["../../../../src/plugins/dashboard/schema/root.ts"],"sourcesContent":["// Dashboard root types — Query / Mutation / Subscription.\n//\n// Queries expose the live projection (`state`), relay node/connection\n// access over the snapshot arrays, and a liveness `ping`. Mutations map to\n// `EngineCommand`s. The single subscription streams the projection over the\n// SubscriptionRef→async-generator bridge. Dependencies (the `state` ref +\n// `publishCommand`) come from the GraphQL context (`ctx`), not closure — the\n// dashboard is a pure control plane (no chain reads).\n\nimport { Effect, Fiber, Queue, Stream, SubscriptionRef } from 'effect';\nimport { resolveArrayConnection } from '@pothos/plugin-relay';\nimport { builder } from './builder.ts';\nimport {\n\tAccount,\n\tCoinCap,\n\tDeepbookInfo,\n\tFundableCoin,\n\tLogFilterInput,\n\tLogRecordType,\n\tPackage,\n\tSealInfo,\n\tService,\n\tSnapshotEntry,\n\tStackState,\n\ttype ServiceSource,\n} from './types.ts';\nimport { StackMode } from './enums.ts';\nimport type { DashboardContext } from './builder.ts';\nimport type { PluginKey } from '../../../substrate/brand.ts';\nimport type { EngineCommand } from '../../../substrate/events.ts';\nimport type { SubscribableState } from '../../../substrate/projection.ts';\nimport type { LogFilter, LogLevel } from '../../../substrate/runtime/observability/index.ts';\n\nconst readSnapshot = (\n\tstate: SubscriptionRef.SubscriptionRef<SubscribableState>,\n): Promise<SubscribableState> => Effect.runPromise(SubscriptionRef.get(state));\n\n// --- CommandResult ------------------------------------------------------\ninterface CommandResultShape {\n\treadonly ok: boolean;\n\treadonly command: string;\n\treadonly message?: string | null;\n}\n\nconst CommandResult = builder.objectRef<CommandResultShape>('CommandResult').implement({\n\tdescription: 'The outcome of dispatching an engine command.',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tcommand: t.exposeString('command'),\n\t\tmessage: t.string({ nullable: true, resolve: (r) => r.message ?? null }),\n\t}),\n});\n\nconst run = async (\n\tctx: DashboardContext,\n\ttag: string,\n\tcommand: EngineCommand,\n): Promise<CommandResultShape> => {\n\tawait Effect.runPromise(ctx.publishCommand(command));\n\treturn { ok: true, command: tag };\n};\n\n// --- SnapshotActionResult -----------------------------------------------\n//\n// Restore/delete go through the control-plane `domain` (NOT the void\n// `publishCommand`), so the dashboard gets a real ok/detail outcome the\n// fire-and-forget command channel cannot carry.\ninterface SnapshotActionResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string | null;\n}\n\nconst SnapshotActionResult = builder\n\t.objectRef<SnapshotActionResultShape>('SnapshotActionResult')\n\t.implement({\n\t\tdescription: 'The outcome of a snapshot restore/delete (real result, not fire-and-forget).',\n\t\tfields: (t) => ({\n\t\t\tok: t.exposeBoolean('ok'),\n\t\t\tdetail: t.string({ nullable: true, resolve: (r) => r.detail }),\n\t\t}),\n\t});\n\n// --- MintResult ---------------------------------------------------------\n//\n// The coin Mint action goes through the control-plane `domain` (NOT the\n// void `publishCommand`): the supervisor holds the treasury-cap-owning\n// signer in-process and returns a real ok/detail outcome plus the on-chain\n// tx `digest` on success.\ninterface MintResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string;\n\treadonly digest: string | null;\n}\n\nconst MintResult = builder.objectRef<MintResultShape>('MintResult').implement({\n\tdescription: 'The outcome of a coin mint (real result, with the on-chain tx digest on success).',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tdetail: t.exposeString('detail'),\n\t\tdigest: t.string({ nullable: true, resolve: (r) => r.digest }),\n\t}),\n});\n\n// --- FundResult ---------------------------------------------------------\n//\n// The Faucet `fund` action routes through the control-plane `pluginDomain`,\n// reusing devstack's IN-PROCESS funding strategies (the same registry the\n// boot-time account funding pass uses): SUI via the chain faucet strategy\n// (fixed-amount), WAL/DEEP via the coin-specific account-signed swap. The\n// strategies return `void` (no digest), so the result carries only\n// `ok`/`detail`. `ok` reflects whether the strategy's `request(...)`\n// actually completed.\ninterface FundResultShape {\n\treadonly ok: boolean;\n\treadonly detail: string;\n}\n\nconst FundResult = builder.objectRef<FundResultShape>('FundResult').implement({\n\tdescription:\n\t\t'The outcome of a faucet fund request (real result — ok reflects whether the ' +\n\t\t'in-process funding strategy completed).',\n\tfields: (t) => ({\n\t\tok: t.exposeBoolean('ok'),\n\t\tdetail: t.exposeString('detail'),\n\t}),\n});\n\n// --- Query --------------------------------------------------------------\nbuilder.queryType({\n\tfields: (t) => ({\n\t\t/** Liveness probe. */\n\t\tping: t.string({ resolve: () => 'pong' }),\n\t\t/** Full live projection snapshot (status, services, endpoints, …). */\n\t\tstate: t.field({\n\t\t\ttype: StackState,\n\t\t\tresolve: (_parent, _args, ctx) => readSnapshot(ctx.state),\n\t\t}),\n\t\t/** Relay connection over the current snapshot's service rows. */\n\t\tservices: t.connection({\n\t\t\ttype: Service,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\tconst sources: ServiceSource[] = snapshot.rows.map((row) => ({ row, snapshot }));\n\t\t\t\treturn resolveArrayConnection({ args }, sources);\n\t\t\t},\n\t\t}),\n\t\t/** Relay connection over the current snapshot's accounts. */\n\t\taccounts: t.connection({\n\t\t\ttype: Account,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\treturn resolveArrayConnection({ args }, [...snapshot.accounts]);\n\t\t\t},\n\t\t}),\n\t\t/** Relay connection over the current snapshot's packages. */\n\t\tpackages: t.connection({\n\t\t\ttype: Package,\n\t\t\tresolve: async (_parent, args, ctx) => {\n\t\t\t\tconst snapshot = await readSnapshot(ctx.state);\n\t\t\t\treturn resolveArrayConnection({ args }, [...snapshot.packages]);\n\t\t\t},\n\t\t}),\n\n\t\t// --- Plugin-domain queries (data the browser cannot reach) --------\n\t\t/** Fork-vs-local stack mode (advance-clock gating). `null` when no\n\t\t * sui plugin is present. */\n\t\tmode: t.field({\n\t\t\ttype: StackMode,\n\t\t\tnullable: true,\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.mode),\n\t\t}),\n\t\t/** Snapshot catalog: id/label/created/participants/containers. */\n\t\tsnapshots: t.field({\n\t\t\ttype: [SnapshotEntry],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.snapshots),\n\t\t}),\n\t\t/** DeepBook deployments: registry/admin/pool ids + market-maker\n\t\t * state. (Pool prices / order books are chain-direct.) */\n\t\tdeepbookInfo: t.field({\n\t\t\ttype: [DeepbookInfo],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.deepbook),\n\t\t}),\n\t\t/** Seal key-server deployments: objectId/threshold/mode/keyServers. */\n\t\tsealInfo: t.field({\n\t\t\ttype: [SealInfo],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.seal),\n\t\t}),\n\t\t/** Coin treasury caps (drives Mint) + addressing facts. (Supply /\n\t\t * metadata are chain-direct.) */\n\t\tcoinCaps: t.field({\n\t\t\ttype: [CoinCap],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.coinCaps),\n\t\t}),\n\t\t/** Coins the faucet can actually fund right now (drives the Faucet\n\t\t * panel's coin pills + amount gating). SUI is always present when a\n\t\t * faucet strategy is registered; WAL/DEEP appear only when their\n\t\t * plugin contributed a funding strategy. */\n\t\tfundableCoins: t.field({\n\t\t\ttype: [FundableCoin],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.pluginDomain.fundableCoins),\n\t\t}),\n\t\t// --- Observability (Console \"Logs\" tab) ---------------------------\n\t\t/** Cross-service queryable log history. Filterable server-side by\n\t\t * service / level / substring / time window; returns most-recent\n\t\t * first, capped by `filter.limit` (default = ring capacity). */\n\t\tlogs: t.field({\n\t\t\ttype: [LogRecordType],\n\t\t\targs: { filter: t.arg({ type: LogFilterInput, required: false }) },\n\t\t\tresolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.logs(toLogFilter(args.filter))),\n\t\t}),\n\t\t/** Distinct services currently in the log ring (filter dropdown). */\n\t\tlogServices: t.field({\n\t\t\ttype: ['String'],\n\t\t\tresolve: (_parent, _args, ctx) => Effect.runPromise(ctx.domain.logServices),\n\t\t}),\n\t}),\n});\n\n/** Closed log-level set used to narrow the String[] filter input back onto\n * the store's `LogLevel` union. Unknown strings are dropped (the store would\n * just never match them anyway). */\nconst LOG_LEVELS: ReadonlySet<LogLevel> = new Set<LogLevel>([\n\t'trace',\n\t'debug',\n\t'info',\n\t'warn',\n\t'error',\n\t'fatal',\n]);\n\nconst nonEmpty = (xs: readonly (string | null)[] | null | undefined): string[] | undefined => {\n\tif (xs == null) return undefined;\n\tconst out = xs.filter((x): x is string => x != null && x.length > 0);\n\treturn out.length > 0 ? out : undefined;\n};\n\n/** Map the nullable GraphQL `LogFilter` input onto the store's `LogFilter`,\n * dropping nulls and unknown levels. */\nconst toLogFilter = (\n\tinput:\n\t\t| {\n\t\t\t\tservices?: readonly (string | null)[] | null;\n\t\t\t\tlevels?: readonly (string | null)[] | null;\n\t\t\t\tsearch?: string | null;\n\t\t\t\tsinceMillis?: number | null;\n\t\t\t\tlimit?: number | null;\n\t\t }\n\t\t| null\n\t\t| undefined,\n): LogFilter | undefined => {\n\tif (input == null) return undefined;\n\tconst services = nonEmpty(input.services);\n\tconst levelStrings = nonEmpty(input.levels);\n\tconst levels = levelStrings?.filter((l): l is LogLevel => LOG_LEVELS.has(l as LogLevel));\n\treturn {\n\t\t...(services ? { services } : {}),\n\t\t...(levels && levels.length > 0 ? { levels } : {}),\n\t\t...(input.search != null ? { search: input.search } : {}),\n\t\t...(input.sinceMillis != null ? { sinceMillis: input.sinceMillis } : {}),\n\t\t...(input.limit != null ? { limit: input.limit } : {}),\n\t};\n};\n\n// --- Mutation -----------------------------------------------------------\nbuilder.mutationType({\n\tfields: (t) => ({\n\t\t/** Restart the whole stack. */\n\t\trestart: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'stack.restart', { tag: 'stack.restart' }),\n\t\t}),\n\t\t/** Selectively restart a single plugin subgraph. */\n\t\trestartPlugin: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { pluginKey: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'selective-restart.requested', {\n\t\t\t\t\ttag: 'selective-restart.requested',\n\t\t\t\t\tpluginKey: args.input.pluginKey as PluginKey,\n\t\t\t\t}),\n\t\t}),\n\t\t/** Capture a snapshot, optionally naming it. */\n\t\tcaptureSnapshot: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { name: t.input.string({ required: false }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'snapshot.capture', {\n\t\t\t\t\ttag: 'snapshot.capture',\n\t\t\t\t\t...(args.input.name == null ? {} : { name: args.input.name }),\n\t\t\t\t}),\n\t\t}),\n\t\t/** Re-run codegen against the live manifest. */\n\t\tcodegen: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'codegen.requested', { tag: 'codegen.requested' }),\n\t\t}),\n\t\t/** Re-apply the manifest, optionally scoped to a single plugin. */\n\t\tapply: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { pluginKey: t.input.string({ required: false }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'apply.requested', {\n\t\t\t\t\ttag: 'apply.requested',\n\t\t\t\t\t...(args.input.pluginKey == null ? {} : { pluginKey: args.input.pluginKey as PluginKey }),\n\t\t\t\t}),\n\t\t}),\n\t\t/** Wipe the live stack footprint (preserves the snapshot catalog). */\n\t\twipe: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'wipe.requested', { tag: 'wipe.requested' }),\n\t\t}),\n\t\t/** Prune the snapshot catalog + sweep byproduct images. */\n\t\tprune: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) => run(ctx, 'prune.requested', { tag: 'prune.requested' }),\n\t\t}),\n\t\t/** Advance the (fork/local) chain clock to an absolute epoch-ms. */\n\t\tadvanceClock: t.fieldWithInput({\n\t\t\ttype: CommandResult,\n\t\t\tinput: { toMillis: t.input.float({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\trun(ctx, 'advance-clock.requested', {\n\t\t\t\t\ttag: 'advance-clock.requested',\n\t\t\t\t\ttoMillis: args.input.toMillis,\n\t\t\t\t}),\n\t\t}),\n\t\t/** Request a graceful stack shutdown. */\n\t\tshutdown: t.field({\n\t\t\ttype: CommandResult,\n\t\t\tresolve: (_parent, _args, ctx) =>\n\t\t\t\trun(ctx, 'shutdown.requested', { tag: 'shutdown.requested' }),\n\t\t}),\n\t\t/** Restore a snapshot by id. Routes through the supervisor\n\t\t * command-loop via `submitCommand` (NOT the in-process\n\t\t * `domain.restoreSnapshot`): restore is destructive — it removes the\n\t\t * live managed containers and relies on a follow-on re-acquire to\n\t\t * rebuild them. Running it in-process against a live supervisor would\n\t\t * race the single command-queue consumer and leave services dead until\n\t\t * a manual Restart. The command-loop's `snapshot.restore` case applies\n\t\t * the restored tree, publishes `snapshot.restored`, THEN drains +\n\t\t * re-acquires every service (the manual-restart sequence) — and the\n\t\t * submitted-command completion deferred lets this mutation await the\n\t\t * real ok/detail outcome the void `publishCommand` could not carry. */\n\t\trestoreSnapshot: t.fieldWithInput({\n\t\t\ttype: SnapshotActionResult,\n\t\t\tinput: { id: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(\n\t\t\t\t\tctx.submitCommand({ tag: 'snapshot.restore', snapshotId: args.input.id }).pipe(\n\t\t\t\t\t\tEffect.as({ ok: true, detail: null as string | null }),\n\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\tEffect.succeed({ ok: false, detail: String(cause) as string | null }),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t}),\n\t\t/** Delete a snapshot by id (via the control-plane `domain`). */\n\t\tdeleteSnapshot: t.fieldWithInput({\n\t\t\ttype: SnapshotActionResult,\n\t\t\tinput: { id: t.input.string({ required: true }) },\n\t\t\tresolve: (_parent, args, ctx) => Effect.runPromise(ctx.domain.deleteSnapshot(args.input.id)),\n\t\t}),\n\t\t/** Mint a custom coin. Routes through the control-plane `domain`:\n\t\t * the supervisor holds the treasury-cap-owning publisher signer\n\t\t * in-process and returns a real ok/detail/digest result (the void\n\t\t * `publishCommand` could not carry the tx digest). `amountBaseUnits`\n\t\t * is the raw integer amount in the coin's smallest unit (string so\n\t\t * large u64 values survive the wire without precision loss). */\n\t\tmint: t.fieldWithInput({\n\t\t\ttype: MintResult,\n\t\t\tinput: {\n\t\t\t\tcoinType: t.input.string({ required: true }),\n\t\t\t\trecipient: t.input.string({ required: true }),\n\t\t\t\tamountBaseUnits: t.input.string({ required: true }),\n\t\t\t},\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(\n\t\t\t\t\tctx.pluginDomain.mintCoin({\n\t\t\t\t\t\tcoinType: args.input.coinType,\n\t\t\t\t\t\trecipient: args.input.recipient,\n\t\t\t\t\t\tamountBaseUnits: args.input.amountBaseUnits,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t}),\n\t\t/** Fund an account/address. Routes through the control-plane\n\t\t * `pluginDomain`, reusing devstack's in-process funding strategies:\n\t\t * SUI (absent / canonical `coinType`) via the chain faucet strategy\n\t\t * (fixed-amount — `amountBaseUnits` is ignored); WAL/DEEP via the\n\t\t * coin-specific account-signed swap (`amountBaseUnits` honored, and\n\t\t * the recipient must be a resolved account). Real result — `ok`\n\t\t * reflects whether the strategy completed. */\n\t\tfund: t.fieldWithInput({\n\t\t\ttype: FundResult,\n\t\t\tinput: {\n\t\t\t\trecipient: t.input.string({ required: true }),\n\t\t\t\tcoinType: t.input.string({ required: false }),\n\t\t\t\tamountBaseUnits: t.input.string({ required: false }),\n\t\t\t},\n\t\t\tresolve: (_parent, args, ctx) =>\n\t\t\t\tEffect.runPromise(\n\t\t\t\t\tctx.pluginDomain.fundAccount({\n\t\t\t\t\t\trecipient: args.input.recipient,\n\t\t\t\t\t\tcoinType: args.input.coinType,\n\t\t\t\t\t\tamountBaseUnits: args.input.amountBaseUnits,\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t}),\n\t}),\n});\n\n// --- Subscription -------------------------------------------------------\nbuilder.subscriptionType({\n\tfields: (t) => ({\n\t\t/** Stream the projection on every change (current value first). */\n\t\tstate: t.field({\n\t\t\ttype: StackState,\n\t\t\tsubscribe: (_parent, _args, ctx) => subscribeState(ctx.state),\n\t\t\tresolve: (payload) => payload,\n\t\t}),\n\t}),\n});\n\n/** Bridge an Effect `SubscriptionRef` to an async iterable for GraphQL\n * subscriptions. `SubscriptionRef.changes` emits the current value first,\n * then each subsequent update. The pump fiber is interrupted when the\n * consumer (yoga) stops iterating. */\nasync function* subscribeState(\n\tref: SubscriptionRef.SubscriptionRef<SubscribableState>,\n): AsyncGenerator<SubscribableState> {\n\tconst queue = Effect.runSync(Queue.unbounded<SubscribableState>());\n\tconst pump = Effect.runFork(\n\t\tStream.runForEach(SubscriptionRef.changes(ref), (snapshot) => Queue.offer(queue, snapshot)),\n\t);\n\ttry {\n\t\twhile (true) {\n\t\t\tyield await Effect.runPromise(Queue.take(queue));\n\t\t}\n\t} finally {\n\t\tEffect.runFork(Fiber.interrupt(pump));\n\t}\n}\n"],"mappings":"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"}