@mysten-incubation/devstack 0.0.1 → 0.1.1

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 (838) hide show
  1. package/README.md +8 -4
  2. package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  3. package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  4. package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  5. package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  6. package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  7. package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  8. package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  9. package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  10. package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  11. package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  12. package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  13. package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
  14. package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
  15. package/dashboard-ui/assets/index-Deml9drg.css +1 -0
  16. package/dashboard-ui/index.html +13 -0
  17. package/dist/api/define-capabilities.d.mts +14 -3
  18. package/dist/api/define-capabilities.mjs +18 -1
  19. package/dist/api/define-capabilities.mjs.map +1 -1
  20. package/dist/api/define-devstack.d.mts +1 -1
  21. package/dist/api/define-devstack.mjs +6 -26
  22. package/dist/api/define-devstack.mjs.map +1 -1
  23. package/dist/api/define-plugin.d.mts +1 -0
  24. package/dist/api/define-plugin.mjs +2 -0
  25. package/dist/api/inference-network.d.mts +132 -0
  26. package/dist/api/inference-network.mjs +105 -16
  27. package/dist/api/inference-network.mjs.map +1 -1
  28. package/dist/api/plugin-errors.d.mts +7 -0
  29. package/dist/api/run-stack.d.mts +20 -9
  30. package/dist/api/run-stack.mjs +56 -29
  31. package/dist/api/run-stack.mjs.map +1 -1
  32. package/dist/build-integrations/playwright/config.d.mts +6 -4
  33. package/dist/build-integrations/playwright/config.mjs +5 -3
  34. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  35. package/dist/build-integrations/playwright/errors.d.mts +1 -1
  36. package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
  37. package/dist/build-integrations/playwright/global-setup.mjs +250 -13
  38. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  39. package/dist/build-integrations/playwright/index.d.mts +5 -3
  40. package/dist/build-integrations/playwright/index.mjs +4 -2
  41. package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
  42. package/dist/build-integrations/playwright/stack-context.mjs +24 -63
  43. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  44. package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
  45. package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
  46. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  47. package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
  48. package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
  49. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
  51. package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
  52. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
  53. package/dist/build-integrations/runtime/discover.d.mts +38 -30
  54. package/dist/build-integrations/runtime/discover.mjs +73 -70
  55. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
  57. package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
  58. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  59. package/dist/build-integrations/runtime/index.d.mts +7 -2
  60. package/dist/build-integrations/runtime/index.mjs +9 -2
  61. package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
  62. package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
  63. package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
  64. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
  65. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
  66. package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
  67. package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
  68. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  69. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
  70. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
  71. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
  72. package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
  73. package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
  74. package/dist/build-integrations/vite/index.d.mts +51 -0
  75. package/dist/build-integrations/vite/index.mjs +73 -0
  76. package/dist/build-integrations/vite/index.mjs.map +1 -0
  77. package/dist/build-integrations/vitest/env.d.mts +4 -3
  78. package/dist/build-integrations/vitest/env.mjs +6 -4
  79. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  80. package/dist/build-integrations/vitest/errors.d.mts +25 -4
  81. package/dist/build-integrations/vitest/errors.mjs +15 -2
  82. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  83. package/dist/build-integrations/vitest/index.d.mts +2 -2
  84. package/dist/build-integrations/vitest/index.mjs +3 -3
  85. package/dist/build-integrations/vitest/setup.d.mts +4 -2
  86. package/dist/build-integrations/vitest/setup.mjs +2 -2
  87. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  88. package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
  89. package/dist/build-integrations/vitest/stack-context.mjs +33 -13
  90. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  91. package/dist/cli/bail.mjs +23 -0
  92. package/dist/cli/bail.mjs.map +1 -0
  93. package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
  94. package/dist/cli/doctor-probes.mjs.map +1 -0
  95. package/dist/cli/main.d.mts +15 -1
  96. package/dist/cli/main.mjs +166 -482
  97. package/dist/cli/main.mjs.map +1 -1
  98. package/dist/cli/prune-direct.mjs +31 -201
  99. package/dist/cli/prune-direct.mjs.map +1 -1
  100. package/dist/cli/snapshot-reader.mjs +14 -11
  101. package/dist/cli/snapshot-reader.mjs.map +1 -1
  102. package/dist/cli/up-lifecycle.mjs +4 -1
  103. package/dist/cli/up-lifecycle.mjs.map +1 -1
  104. package/dist/cli/wirings/apply.mjs +95 -0
  105. package/dist/cli/wirings/apply.mjs.map +1 -0
  106. package/dist/cli/wirings/build-verb-layers.mjs +42 -0
  107. package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
  108. package/dist/cli/wirings/config-loader.mjs +69 -0
  109. package/dist/cli/wirings/config-loader.mjs.map +1 -0
  110. package/dist/cli/wirings/engine-command.mjs +30 -0
  111. package/dist/cli/wirings/engine-command.mjs.map +1 -0
  112. package/dist/cli/wirings/identity.mjs +72 -0
  113. package/dist/cli/wirings/identity.mjs.map +1 -0
  114. package/dist/cli/wirings/provide-file-system.mjs +7 -0
  115. package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
  116. package/dist/cli/wirings/snapshot.mjs +177 -0
  117. package/dist/cli/wirings/snapshot.mjs.map +1 -0
  118. package/dist/cli/wirings/up.mjs +287 -0
  119. package/dist/cli/wirings/up.mjs.map +1 -0
  120. package/dist/cli/wirings/wipe.mjs +40 -0
  121. package/dist/cli/wirings/wipe.mjs.map +1 -0
  122. package/dist/contracts/capability-decl.d.mts +0 -2
  123. package/dist/contracts/codegenable.d.mts +43 -0
  124. package/dist/contracts/container-runtime.d.mts +26 -1
  125. package/dist/contracts/faucet-strategy.d.mts +25 -0
  126. package/dist/contracts/funding-strategy.d.mts +42 -0
  127. package/dist/contracts/plugin-expander.mjs +60 -0
  128. package/dist/contracts/plugin-expander.mjs.map +1 -0
  129. package/dist/contracts/projection.d.mts +5 -3
  130. package/dist/contracts/renderer.d.mts +23 -0
  131. package/dist/contracts/routable.d.mts +14 -1
  132. package/dist/contracts/snapshotable.d.mts +25 -3
  133. package/dist/contracts/wallet-protocol.d.mts +52 -0
  134. package/dist/contracts/wallet-protocol.mjs +52 -0
  135. package/dist/contracts/wallet-protocol.mjs.map +1 -0
  136. package/dist/index.d.mts +26 -25
  137. package/dist/index.mjs +20 -13
  138. package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
  139. package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
  140. package/dist/orchestrators/codegen/bindings.d.mts +1 -2
  141. package/dist/orchestrators/codegen/bindings.mjs +52 -186
  142. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/emit.mjs +19 -1
  144. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  145. package/dist/orchestrators/codegen/errors.mjs +8 -3
  146. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/format.mjs +47 -39
  148. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/gitignore.mjs +3 -1
  150. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  151. package/dist/orchestrators/codegen/output-location.mjs +41 -0
  152. package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
  153. package/dist/orchestrators/codegen/paths.d.mts +1 -1
  154. package/dist/orchestrators/codegen/paths.mjs +40 -14
  155. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  156. package/dist/orchestrators/codegen/permissions.mjs +3 -1
  157. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  158. package/dist/orchestrators/codegen/service.mjs +157 -105
  159. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  160. package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
  161. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
  162. package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
  163. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
  164. package/dist/orchestrators/router/cleanup.mjs +26 -27
  165. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  166. package/dist/orchestrators/router/entrypoints.mjs +2 -2
  167. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  168. package/dist/orchestrators/router/file-provider.mjs +14 -5
  169. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  170. package/dist/orchestrators/router/hostname.mjs +19 -55
  171. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  172. package/dist/orchestrators/router/index.mjs +11 -0
  173. package/dist/orchestrators/router/profile.mjs +2 -2
  174. package/dist/orchestrators/router/sentinels.mjs +26 -0
  175. package/dist/orchestrators/router/sentinels.mjs.map +1 -0
  176. package/dist/orchestrators/router/service.mjs +40 -37
  177. package/dist/orchestrators/router/service.mjs.map +1 -1
  178. package/dist/orchestrators/router/traefik-container.mjs +27 -16
  179. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  180. package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
  181. package/dist/orchestrators/run.mjs.map +1 -0
  182. package/dist/orchestrators/runtime-composition.d.mts +1 -1
  183. package/dist/orchestrators/runtime-composition.mjs +123 -39
  184. package/dist/orchestrators/runtime-composition.mjs.map +1 -1
  185. package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
  186. package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
  187. package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
  188. package/dist/orchestrators/snapshot/capture.mjs +42 -28
  189. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  190. package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
  191. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  192. package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
  193. package/dist/orchestrators/snapshot/index.mjs +13 -0
  194. package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
  195. package/dist/orchestrators/snapshot/integrity.mjs +73 -17
  196. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  197. package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
  198. package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
  199. package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
  200. package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
  201. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
  202. package/dist/orchestrators/snapshot/prune.mjs +20 -55
  203. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  204. package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
  205. package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
  206. package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
  207. package/dist/orchestrators/snapshot/restore.mjs +118 -84
  208. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  209. package/dist/orchestrators/snapshot/service.mjs +53 -56
  210. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  211. package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
  212. package/dist/orchestrators/snapshot/state-document.mjs +47 -7
  213. package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
  214. package/dist/orchestrators/snapshot/wipe.mjs +67 -10
  215. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  216. package/dist/plugins/account/codegen.mjs +9 -8
  217. package/dist/plugins/account/codegen.mjs.map +1 -1
  218. package/dist/plugins/account/errors.d.mts +33 -6
  219. package/dist/plugins/account/errors.mjs.map +1 -1
  220. package/dist/plugins/account/funding.d.mts +29 -19
  221. package/dist/plugins/account/funding.mjs +84 -66
  222. package/dist/plugins/account/funding.mjs.map +1 -1
  223. package/dist/plugins/account/index.d.mts +2 -4
  224. package/dist/plugins/account/index.mjs +64 -31
  225. package/dist/plugins/account/index.mjs.map +1 -1
  226. package/dist/plugins/account/keypair.mjs +6 -9
  227. package/dist/plugins/account/keypair.mjs.map +1 -1
  228. package/dist/plugins/account/lease.mjs +1 -0
  229. package/dist/plugins/account/lease.mjs.map +1 -1
  230. package/dist/plugins/account/registry.d.mts +14 -1
  231. package/dist/plugins/account/registry.mjs +18 -18
  232. package/dist/plugins/account/registry.mjs.map +1 -1
  233. package/dist/plugins/account/service.d.mts +23 -4
  234. package/dist/plugins/account/service.mjs +83 -45
  235. package/dist/plugins/account/service.mjs.map +1 -1
  236. package/dist/plugins/account/snapshot.mjs +2 -5
  237. package/dist/plugins/account/snapshot.mjs.map +1 -1
  238. package/dist/plugins/account/spans.mjs +16 -0
  239. package/dist/plugins/account/spans.mjs.map +1 -0
  240. package/dist/plugins/account/variants/keystore.mjs +6 -8
  241. package/dist/plugins/account/variants/keystore.mjs.map +1 -1
  242. package/dist/plugins/action/build-context.d.mts +3 -2
  243. package/dist/plugins/action/errors.d.mts +16 -12
  244. package/dist/plugins/action/errors.mjs.map +1 -1
  245. package/dist/plugins/action/execute.mjs +65 -103
  246. package/dist/plugins/action/execute.mjs.map +1 -1
  247. package/dist/plugins/action/index.d.mts +0 -2
  248. package/dist/plugins/action/index.mjs +17 -13
  249. package/dist/plugins/action/index.mjs.map +1 -1
  250. package/dist/plugins/action/service.mjs +38 -35
  251. package/dist/plugins/action/service.mjs.map +1 -1
  252. package/dist/plugins/action/spans.mjs +11 -0
  253. package/dist/plugins/action/spans.mjs.map +1 -0
  254. package/dist/plugins/coin/codegen.mjs +9 -8
  255. package/dist/plugins/coin/codegen.mjs.map +1 -1
  256. package/dist/plugins/coin/discovery.mjs +8 -4
  257. package/dist/plugins/coin/discovery.mjs.map +1 -1
  258. package/dist/plugins/coin/index.d.mts +11 -29
  259. package/dist/plugins/coin/index.mjs +56 -27
  260. package/dist/plugins/coin/index.mjs.map +1 -1
  261. package/dist/plugins/coin/metadata.mjs +8 -15
  262. package/dist/plugins/coin/metadata.mjs.map +1 -1
  263. package/dist/plugins/coin/mint.d.mts +30 -11
  264. package/dist/plugins/coin/mint.mjs +78 -74
  265. package/dist/plugins/coin/mint.mjs.map +1 -1
  266. package/dist/plugins/coin/registry.mjs +4 -7
  267. package/dist/plugins/coin/registry.mjs.map +1 -1
  268. package/dist/plugins/coin/service.d.mts +39 -1
  269. package/dist/plugins/coin/service.mjs +11 -4
  270. package/dist/plugins/coin/service.mjs.map +1 -1
  271. package/dist/plugins/coin/spans.mjs +20 -0
  272. package/dist/plugins/coin/spans.mjs.map +1 -0
  273. package/dist/plugins/dashboard/domain.mjs +402 -0
  274. package/dist/plugins/dashboard/domain.mjs.map +1 -0
  275. package/dist/plugins/dashboard/index.d.mts +29 -0
  276. package/dist/plugins/dashboard/index.mjs +91 -0
  277. package/dist/plugins/dashboard/index.mjs.map +1 -0
  278. package/dist/plugins/dashboard/origin-policy.mjs +36 -0
  279. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
  280. package/dist/plugins/dashboard/routable.mjs +27 -0
  281. package/dist/plugins/dashboard/routable.mjs.map +1 -0
  282. package/dist/plugins/dashboard/schema/builder.mjs +21 -0
  283. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
  284. package/dist/plugins/dashboard/schema/enums.mjs +72 -0
  285. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
  286. package/dist/plugins/dashboard/schema/root.mjs +351 -0
  287. package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
  288. package/dist/plugins/dashboard/schema/types.mjs +508 -0
  289. package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
  290. package/dist/plugins/dashboard/schema.mjs +11 -0
  291. package/dist/plugins/dashboard/schema.mjs.map +1 -0
  292. package/dist/plugins/dashboard/server.mjs +166 -0
  293. package/dist/plugins/dashboard/server.mjs.map +1 -0
  294. package/dist/plugins/deepbook/deploy.mjs +53 -115
  295. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  296. package/dist/plugins/deepbook/errors.mjs +1 -0
  297. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  298. package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
  299. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  300. package/dist/plugins/deepbook/hash.mjs +9 -0
  301. package/dist/plugins/deepbook/hash.mjs.map +1 -0
  302. package/dist/plugins/deepbook/index.d.mts +1 -10
  303. package/dist/plugins/deepbook/index.mjs +25 -22
  304. package/dist/plugins/deepbook/index.mjs.map +1 -1
  305. package/dist/plugins/deepbook/pyth/index.mjs +26 -55
  306. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  307. package/dist/plugins/deepbook/snapshot.mjs +17 -29
  308. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  309. package/dist/plugins/deepbook/spans.mjs +18 -0
  310. package/dist/plugins/deepbook/spans.mjs.map +1 -0
  311. package/dist/plugins/deepbook/type-strings.mjs +65 -0
  312. package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
  313. package/dist/plugins/deepbook/types.d.mts +2 -3
  314. package/dist/plugins/deepbook/types.mjs.map +1 -1
  315. package/dist/plugins/faucet/dispatcher.d.mts +21 -2
  316. package/dist/plugins/faucet/dispatcher.mjs +1 -2
  317. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  318. package/dist/plugins/faucet/errors.d.mts +11 -24
  319. package/dist/plugins/faucet/errors.mjs.map +1 -1
  320. package/dist/plugins/faucet/http.mjs +33 -14
  321. package/dist/plugins/faucet/http.mjs.map +1 -1
  322. package/dist/plugins/faucet/index.d.mts +15 -5
  323. package/dist/plugins/faucet/index.mjs +3 -0
  324. package/dist/plugins/faucet/index.mjs.map +1 -1
  325. package/dist/plugins/faucet/spans.mjs +12 -0
  326. package/dist/plugins/faucet/spans.mjs.map +1 -0
  327. package/dist/plugins/host-service/errors.d.mts +1 -1
  328. package/dist/plugins/host-service/index.mjs +34 -8
  329. package/dist/plugins/host-service/index.mjs.map +1 -1
  330. package/dist/plugins/host-service/routable.mjs +2 -1
  331. package/dist/plugins/host-service/routable.mjs.map +1 -1
  332. package/dist/plugins/host-service/service.d.mts +21 -0
  333. package/dist/plugins/host-service/service.mjs +136 -81
  334. package/dist/plugins/host-service/service.mjs.map +1 -1
  335. package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
  336. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
  337. package/dist/plugins/internal/codegen-helpers.mjs +18 -0
  338. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
  339. package/dist/plugins/internal/funding-failure-error.mjs +32 -0
  340. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
  341. package/dist/plugins/package/build.mjs +1 -1
  342. package/dist/plugins/package/build.mjs.map +1 -1
  343. package/dist/plugins/package/codegen.mjs +26 -0
  344. package/dist/plugins/package/codegen.mjs.map +1 -1
  345. package/dist/plugins/package/errors.d.mts +16 -6
  346. package/dist/plugins/package/errors.mjs.map +1 -1
  347. package/dist/plugins/package/index.d.mts +0 -4
  348. package/dist/plugins/package/index.mjs +27 -21
  349. package/dist/plugins/package/index.mjs.map +1 -1
  350. package/dist/plugins/package/mode-known.mjs +26 -12
  351. package/dist/plugins/package/mode-known.mjs.map +1 -1
  352. package/dist/plugins/package/mode-local.mjs +47 -41
  353. package/dist/plugins/package/mode-local.mjs.map +1 -1
  354. package/dist/plugins/package/publish-executor.mjs +55 -114
  355. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  356. package/dist/plugins/package/registry.mjs +2 -1
  357. package/dist/plugins/package/registry.mjs.map +1 -1
  358. package/dist/plugins/package/service.mjs.map +1 -1
  359. package/dist/plugins/package/spans.mjs +14 -0
  360. package/dist/plugins/package/spans.mjs.map +1 -0
  361. package/dist/plugins/postgres/db-ensure.mjs +19 -12
  362. package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
  363. package/dist/plugins/postgres/errors.d.mts +5 -0
  364. package/dist/plugins/postgres/errors.mjs.map +1 -1
  365. package/dist/plugins/postgres/index.mjs +10 -17
  366. package/dist/plugins/postgres/index.mjs.map +1 -1
  367. package/dist/plugins/postgres/service.mjs +58 -24
  368. package/dist/plugins/postgres/service.mjs.map +1 -1
  369. package/dist/plugins/postgres/snapshot.mjs.map +1 -1
  370. package/dist/plugins/postgres/spans.mjs +11 -0
  371. package/dist/plugins/postgres/spans.mjs.map +1 -0
  372. package/dist/plugins/router-entrypoints.mjs +4 -4
  373. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  374. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
  375. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  376. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
  377. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  378. package/dist/plugins/seal/codegen.d.mts +2 -3
  379. package/dist/plugins/seal/codegen.mjs.map +1 -1
  380. package/dist/plugins/seal/config-render.mjs +35 -8
  381. package/dist/plugins/seal/config-render.mjs.map +1 -1
  382. package/dist/plugins/seal/deploy.mjs +31 -39
  383. package/dist/plugins/seal/deploy.mjs.map +1 -1
  384. package/dist/plugins/seal/errors.d.mts +1 -3
  385. package/dist/plugins/seal/errors.mjs +7 -1
  386. package/dist/plugins/seal/errors.mjs.map +1 -1
  387. package/dist/plugins/seal/index.d.mts +1 -6
  388. package/dist/plugins/seal/index.mjs +40 -14
  389. package/dist/plugins/seal/index.mjs.map +1 -1
  390. package/dist/plugins/seal/key-manager.d.mts +1 -9
  391. package/dist/plugins/seal/key-manager.mjs +2 -18
  392. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  393. package/dist/plugins/seal/key-server.mjs +37 -36
  394. package/dist/plugins/seal/key-server.mjs.map +1 -1
  395. package/dist/plugins/seal/keygen.mjs +16 -17
  396. package/dist/plugins/seal/keygen.mjs.map +1 -1
  397. package/dist/plugins/seal/mode/fork-known.mjs +36 -14
  398. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  399. package/dist/plugins/seal/mode/live.d.mts +6 -4
  400. package/dist/plugins/seal/mode/live.mjs +14 -21
  401. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  402. package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
  403. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  404. package/dist/plugins/seal/registry-publish.mjs +1 -0
  405. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  406. package/dist/plugins/seal/routable.mjs.map +1 -1
  407. package/dist/plugins/seal/service.mjs.map +1 -1
  408. package/dist/plugins/seal/spans.mjs +18 -0
  409. package/dist/plugins/seal/spans.mjs.map +1 -0
  410. package/dist/plugins/sui/auto-tick.mjs +17 -23
  411. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  412. package/dist/plugins/sui/chain-build-container.mjs +18 -0
  413. package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
  414. package/dist/plugins/sui/chain-probe.d.mts +5 -5
  415. package/dist/plugins/sui/chain-probe.mjs +28 -58
  416. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  417. package/dist/plugins/sui/codegen.mjs +26 -0
  418. package/dist/plugins/sui/codegen.mjs.map +1 -1
  419. package/dist/plugins/sui/errors.d.mts +2 -29
  420. package/dist/plugins/sui/errors.mjs +1 -3
  421. package/dist/plugins/sui/errors.mjs.map +1 -1
  422. package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
  423. package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
  424. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
  425. package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
  426. package/dist/plugins/sui/fork-orchestration.mjs +170 -2
  427. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  428. package/dist/plugins/sui/fork-transaction.d.mts +2 -0
  429. package/dist/plugins/sui/fork-transaction.mjs +92 -28
  430. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  431. package/dist/plugins/sui/index.d.mts +33 -70
  432. package/dist/plugins/sui/index.mjs +58 -35
  433. package/dist/plugins/sui/index.mjs.map +1 -1
  434. package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
  435. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
  436. package/dist/plugins/sui/mode/external.mjs +7 -13
  437. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  438. package/dist/plugins/sui/mode/fork.mjs +136 -59
  439. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  440. package/dist/plugins/sui/mode/live.mjs +10 -16
  441. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  442. package/dist/plugins/sui/mode/local.mjs +37 -36
  443. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  444. package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
  445. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  446. package/dist/plugins/sui/mode/shared.d.mts +1 -5
  447. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  448. package/dist/plugins/sui/mode/spec.d.mts +18 -0
  449. package/dist/plugins/sui/move-summary-runner.mjs +207 -0
  450. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
  451. package/dist/plugins/sui/network-resolver.d.mts +4 -3
  452. package/dist/plugins/sui/service.mjs.map +1 -1
  453. package/dist/plugins/sui/snapshot.mjs +3 -0
  454. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  455. package/dist/plugins/sui/spans.mjs +17 -0
  456. package/dist/plugins/sui/spans.mjs.map +1 -0
  457. package/dist/plugins/wallet/codegen.d.mts +0 -1
  458. package/dist/plugins/wallet/codegen.mjs +8 -9
  459. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  460. package/dist/plugins/wallet/index.d.mts +6 -8
  461. package/dist/plugins/wallet/index.mjs +46 -35
  462. package/dist/plugins/wallet/index.mjs.map +1 -1
  463. package/dist/plugins/wallet/origin-policy.mjs +12 -28
  464. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  465. package/dist/plugins/wallet/pairing.mjs +6 -4
  466. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  467. package/dist/plugins/wallet/protocol.d.mts +1 -0
  468. package/dist/plugins/wallet/protocol.mjs +5 -44
  469. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  470. package/dist/plugins/wallet/routable.mjs +2 -8
  471. package/dist/plugins/wallet/routable.mjs.map +1 -1
  472. package/dist/plugins/wallet/server.mjs +36 -44
  473. package/dist/plugins/wallet/server.mjs.map +1 -1
  474. package/dist/plugins/wallet/service.d.mts +1 -5
  475. package/dist/plugins/wallet/service.mjs +22 -18
  476. package/dist/plugins/wallet/service.mjs.map +1 -1
  477. package/dist/plugins/wallet/spans.mjs +22 -0
  478. package/dist/plugins/wallet/spans.mjs.map +1 -0
  479. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
  480. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  481. package/dist/plugins/walrus/codegen.d.mts +3 -3
  482. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  483. package/dist/plugins/walrus/deploy-paths.mjs +21 -5
  484. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  485. package/dist/plugins/walrus/deploy.mjs +67 -69
  486. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  487. package/dist/plugins/walrus/errors.mjs +1 -0
  488. package/dist/plugins/walrus/errors.mjs.map +1 -1
  489. package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
  490. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  491. package/dist/plugins/walrus/index.d.mts +2 -13
  492. package/dist/plugins/walrus/index.mjs +18 -23
  493. package/dist/plugins/walrus/index.mjs.map +1 -1
  494. package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
  495. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  496. package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
  497. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  498. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  499. package/dist/plugins/walrus/routable.mjs +7 -23
  500. package/dist/plugins/walrus/routable.mjs.map +1 -1
  501. package/dist/plugins/walrus/service.mjs.map +1 -1
  502. package/dist/plugins/walrus/spans.mjs +18 -0
  503. package/dist/plugins/walrus/spans.mjs.map +1 -0
  504. package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
  505. package/dist/plugins/walrus/storage-nodes.mjs +15 -8
  506. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  507. package/dist/plugins/walrus/wal-swap.mjs +58 -15
  508. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  509. package/dist/primitives/artifact-publisher.d.mts +1 -1
  510. package/dist/primitives/artifact-publisher.mjs +15 -0
  511. package/dist/primitives/artifact-publisher.mjs.map +1 -0
  512. package/dist/runtime/docker/client.mjs +17 -4
  513. package/dist/runtime/docker/client.mjs.map +1 -1
  514. package/dist/runtime/docker/container.mjs +219 -132
  515. package/dist/runtime/docker/container.mjs.map +1 -1
  516. package/dist/runtime/docker/errors.mjs +0 -6
  517. package/dist/runtime/docker/errors.mjs.map +1 -1
  518. package/dist/runtime/docker/exec.mjs +21 -18
  519. package/dist/runtime/docker/exec.mjs.map +1 -1
  520. package/dist/runtime/docker/image.mjs +36 -13
  521. package/dist/runtime/docker/image.mjs.map +1 -1
  522. package/dist/runtime/docker/index.mjs +14 -0
  523. package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
  524. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
  525. package/dist/runtime/docker/inventory.mjs +14 -11
  526. package/dist/runtime/docker/inventory.mjs.map +1 -1
  527. package/dist/runtime/docker/labels.mjs +38 -5
  528. package/dist/runtime/docker/labels.mjs.map +1 -1
  529. package/dist/runtime/docker/logs.d.mts +1 -1
  530. package/dist/runtime/docker/logs.mjs.map +1 -1
  531. package/dist/runtime/docker/network.mjs +83 -47
  532. package/dist/runtime/docker/network.mjs.map +1 -1
  533. package/dist/runtime/docker/render-run-args.mjs +82 -0
  534. package/dist/runtime/docker/render-run-args.mjs.map +1 -0
  535. package/dist/runtime/docker/service.d.mts +1 -1
  536. package/dist/runtime/docker/service.mjs +12 -7
  537. package/dist/runtime/docker/service.mjs.map +1 -1
  538. package/dist/runtime/docker/sweep.mjs +118 -43
  539. package/dist/runtime/docker/sweep.mjs.map +1 -1
  540. package/dist/runtime/docker/volume.mjs +2 -0
  541. package/dist/runtime/docker/volume.mjs.map +1 -1
  542. package/dist/runtime/docker/wrap.mjs +30 -1
  543. package/dist/runtime/docker/wrap.mjs.map +1 -1
  544. package/dist/substrate/cross-process.mjs +14 -8
  545. package/dist/substrate/cross-process.mjs.map +1 -1
  546. package/dist/substrate/event-time.mjs +33 -0
  547. package/dist/substrate/event-time.mjs.map +1 -0
  548. package/dist/substrate/events.d.mts +28 -8
  549. package/dist/substrate/identity.d.mts +2 -1
  550. package/dist/substrate/manifest.d.mts +68 -5
  551. package/dist/substrate/manifest.mjs +34 -5
  552. package/dist/substrate/manifest.mjs.map +1 -1
  553. package/dist/substrate/network.d.mts +3 -5
  554. package/dist/substrate/options.d.mts +0 -2
  555. package/dist/substrate/plugin.d.mts +13 -0
  556. package/dist/substrate/plugin.mjs +4 -2
  557. package/dist/substrate/plugin.mjs.map +1 -1
  558. package/dist/substrate/projection.d.mts +35 -3
  559. package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
  560. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
  561. package/dist/substrate/runtime/atomic-write.mjs +97 -32
  562. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  563. package/dist/substrate/runtime/cache/index.mjs +3 -0
  564. package/dist/substrate/runtime/cache/schema.mjs +2 -2
  565. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  566. package/dist/substrate/runtime/cache/service.mjs +9 -7
  567. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  568. package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
  569. package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
  570. package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
  571. package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
  572. package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
  573. package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
  574. package/dist/substrate/runtime/config-validation.d.mts +1 -13
  575. package/dist/substrate/runtime/config-validation.mjs +2 -91
  576. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  577. package/dist/substrate/runtime/container-runtime.d.mts +1 -0
  578. package/dist/substrate/runtime/container-runtime.mjs +2 -0
  579. package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
  580. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
  581. package/dist/substrate/runtime/control-plane/service.mjs +7 -0
  582. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
  583. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
  584. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  585. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
  586. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  587. package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
  588. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
  589. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  590. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
  591. package/dist/substrate/runtime/cross-process/index.mjs +11 -0
  592. package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
  593. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
  594. package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
  595. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  596. package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
  597. package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
  598. package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
  599. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
  600. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
  601. package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
  602. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  603. package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
  604. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
  605. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
  606. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
  607. package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
  608. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  609. package/dist/substrate/runtime/current-plugin.mjs +2 -2
  610. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  611. package/dist/substrate/runtime/errors.mjs +12 -6
  612. package/dist/substrate/runtime/errors.mjs.map +1 -1
  613. package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
  614. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
  615. package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
  616. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
  617. package/dist/substrate/runtime/host-gateway.mjs +20 -0
  618. package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
  619. package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
  620. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  621. package/dist/substrate/runtime/http-probe.d.mts +1 -1
  622. package/dist/substrate/runtime/index.mjs +14 -0
  623. package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
  624. package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
  625. package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
  626. package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
  627. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  628. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
  629. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  630. package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
  631. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
  632. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
  633. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  634. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
  635. package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
  636. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  637. package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
  638. package/dist/substrate/runtime/managed-container.d.mts +19 -1
  639. package/dist/substrate/runtime/managed-container.mjs +20 -1
  640. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  641. package/dist/substrate/runtime/manifest/index.mjs +3 -0
  642. package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
  643. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  644. package/dist/substrate/runtime/mode-errors.mjs +20 -0
  645. package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
  646. package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
  647. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  648. package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
  649. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
  650. package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
  651. package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
  652. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
  653. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  654. package/dist/substrate/runtime/observability/index.mjs +13 -0
  655. package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
  656. package/dist/substrate/runtime/observability/log-store.mjs +175 -0
  657. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
  658. package/dist/substrate/runtime/observability/logger.d.mts +2 -1
  659. package/dist/substrate/runtime/observability/logger.mjs +5 -9
  660. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  661. package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
  662. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
  663. package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
  664. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  665. package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
  666. package/dist/substrate/runtime/observability/redaction.mjs +8 -14
  667. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  668. package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
  669. package/dist/substrate/runtime/observability/span-store.mjs +110 -0
  670. package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
  671. package/dist/substrate/runtime/observability/spans.mjs +14 -14
  672. package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
  673. package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
  674. package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
  675. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
  676. package/dist/substrate/runtime/paths.d.mts +1 -1
  677. package/dist/substrate/runtime/paths.mjs +4 -3
  678. package/dist/substrate/runtime/paths.mjs.map +1 -1
  679. package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
  680. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
  681. package/dist/substrate/runtime/port-broker/index.mjs +3 -0
  682. package/dist/substrate/runtime/port-broker/service.mjs +170 -126
  683. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  684. package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
  685. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  686. package/dist/substrate/runtime/probes.d.mts +7 -5
  687. package/dist/substrate/runtime/probes.mjs +3 -1
  688. package/dist/substrate/runtime/probes.mjs.map +1 -1
  689. package/dist/substrate/runtime/projection/index.mjs +4 -0
  690. package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
  691. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  692. package/dist/substrate/runtime/projection/persisted.mjs +33 -15
  693. package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
  694. package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
  695. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  696. package/dist/substrate/runtime/projection/update.mjs +88 -24
  697. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  698. package/dist/substrate/runtime/random-suffix.mjs +11 -0
  699. package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
  700. package/dist/substrate/runtime/retry-policy.d.mts +59 -1
  701. package/dist/substrate/runtime/retry-policy.mjs +66 -1
  702. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  703. package/dist/substrate/runtime/routed-url.d.mts +1 -0
  704. package/dist/substrate/runtime/routed-url.mjs +79 -0
  705. package/dist/substrate/runtime/routed-url.mjs.map +1 -0
  706. package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
  707. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  708. package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
  709. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  710. package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
  711. package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
  712. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
  713. package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
  714. package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
  715. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
  716. package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
  717. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  718. package/dist/substrate/runtime/state-store/index.d.mts +1 -0
  719. package/dist/substrate/runtime/state-store/index.mjs +3 -0
  720. package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
  721. package/dist/substrate/runtime/state-store/schema.mjs +19 -14
  722. package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
  723. package/dist/substrate/runtime/state-store/service.d.mts +1 -0
  724. package/dist/substrate/runtime/state-store/service.mjs +145 -0
  725. package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
  726. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
  727. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
  728. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
  729. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
  730. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  731. package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
  732. package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
  733. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  734. package/dist/substrate/runtime/subnet-broker.mjs +60 -0
  735. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
  736. package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
  737. package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
  738. package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
  739. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
  740. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
  741. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
  742. package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
  743. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
  744. package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
  745. package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
  746. package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
  747. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
  748. package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
  749. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
  750. package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
  751. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
  752. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
  753. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
  754. package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
  755. package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
  756. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
  757. package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
  758. package/dist/substrate/runtime/supervisor/index.mjs +3 -0
  759. package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
  760. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
  761. package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
  762. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
  763. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
  764. package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
  765. package/dist/substrate/runtime/supervisor/state.mjs +22 -0
  766. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
  767. package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
  768. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
  769. package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
  770. package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
  771. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
  772. package/dist/substrate/runtime/typed-env.mjs +8 -0
  773. package/dist/substrate/runtime/typed-env.mjs.map +1 -0
  774. package/dist/substrate/state-store.d.mts +1 -0
  775. package/dist/substrate/versioned-doc-schema.mjs +17 -0
  776. package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
  777. package/dist/substrate/versioned-doc-sync.mjs +94 -0
  778. package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
  779. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  780. package/dist/surfaces/cli/commands/index.mjs +9 -0
  781. package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
  782. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
  783. package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
  784. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  785. package/dist/surfaces/cli/commands/prune.mjs +34 -17
  786. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  787. package/dist/surfaces/cli/commands/status.mjs +2 -2
  788. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  789. package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
  790. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  791. package/dist/surfaces/cli/commands/wipe.mjs +38 -4
  792. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  793. package/dist/surfaces/cli/errors.mjs +1 -1
  794. package/dist/surfaces/cli/errors.mjs.map +1 -1
  795. package/dist/surfaces/cli/flags.mjs +0 -1
  796. package/dist/surfaces/cli/flags.mjs.map +1 -1
  797. package/dist/surfaces/cli/index.mjs +98 -18
  798. package/dist/surfaces/cli/index.mjs.map +1 -1
  799. package/dist/surfaces/cli/output.mjs +1 -0
  800. package/dist/surfaces/cli/output.mjs.map +1 -1
  801. package/dist/surfaces/cli/sysexits.mjs +2 -1
  802. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  803. package/dist/surfaces/tui/app.mjs +25 -3
  804. package/dist/surfaces/tui/app.mjs.map +1 -1
  805. package/dist/surfaces/tui/display-derivation.mjs +23 -74
  806. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  807. package/dist/surfaces/tui/event-log.mjs +35 -23
  808. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  809. package/dist/surfaces/tui/input.mjs +5 -1
  810. package/dist/surfaces/tui/input.mjs.map +1 -1
  811. package/dist/surfaces/tui/plain-renderer.mjs +70 -34
  812. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  813. package/package.json +24 -4
  814. package/dist/contracts/liveness-classifier.d.mts +0 -19
  815. package/dist/contracts/network-resolver.d.mts +0 -15
  816. package/dist/contracts/network-resolver.mjs +0 -7
  817. package/dist/contracts/network-resolver.mjs.map +0 -1
  818. package/dist/orchestrators/codegen/extras.mjs +0 -16
  819. package/dist/orchestrators/codegen/extras.mjs.map +0 -1
  820. package/dist/plugins/deepbook/routable.mjs +0 -21
  821. package/dist/plugins/deepbook/routable.mjs.map +0 -1
  822. package/dist/plugins/faucet/service.d.mts +0 -20
  823. package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
  824. package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
  825. package/dist/plugins/sui/seed-objects.d.mts +0 -18
  826. package/dist/plugins/sui/seed-objects.mjs +0 -25
  827. package/dist/plugins/sui/seed-objects.mjs.map +0 -1
  828. package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
  829. package/dist/substrate/runtime/context-helpers.mjs +0 -32
  830. package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
  831. package/dist/substrate/runtime/run.mjs.map +0 -1
  832. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
  833. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
  834. package/dist/substrate/runtime/supervisor.d.mts +0 -1
  835. package/dist/substrate/runtime/supervisor.mjs +0 -831
  836. package/dist/substrate/runtime/supervisor.mjs.map +0 -1
  837. package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
  838. /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
@@ -1,47 +1,7 @@
1
1
  import { decodeUnknown } from "../../substrate/runtime/runtime-decode.mjs";
2
- import { Effect, Schema } from "effect";
2
+ import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
3
+ import { Effect } from "effect";
3
4
  //#region src/plugins/sui/chain-probe.ts
4
- /** Validated subset of `client.core.getObject(...).object`. We
5
- * narrow to the fields verify probes actually consult — the SDK
6
- * exposes more (digest, content, json, display) but those are
7
- * out of scope here. */
8
- const ObjectOwnerSchema = Schema.Union([
9
- Schema.Struct({
10
- $kind: Schema.Literal("AddressOwner"),
11
- AddressOwner: Schema.String
12
- }),
13
- Schema.Struct({
14
- $kind: Schema.Literal("Shared"),
15
- Shared: Schema.Struct({ initialSharedVersion: Schema.String })
16
- }),
17
- Schema.Struct({
18
- $kind: Schema.Literal("Immutable"),
19
- Immutable: Schema.Literal(true)
20
- }),
21
- Schema.Struct({
22
- $kind: Schema.Literal("ConsensusAddressOwner"),
23
- ConsensusAddressOwner: Schema.Unknown
24
- }),
25
- Schema.Struct({
26
- $kind: Schema.Literal("Parent"),
27
- Parent: Schema.Unknown
28
- }),
29
- Schema.Struct({
30
- $kind: Schema.Literal("Unknown"),
31
- Unknown: Schema.Unknown
32
- })
33
- ]);
34
- /** Validated SDK response shape: `{ object: { objectId, type, ... } }`.
35
- * Substrate-redesign note: today's code validates `version` as a
36
- * string but it's semantically a bigint — branded type recommendation
37
- * carried in the Opportunities section. */
38
- const SuiObjectShapeSchema = Schema.Struct({
39
- objectId: Schema.String,
40
- type: Schema.String,
41
- version: Schema.String,
42
- owner: ObjectOwnerSchema
43
- });
44
- Schema.Struct({ object: SuiObjectShapeSchema });
45
5
  /** Construct the chain-probe instance for a resolved Sui client +
46
6
  * chain id. The result implements the contract's `ChainProbe<Key>`
47
7
  * shape; the Sui plugin emits this via a StrategyContributorDecl
@@ -53,7 +13,7 @@ const makeSuiChainProbe = (sdk, chain) => ({ get: (key, schema, mode) => Effect.
53
13
  _tag: "ChainProbeError",
54
14
  reason: isNotFound(cause) ? "not-found" : "transient",
55
15
  chain,
56
- detail: stringifyCause(cause)
16
+ detail: formatUnknownError(cause)
57
17
  })
58
18
  }).pipe(Effect.catch((err) => mode === "lenient" && (err.reason === "not-found" || err.reason === "transient") ? Effect.succeed(null) : Effect.fail(err)));
59
19
  if (raw === null) return null;
@@ -65,7 +25,7 @@ const makeSuiChainProbe = (sdk, chain) => ({ get: (key, schema, mode) => Effect.
65
25
  _tag: "ChainProbeError",
66
26
  reason: "decode-failed",
67
27
  chain,
68
- detail: stringifyCause(issue.cause ?? issue)
28
+ detail: formatUnknownError(issue.cause ?? issue)
69
29
  })
70
30
  });
71
31
  }) });
@@ -81,22 +41,32 @@ const projectTransactionPayload = (raw) => {
81
41
  if (envelope.$kind === "FailedTransaction") return envelope.FailedTransaction ?? null;
82
42
  return raw;
83
43
  };
84
- /** Heuristic: SDK errors carrying "not found" / "Not exist" in
85
- * the message are treated as not-found; everything else is
86
- * transient. The substrate's lenient-retry profile re-runs the
87
- * probe on a transient bucket; not-found is terminal. */
44
+ /** Heuristic: SDK errors carrying object/transaction-shape "not found"
45
+ * markers are treated as terminal not-found; everything else is
46
+ * transient. The substrate's lenient-retry profile re-runs the probe
47
+ * on a transient bucket; not-found is terminal.
48
+ *
49
+ * Limitation: `@mysten/sui` does NOT surface a structured status code
50
+ * on its SDK errors — the substrate only sees an `Error` message. We
51
+ * therefore narrow the substring matches as much as possible to avoid
52
+ * misclassifying network-layer "endpoint does not exist" or generic
53
+ * "not found" prose as terminal:
54
+ *
55
+ * - We require the matched phrase to refer to the OBJECT or
56
+ * TRANSACTION rather than the endpoint. Concretely we look for the
57
+ * SDK's canonical "object not found" / "object does not exist" /
58
+ * "no such object" wording and the equivalent "transaction not
59
+ * found" / "transaction does not exist" wording.
60
+ * - We DO NOT match the bare substring "not found" alone (that
61
+ * catches "endpoint does not exist", DNS prose, etc. — all of
62
+ * which are network-layer transients).
63
+ *
64
+ * If `@mysten/sui` surfaces a structured error class with an
65
+ * `httpStatus` (or equivalent) in the future, swap this for an
66
+ * exact 404 / -32000 check. */
88
67
  const isNotFound = (cause) => {
89
68
  const msg = cause?.message?.toLowerCase() ?? "";
90
- return msg.includes("not found") || msg.includes("does not exist") || msg.includes("no such object") || msg.includes("not exist");
91
- };
92
- const stringifyCause = (cause) => {
93
- if (cause instanceof Error) return cause.message;
94
- if (typeof cause === "string") return cause;
95
- try {
96
- return JSON.stringify(cause);
97
- } catch {
98
- return String(cause);
99
- }
69
+ return /\bobject\b.*\bnot found\b/u.test(msg) || /\bobject\b.*\bdoes not exist\b/u.test(msg) || /\bno such object\b/u.test(msg) || /\btransaction\b.*\bnot found\b/u.test(msg) || /\btransaction\b.*\bdoes not exist\b/u.test(msg);
100
70
  };
101
71
  //#endregion
102
72
  export { makeSuiChainProbe };
@@ -1 +1 @@
1
- {"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../../src/plugins/sui/chain-probe.ts"],"sourcesContent":["// Sui plugin — ChainProbe capability implementation.\n//\n// Architecture §9: ChainProbe is a contract, NOT a primitive. Sui\n// provides the only in-tree implementation; the substrate dispatches\n// to it via the StrategyContributor registry under\n// `chain-probe:<chainId>`.\n//\n// Lenient mode: returns null for both \"not found\" AND transient RPC\n// failure — verify pipelines re-derive on the next cycle rather than\n// fail boot. Strict mode: distinguishes via tagged error.\n//\n// Why lenient is the default in this plugin's wiring: artifact publisher verify is\n// the dominant consumer; artifact publisher's lenient-retry profile (15 attempts,\n// 90s budget) is calibrated against lenient semantics. A strict\n// surface exists for explicit \"I want to know if the chain is\n// reachable\" callers (the doctor command, debugging).\n\nimport { Effect, Schema } from 'effect';\n\nimport type {\n\tChainProbe,\n\tChainProbeError,\n\tChainProbeMode,\n\tChainProbeSchema,\n} from '../../contracts/chain-probe.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\n\n/**\n * Sui's chain-key shape — discriminated so the probe can dispatch\n * between object reads, tx reads, and the (forthcoming) batch\n * variant on one method.\n */\nexport type SuiProbeKey =\n\t| { readonly kind: 'object'; readonly objectId: string }\n\t| { readonly kind: 'transaction'; readonly digest: string };\n\n/** Validated subset of `client.core.getObject(...).object`. We\n * narrow to the fields verify probes actually consult — the SDK\n * exposes more (digest, content, json, display) but those are\n * out of scope here. */\nconst ObjectOwnerSchema = Schema.Union([\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('AddressOwner'),\n\t\tAddressOwner: Schema.String,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Shared'),\n\t\tShared: Schema.Struct({ initialSharedVersion: Schema.String }),\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Immutable'),\n\t\tImmutable: Schema.Literal(true),\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('ConsensusAddressOwner'),\n\t\tConsensusAddressOwner: Schema.Unknown,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Parent'),\n\t\tParent: Schema.Unknown,\n\t}),\n\tSchema.Struct({\n\t\t$kind: Schema.Literal('Unknown'),\n\t\tUnknown: Schema.Unknown,\n\t}),\n]);\n\n/** Validated SDK response shape: `{ object: { objectId, type, ... } }`.\n * Substrate-redesign note: today's code validates `version` as a\n * string but it's semantically a bigint — branded type recommendation\n * carried in the Opportunities section. */\nexport const SuiObjectShapeSchema = Schema.Struct({\n\tobjectId: Schema.String,\n\ttype: Schema.String,\n\tversion: Schema.String,\n\towner: ObjectOwnerSchema,\n});\n\nexport const SuiGetObjectResponseSchema = Schema.Struct({\n\tobject: SuiObjectShapeSchema,\n});\n\n/** Plugin-internal SDK shim — the type the plugin's acquire body\n * hands to the probe factory + the account's sign/execute closure.\n * Kept narrow so we don't pull `@mysten/sui` types into the substrate.\n *\n * Exposes the four surfaces consumers actually use:\n *\n * - `getObject` / `getTransaction` — the lenient chain probe.\n * - `executeTransaction` — the account plugin's submit path\n * (txBytes + caller-signed signatures).\n * - `waitForTransaction` — post-submit finality wait.\n *\n * Plus an OPAQUE `client` field — the underlying `SuiGrpcClient`\n * reference. The package plugin's publish-tx builder hands this to\n * `Transaction.build({ client })` (the SDK resolves gas + object\n * versions through it). We type as `unknown` so the substrate stays\n * free of a direct `@mysten/sui/client` type import; the consumer\n * casts at the boundary (mirrors the same opacity decision in the\n * Coin plugin's `MintSdkShim.client`). */\nexport interface SuiSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: {\n\t\t\treadonly objectId: string;\n\t\t\treadonly include?: {\n\t\t\t\treadonly content?: boolean;\n\t\t\t\treadonly json?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly getTransaction: (args: { readonly digest: string }) => Promise<unknown>;\n\t\treadonly getBalance: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t}) => Promise<unknown>;\n\t\treadonly listCoins: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t\treadonly limit?: number;\n\t\t\treadonly cursor?: string | null;\n\t\t}) => Promise<{\n\t\t\treadonly objects: ReadonlyArray<{\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly version: string;\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly balance: string;\n\t\t\t}>;\n\t\t\treadonly hasNextPage: boolean;\n\t\t\treadonly cursor: string | null;\n\t\t}>;\n\t\treadonly executeTransaction: (args: {\n\t\t\treadonly transaction: Uint8Array;\n\t\t\treadonly signatures: ReadonlyArray<string>;\n\t\t\treadonly include?: {\n\t\t\t\treadonly effects?: boolean;\n\t\t\t\treadonly objectTypes?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly waitForTransaction: (args: {\n\t\t\treadonly digest: string;\n\t\t\treadonly timeout?: number;\n\t\t}) => Promise<unknown>;\n\t};\n\t/** Opaque client reference for `Transaction.build({ client })`.\n\t * The Sui barrel wires the resolved `SuiGrpcClient` through; the\n\t * shim layer doesn't type-narrow it (mirrors `MintSdkShim.client`). */\n\treadonly client: unknown;\n}\n\n/** Construct the chain-probe instance for a resolved Sui client +\n * chain id. The result implements the contract's `ChainProbe<Key>`\n * shape; the Sui plugin emits this via a StrategyContributorDecl\n * keyed by `chain-probe:<chainId>`. */\nexport const makeSuiChainProbe = (sdk: SuiSdkShim, chain: string): ChainProbe<SuiProbeKey> => ({\n\tget: <Shape>(\n\t\tkey: SuiProbeKey,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t): Effect.Effect<Shape | null, ChainProbeError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tkey.kind === 'object'\n\t\t\t\t\t\t? sdk.core.getObject({ objectId: key.objectId })\n\t\t\t\t\t\t: sdk.core.getTransaction({ digest: key.digest }),\n\t\t\t\tcatch: (cause): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: isNotFound(cause) ? 'not-found' : 'transient',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: stringifyCause(cause),\n\t\t\t\t}),\n\t\t\t}).pipe(\n\t\t\t\t// Lenient mode coerces both not-found and transient into a\n\t\t\t\t// null result. Strict mode lets the error propagate.\n\t\t\t\tEffect.catch(\n\t\t\t\t\t(err): Effect.Effect<unknown, ChainProbeError> =>\n\t\t\t\t\t\tmode === 'lenient' && (err.reason === 'not-found' || err.reason === 'transient')\n\t\t\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t\t\t: Effect.fail(err),\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (raw === null) return null;\n\t\t\tconst payload = projectProbePayload(key, raw);\n\t\t\tif (payload === null) return null;\n\n\t\t\t// Decode against the caller-supplied Schema. A decode failure\n\t\t\t// is structured (NOT silent undefined) — this is the\n\t\t\t// load-bearing learning from deepbook.\n\t\t\tconst decoded = yield* decodeUnknown(schema, payload, {\n\t\t\t\tsource: `chain probe ${chain}`,\n\t\t\t\tmkError: (issue): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: 'decode-failed',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: stringifyCause(issue.cause ?? issue),\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn decoded;\n\t\t}),\n});\n\nconst projectProbePayload = (key: SuiProbeKey, raw: unknown): unknown | null => {\n\tif (key.kind === 'transaction') return projectTransactionPayload(raw);\n\tif (typeof raw !== 'object' || raw === null || !('object' in raw)) return raw;\n\n\treturn (raw as { readonly object?: unknown }).object ?? null;\n};\n\nconst projectTransactionPayload = (raw: unknown): unknown | null => {\n\tif (typeof raw !== 'object' || raw === null) return raw;\n\tconst envelope = raw as {\n\t\treadonly $kind?: 'Transaction' | 'FailedTransaction';\n\t\treadonly Transaction?: unknown;\n\t\treadonly FailedTransaction?: unknown;\n\t};\n\tif (envelope.$kind === 'Transaction') return envelope.Transaction ?? null;\n\tif (envelope.$kind === 'FailedTransaction') return envelope.FailedTransaction ?? null;\n\treturn raw;\n};\n\n/** Heuristic: SDK errors carrying \"not found\" / \"Not exist\" in\n * the message are treated as not-found; everything else is\n * transient. The substrate's lenient-retry profile re-runs the\n * probe on a transient bucket; not-found is terminal. */\nconst isNotFound = (cause: unknown): boolean => {\n\tconst msg = (cause as { message?: string })?.message?.toLowerCase() ?? '';\n\treturn (\n\t\tmsg.includes('not found') ||\n\t\tmsg.includes('does not exist') ||\n\t\tmsg.includes('no such object') ||\n\t\tmsg.includes('not exist')\n\t);\n};\n\nconst stringifyCause = (cause: unknown): string => {\n\tif (cause instanceof Error) return cause.message;\n\tif (typeof cause === 'string') return cause;\n\ttry {\n\t\treturn JSON.stringify(cause);\n\t} catch {\n\t\treturn String(cause);\n\t}\n};\n"],"mappings":";;;;;;;AAwCA,MAAM,oBAAoB,OAAO,MAAM;CACtC,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,eAAe;EACrC,cAAc,OAAO;EACrB,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,SAAS;EAC/B,QAAQ,OAAO,OAAO,EAAE,sBAAsB,OAAO,QAAQ,CAAC;EAC9D,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,YAAY;EAClC,WAAW,OAAO,QAAQ,KAAK;EAC/B,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,wBAAwB;EAC9C,uBAAuB,OAAO;EAC9B,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,SAAS;EAC/B,QAAQ,OAAO;EACf,CAAC;CACF,OAAO,OAAO;EACb,OAAO,OAAO,QAAQ,UAAU;EAChC,SAAS,OAAO;EAChB,CAAC;CACF,CAAC;;;;;AAMF,MAAa,uBAAuB,OAAO,OAAO;CACjD,UAAU,OAAO;CACjB,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,OAAO;CACP,CAAC;AAEwC,OAAO,OAAO,EACvD,QAAQ,sBACR,CAAC;;;;;AAwEF,MAAa,qBAAqB,KAAiB,WAA4C,EAC9F,MACC,KACA,QACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WACC,IAAI,SAAS,WACV,IAAI,KAAK,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,GAC9C,IAAI,KAAK,eAAe,EAAE,QAAQ,IAAI,QAAQ,CAAC;EACnD,QAAQ,WAA4B;GACnC,MAAM;GACN,QAAQ,WAAW,MAAM,GAAG,cAAc;GAC1C;GACA,QAAQ,eAAe,MAAM;GAC7B;EACD,CAAC,CAAC,KAGF,OAAO,OACL,QACA,SAAS,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW,eACjE,OAAO,QAAQ,KAAK,GACpB,OAAO,KAAK,IAAI,CACpB,CACD;AACD,KAAI,QAAQ,KAAM,QAAO;CACzB,MAAM,UAAU,oBAAoB,KAAK,IAAI;AAC7C,KAAI,YAAY,KAAM,QAAO;AAc7B,QAAO,OATgB,cAAc,QAAQ,SAAS;EACrD,QAAQ,eAAe;EACvB,UAAU,WAA4B;GACrC,MAAM;GACN,QAAQ;GACR;GACA,QAAQ,eAAe,MAAM,SAAS,MAAM;GAC5C;EACD,CAAC;EAED,EACH;AAED,MAAM,uBAAuB,KAAkB,QAAiC;AAC/E,KAAI,IAAI,SAAS,cAAe,QAAO,0BAA0B,IAAI;AACrE,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,YAAY,KAAM,QAAO;AAE1E,QAAQ,IAAsC,UAAU;;AAGzD,MAAM,6BAA6B,QAAiC;AACnE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;CACpD,MAAM,WAAW;AAKjB,KAAI,SAAS,UAAU,cAAe,QAAO,SAAS,eAAe;AACrE,KAAI,SAAS,UAAU,oBAAqB,QAAO,SAAS,qBAAqB;AACjF,QAAO;;;;;;AAOR,MAAM,cAAc,UAA4B;CAC/C,MAAM,MAAO,OAAgC,SAAS,aAAa,IAAI;AACvE,QACC,IAAI,SAAS,YAAY,IACzB,IAAI,SAAS,iBAAiB,IAC9B,IAAI,SAAS,iBAAiB,IAC9B,IAAI,SAAS,YAAY;;AAI3B,MAAM,kBAAkB,UAA2B;AAClD,KAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,KAAI,OAAO,UAAU,SAAU,QAAO;AACtC,KAAI;AACH,SAAO,KAAK,UAAU,MAAM;SACrB;AACP,SAAO,OAAO,MAAM"}
1
+ {"version":3,"file":"chain-probe.mjs","names":[],"sources":["../../../src/plugins/sui/chain-probe.ts"],"sourcesContent":["// Sui plugin — ChainProbe capability implementation.\n//\n// Architecture §9: ChainProbe is a contract, NOT a primitive. Sui\n// provides the only in-tree implementation; the substrate dispatches\n// to it via the StrategyContributor registry under\n// `chain-probe:<chainId>`.\n//\n// Lenient mode: returns null for both \"not found\" AND transient RPC\n// failure — verify pipelines re-derive on the next cycle rather than\n// fail boot. Strict mode: distinguishes via tagged error.\n//\n// Why lenient is the default in this plugin's wiring: artifact publisher verify is\n// the dominant consumer; artifact publisher's lenient-retry profile (15 attempts,\n// 90s budget) is calibrated against lenient semantics. A strict\n// surface exists for explicit \"I want to know if the chain is\n// reachable\" callers (the doctor command, debugging).\n\nimport { Effect } from 'effect';\nimport type { ClientWithCoreApi } from '@mysten/sui/client';\n\nimport type {\n\tChainProbe,\n\tChainProbeError,\n\tChainProbeMode,\n\tChainProbeSchema,\n} from '../../contracts/chain-probe.ts';\nimport { decodeUnknown } from '../../substrate/runtime/runtime-decode.ts';\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\n\n/**\n * Sui's chain-key shape — discriminated so the probe can dispatch\n * between object reads, tx reads, and the (forthcoming) batch\n * variant on one method.\n */\nexport type SuiProbeKey =\n\t| { readonly kind: 'object'; readonly objectId: string }\n\t| { readonly kind: 'transaction'; readonly digest: string };\n\n// Note: this probe decodes against the CALLER-supplied `schema`\n// argument (see `makeSuiChainProbe`), never a local literal. Earlier\n// revisions also exported `SuiObjectShapeSchema` /\n// `SuiGetObjectResponseSchema` to \"document the SDK shape\", but they\n// had zero consumers (the contract's `ChainProbeSchema<Shape>` is what\n// validates), so per STYLE_GUIDE §5 (no orphan exports) they were\n// removed. Re-add a concrete object schema only if a caller actually\n// decodes through it.\n\n/** Plugin-internal SDK shim — the type the plugin's acquire body\n * hands to the probe factory + the account's sign/execute closure.\n * Kept narrow so we don't pull `@mysten/sui` types into the substrate.\n *\n * Exposes the four surfaces consumers actually use:\n *\n * - `getObject` / `getTransaction` — the lenient chain probe.\n * - `executeTransaction` — the account plugin's submit path\n * (txBytes + caller-signed signatures).\n * - `waitForTransaction` — post-submit finality wait.\n *\n * Plus an OPAQUE `client` field — the underlying `SuiGrpcClient`\n * reference. The package plugin's publish-tx builder hands this to\n * `Transaction.build({ client })` (the SDK resolves gas + object\n * versions through it). We type as `unknown` so the substrate stays\n * free of a direct `@mysten/sui/client` type import; the consumer\n * casts at the boundary (mirrors the same opacity decision in the\n * Coin plugin's `MintSdkShim.client`). */\nexport interface SuiSdkShim {\n\treadonly core: {\n\t\treadonly getObject: (args: {\n\t\t\treadonly objectId: string;\n\t\t\treadonly include?: {\n\t\t\t\treadonly content?: boolean;\n\t\t\t\treadonly json?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly getTransaction: (args: { readonly digest: string }) => Promise<unknown>;\n\t\treadonly getBalance: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t}) => Promise<unknown>;\n\t\treadonly listCoins: (args: {\n\t\t\treadonly owner: string;\n\t\t\treadonly coinType?: string;\n\t\t\treadonly limit?: number;\n\t\t\treadonly cursor?: string | null;\n\t\t}) => Promise<{\n\t\t\treadonly objects: ReadonlyArray<{\n\t\t\t\treadonly objectId: string;\n\t\t\t\treadonly version: string;\n\t\t\t\treadonly digest: string;\n\t\t\t\treadonly balance: string;\n\t\t\t}>;\n\t\t\treadonly hasNextPage: boolean;\n\t\t\treadonly cursor: string | null;\n\t\t}>;\n\t\treadonly executeTransaction: (args: {\n\t\t\treadonly transaction: Uint8Array;\n\t\t\treadonly signatures: ReadonlyArray<string>;\n\t\t\treadonly include?: {\n\t\t\t\treadonly effects?: boolean;\n\t\t\t\treadonly objectTypes?: boolean;\n\t\t\t};\n\t\t}) => Promise<unknown>;\n\t\treadonly waitForTransaction: (args: {\n\t\t\treadonly digest: string;\n\t\t\treadonly timeout?: number;\n\t\t}) => Promise<unknown>;\n\t};\n\t/** Client reference for `Transaction.build({ client })` and every\n\t * `client.core.*` call. The Sui barrel wires the resolved\n\t * `SuiGrpcClient` through; consumers cast no further. */\n\treadonly client: ClientWithCoreApi;\n}\n\n/** Construct the chain-probe instance for a resolved Sui client +\n * chain id. The result implements the contract's `ChainProbe<Key>`\n * shape; the Sui plugin emits this via a StrategyContributorDecl\n * keyed by `chain-probe:<chainId>`. */\nexport const makeSuiChainProbe = (sdk: SuiSdkShim, chain: string): ChainProbe<SuiProbeKey> => ({\n\tget: <Shape>(\n\t\tkey: SuiProbeKey,\n\t\tschema: ChainProbeSchema<Shape>,\n\t\tmode: ChainProbeMode,\n\t): Effect.Effect<Shape | null, ChainProbeError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst raw: unknown = yield* Effect.tryPromise({\n\t\t\t\ttry: () =>\n\t\t\t\t\tkey.kind === 'object'\n\t\t\t\t\t\t? sdk.core.getObject({ objectId: key.objectId })\n\t\t\t\t\t\t: sdk.core.getTransaction({ digest: key.digest }),\n\t\t\t\tcatch: (cause): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: isNotFound(cause) ? 'not-found' : 'transient',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: formatUnknownError(cause),\n\t\t\t\t}),\n\t\t\t}).pipe(\n\t\t\t\t// Lenient mode coerces both not-found and transient into a\n\t\t\t\t// null result. Strict mode lets the error propagate.\n\t\t\t\tEffect.catch(\n\t\t\t\t\t(err): Effect.Effect<unknown, ChainProbeError> =>\n\t\t\t\t\t\tmode === 'lenient' && (err.reason === 'not-found' || err.reason === 'transient')\n\t\t\t\t\t\t\t? Effect.succeed(null)\n\t\t\t\t\t\t\t: Effect.fail(err),\n\t\t\t\t),\n\t\t\t);\n\t\t\tif (raw === null) return null;\n\t\t\tconst payload = projectProbePayload(key, raw);\n\t\t\tif (payload === null) return null;\n\n\t\t\t// Decode against the caller-supplied Schema. A decode failure\n\t\t\t// is structured (NOT silent undefined) — this is the\n\t\t\t// load-bearing learning from deepbook.\n\t\t\tconst decoded = yield* decodeUnknown(schema, payload, {\n\t\t\t\tsource: `chain probe ${chain}`,\n\t\t\t\tmkError: (issue): ChainProbeError => ({\n\t\t\t\t\t_tag: 'ChainProbeError',\n\t\t\t\t\treason: 'decode-failed',\n\t\t\t\t\tchain,\n\t\t\t\t\tdetail: formatUnknownError(issue.cause ?? issue),\n\t\t\t\t}),\n\t\t\t});\n\t\t\treturn decoded;\n\t\t}),\n});\n\nconst projectProbePayload = (key: SuiProbeKey, raw: unknown): unknown | null => {\n\tif (key.kind === 'transaction') return projectTransactionPayload(raw);\n\tif (typeof raw !== 'object' || raw === null || !('object' in raw)) return raw;\n\n\treturn (raw as { readonly object?: unknown }).object ?? null;\n};\n\nconst projectTransactionPayload = (raw: unknown): unknown | null => {\n\tif (typeof raw !== 'object' || raw === null) return raw;\n\tconst envelope = raw as {\n\t\treadonly $kind?: 'Transaction' | 'FailedTransaction';\n\t\treadonly Transaction?: unknown;\n\t\treadonly FailedTransaction?: unknown;\n\t};\n\tif (envelope.$kind === 'Transaction') return envelope.Transaction ?? null;\n\tif (envelope.$kind === 'FailedTransaction') return envelope.FailedTransaction ?? null;\n\treturn raw;\n};\n\n/** Heuristic: SDK errors carrying object/transaction-shape \"not found\"\n * markers are treated as terminal not-found; everything else is\n * transient. The substrate's lenient-retry profile re-runs the probe\n * on a transient bucket; not-found is terminal.\n *\n * Limitation: `@mysten/sui` does NOT surface a structured status code\n * on its SDK errors — the substrate only sees an `Error` message. We\n * therefore narrow the substring matches as much as possible to avoid\n * misclassifying network-layer \"endpoint does not exist\" or generic\n * \"not found\" prose as terminal:\n *\n * - We require the matched phrase to refer to the OBJECT or\n * TRANSACTION rather than the endpoint. Concretely we look for the\n * SDK's canonical \"object not found\" / \"object does not exist\" /\n * \"no such object\" wording and the equivalent \"transaction not\n * found\" / \"transaction does not exist\" wording.\n * - We DO NOT match the bare substring \"not found\" alone (that\n * catches \"endpoint does not exist\", DNS prose, etc. — all of\n * which are network-layer transients).\n *\n * If `@mysten/sui` surfaces a structured error class with an\n * `httpStatus` (or equivalent) in the future, swap this for an\n * exact 404 / -32000 check. */\nconst isNotFound = (cause: unknown): boolean => {\n\tconst msg = (cause as { message?: string })?.message?.toLowerCase() ?? '';\n\treturn (\n\t\t// SDK-side `getObject` / `getTransaction` not-found markers.\n\t\t/\\bobject\\b.*\\bnot found\\b/u.test(msg) ||\n\t\t/\\bobject\\b.*\\bdoes not exist\\b/u.test(msg) ||\n\t\t/\\bno such object\\b/u.test(msg) ||\n\t\t// SDK-side `getTransaction` not-found markers — terminal for\n\t\t// this probe (the queried digest will never materialise).\n\t\t/\\btransaction\\b.*\\bnot found\\b/u.test(msg) ||\n\t\t/\\btransaction\\b.*\\bdoes not exist\\b/u.test(msg)\n\t);\n};\n"],"mappings":";;;;;;;;AAqHA,MAAa,qBAAqB,KAAiB,WAA4C,EAC9F,MACC,KACA,QACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,MAAe,OAAO,OAAO,WAAW;EAC7C,WACC,IAAI,SAAS,WACV,IAAI,KAAK,UAAU,EAAE,UAAU,IAAI,UAAU,CAAC,GAC9C,IAAI,KAAK,eAAe,EAAE,QAAQ,IAAI,QAAQ,CAAC;EACnD,QAAQ,WAA4B;GACnC,MAAM;GACN,QAAQ,WAAW,MAAM,GAAG,cAAc;GAC1C;GACA,QAAQ,mBAAmB,MAAM;GACjC;EACD,CAAC,CAAC,KAGF,OAAO,OACL,QACA,SAAS,cAAc,IAAI,WAAW,eAAe,IAAI,WAAW,eACjE,OAAO,QAAQ,KAAK,GACpB,OAAO,KAAK,IAAI,CACpB,CACD;AACD,KAAI,QAAQ,KAAM,QAAO;CACzB,MAAM,UAAU,oBAAoB,KAAK,IAAI;AAC7C,KAAI,YAAY,KAAM,QAAO;AAc7B,QAAO,OATgB,cAAc,QAAQ,SAAS;EACrD,QAAQ,eAAe;EACvB,UAAU,WAA4B;GACrC,MAAM;GACN,QAAQ;GACR;GACA,QAAQ,mBAAmB,MAAM,SAAS,MAAM;GAChD;EACD,CAAC;EAED,EACH;AAED,MAAM,uBAAuB,KAAkB,QAAiC;AAC/E,KAAI,IAAI,SAAS,cAAe,QAAO,0BAA0B,IAAI;AACrE,KAAI,OAAO,QAAQ,YAAY,QAAQ,QAAQ,EAAE,YAAY,KAAM,QAAO;AAE1E,QAAQ,IAAsC,UAAU;;AAGzD,MAAM,6BAA6B,QAAiC;AACnE,KAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;CACpD,MAAM,WAAW;AAKjB,KAAI,SAAS,UAAU,cAAe,QAAO,SAAS,eAAe;AACrE,KAAI,SAAS,UAAU,oBAAqB,QAAO,SAAS,qBAAqB;AACjF,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;AA0BR,MAAM,cAAc,UAA4B;CAC/C,MAAM,MAAO,OAAgC,SAAS,aAAa,IAAI;AACvE,QAEC,6BAA6B,KAAK,IAAI,IACtC,kCAAkC,KAAK,IAAI,IAC3C,sBAAsB,KAAK,IAAI,IAG/B,kCAAkC,KAAK,IAAI,IAC3C,uCAAuC,KAAK,IAAI"}
@@ -1,5 +1,26 @@
1
1
  import { Effect } from "effect";
2
2
  //#region src/plugins/sui/codegen.ts
3
+ /** Aggregate projection: fold the emitted `suiNetwork` shape into
4
+ * the cross-plugin `services.ts` aggregate at `services.sui`. The
5
+ * orchestrator stays plugin-name-blind; this projector owns the
6
+ * `{ rpc, faucet, graphql }` shape decision. */
7
+ const projectSuiNetworkServices = (exported) => {
8
+ const network = exported["suiNetwork"];
9
+ if (typeof network !== "object" || network === null) return null;
10
+ const record = network;
11
+ const rpcUrl = stringField(record, "rpcUrl");
12
+ const faucetUrl = stringField(record, "faucetUrl");
13
+ const graphqlUrl = stringField(record, "graphqlUrl");
14
+ return { sui: {
15
+ rpc: { url: rpcUrl ?? "" },
16
+ faucet: faucetUrl === null ? null : { url: faucetUrl },
17
+ graphql: graphqlUrl === null ? null : { url: graphqlUrl }
18
+ } };
19
+ };
20
+ const stringField = (record, key) => {
21
+ const value = record[key];
22
+ return typeof value === "string" && value.length > 0 ? value : null;
23
+ };
3
24
  /** Construct the Codegenable contribution. Emit is byte-deterministic
4
25
  * on unchanged input (architecture: no mtime churn on no-op
5
26
  * cycles). */
@@ -7,6 +28,11 @@ const makeCodegenable = (resolved) => ({
7
28
  kind: "codegenable",
8
29
  emitterName: "sui-network",
9
30
  outputPath: "sui/network.ts",
31
+ aggregate: {
32
+ kind: "sui-network",
33
+ bucket: "services.ts",
34
+ project: projectSuiNetworkServices
35
+ },
10
36
  emit: (ctx) => Effect.sync(() => {
11
37
  const bindings = {
12
38
  chain: resolved.chain,
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/sui/codegen.ts"],"sourcesContent":["// Sui plugin — Codegenable contribution.\n//\n// Architecture §6: plugins emit typed `CodegenableDecl`s; the\n// codegen orchestrator stages files into the user's source tree\n// WITHOUT naming the plugin. Sui's contribution is network\n// metadata: the active RPC endpoint, the chain id, and (when\n// applicable) the resolved known-package ids.\n//\n// Downstream consumers — chain-aware code (e.g. SDK boots, wallet\n// pickers, frontend RPC selectors) — `import { suiNetwork } from\n// '<staging>/sui/network'`; the generated module owns that exported\n// value's type.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ResolvedSuiNetwork } from './network-resolver.ts';\n\n/** The typed shape the emitted file exports. */\nexport interface SuiNetworkBindings {\n\treadonly chain: string;\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly rpcUrl: string;\n\treadonly faucetUrl: string | null;\n\treadonly graphqlUrl: string | null;\n\t/** Fork-only — upstream identity for known-package lookups. */\n\treadonly forkUpstream: string | null;\n}\n\n/** Construct the Codegenable contribution. Emit is byte-deterministic\n * on unchanged input (architecture: no mtime churn on no-op\n * cycles). */\nexport const makeCodegenable = (resolved: ResolvedSuiNetwork): CodegenableDecl<'sui-network'> => ({\n\tkind: 'codegenable',\n\temitterName: 'sui-network',\n\toutputPath: 'sui/network.ts',\n\temit: (ctx) =>\n\t\tEffect.sync(() => {\n\t\t\tconst bindings: SuiNetworkBindings = {\n\t\t\t\tchain: resolved.chain,\n\t\t\t\tmode: resolved.mode,\n\t\t\t\trpcUrl: resolved.rpc,\n\t\t\t\tfaucetUrl: resolved.faucet ?? null,\n\t\t\t\tgraphqlUrl: resolved.graphql ?? null,\n\t\t\t\tforkUpstream: resolved.forkUpstream ?? null,\n\t\t\t};\n\t\t\tctx.exportConst('suiNetwork', bindings);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;AAgCA,MAAa,mBAAmB,cAAkE;CACjG,MAAM;CACN,aAAa;CACb,YAAY;CACZ,OAAO,QACN,OAAO,WAAW;EACjB,MAAM,WAA+B;GACpC,OAAO,SAAS;GAChB,MAAM,SAAS;GACf,QAAQ,SAAS;GACjB,WAAW,SAAS,UAAU;GAC9B,YAAY,SAAS,WAAW;GAChC,cAAc,SAAS,gBAAgB;GACvC;AACD,MAAI,YAAY,cAAc,SAAS;AACvC,SAAO,IAAI,MAAM;GAChB;CACH"}
1
+ {"version":3,"file":"codegen.mjs","names":[],"sources":["../../../src/plugins/sui/codegen.ts"],"sourcesContent":["// Sui plugin — Codegenable contribution.\n//\n// Architecture §6: plugins emit typed `CodegenableDecl`s; the\n// codegen orchestrator stages files into the user's source tree\n// WITHOUT naming the plugin. Sui's contribution is network\n// metadata: the active RPC endpoint, the chain id, and (when\n// applicable) the resolved known-package ids.\n//\n// Downstream consumers — chain-aware code (e.g. SDK boots, wallet\n// pickers, frontend RPC selectors) — `import { suiNetwork } from\n// '<staging>/sui/network'`; the generated module owns that exported\n// value's type.\n\nimport { Effect } from 'effect';\n\nimport type { CodegenableDecl } from '../../contracts/codegenable.ts';\nimport type { ResolvedSuiNetwork } from './network-resolver.ts';\n\n/** The typed shape the emitted file exports. */\nexport interface SuiNetworkBindings {\n\treadonly chain: string;\n\treadonly mode: 'local' | 'local-rpc' | 'live' | 'fork';\n\treadonly rpcUrl: string;\n\treadonly faucetUrl: string | null;\n\treadonly graphqlUrl: string | null;\n\t/** Fork-only — upstream identity for known-package lookups. */\n\treadonly forkUpstream: string | null;\n}\n\n/** Aggregate projection: fold the emitted `suiNetwork` shape into\n * the cross-plugin `services.ts` aggregate at `services.sui`. The\n * orchestrator stays plugin-name-blind; this projector owns the\n * `{ rpc, faucet, graphql }` shape decision. */\nconst projectSuiNetworkServices = (\n\texported: Readonly<Record<string, unknown>>,\n): Readonly<Record<string, unknown>> | null => {\n\tconst network = exported['suiNetwork'];\n\tif (typeof network !== 'object' || network === null) return null;\n\tconst record = network as Readonly<Record<string, unknown>>;\n\tconst rpcUrl = stringField(record, 'rpcUrl');\n\tconst faucetUrl = stringField(record, 'faucetUrl');\n\tconst graphqlUrl = stringField(record, 'graphqlUrl');\n\treturn {\n\t\tsui: {\n\t\t\trpc: { url: rpcUrl ?? '' },\n\t\t\tfaucet: faucetUrl === null ? null : { url: faucetUrl },\n\t\t\tgraphql: graphqlUrl === null ? null : { url: graphqlUrl },\n\t\t},\n\t};\n};\n\nconst stringField = (record: Readonly<Record<string, unknown>>, key: string): string | null => {\n\tconst value = record[key];\n\treturn typeof value === 'string' && value.length > 0 ? value : null;\n};\n\n/** Construct the Codegenable contribution. Emit is byte-deterministic\n * on unchanged input (architecture: no mtime churn on no-op\n * cycles). */\nexport const makeCodegenable = (resolved: ResolvedSuiNetwork): CodegenableDecl<'sui-network'> => ({\n\tkind: 'codegenable',\n\temitterName: 'sui-network',\n\toutputPath: 'sui/network.ts',\n\taggregate: {\n\t\tkind: 'sui-network',\n\t\tbucket: 'services.ts',\n\t\tproject: projectSuiNetworkServices,\n\t},\n\temit: (ctx) =>\n\t\tEffect.sync(() => {\n\t\t\tconst bindings: SuiNetworkBindings = {\n\t\t\t\tchain: resolved.chain,\n\t\t\t\tmode: resolved.mode,\n\t\t\t\trpcUrl: resolved.rpc,\n\t\t\t\tfaucetUrl: resolved.faucet ?? null,\n\t\t\t\tgraphqlUrl: resolved.graphql ?? null,\n\t\t\t\tforkUpstream: resolved.forkUpstream ?? null,\n\t\t\t};\n\t\t\tctx.exportConst('suiNetwork', bindings);\n\t\t\treturn ctx.done();\n\t\t}),\n});\n"],"mappings":";;;;;;AAiCA,MAAM,6BACL,aAC8C;CAC9C,MAAM,UAAU,SAAS;AACzB,KAAI,OAAO,YAAY,YAAY,YAAY,KAAM,QAAO;CAC5D,MAAM,SAAS;CACf,MAAM,SAAS,YAAY,QAAQ,SAAS;CAC5C,MAAM,YAAY,YAAY,QAAQ,YAAY;CAClD,MAAM,aAAa,YAAY,QAAQ,aAAa;AACpD,QAAO,EACN,KAAK;EACJ,KAAK,EAAE,KAAK,UAAU,IAAI;EAC1B,QAAQ,cAAc,OAAO,OAAO,EAAE,KAAK,WAAW;EACtD,SAAS,eAAe,OAAO,OAAO,EAAE,KAAK,YAAY;EACzD,EACD;;AAGF,MAAM,eAAe,QAA2C,QAA+B;CAC9F,MAAM,QAAQ,OAAO;AACrB,QAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;;;;;AAMhE,MAAa,mBAAmB,cAAkE;CACjG,MAAM;CACN,aAAa;CACb,YAAY;CACZ,WAAW;EACV,MAAM;EACN,QAAQ;EACR,SAAS;EACT;CACD,OAAO,QACN,OAAO,WAAW;EACjB,MAAM,WAA+B;GACpC,OAAO,SAAS;GAChB,MAAM,SAAS;GACf,QAAQ,SAAS;GACjB,WAAW,SAAS,UAAU;GAC9B,YAAY,SAAS,WAAW;GAChC,cAAc,SAAS,gBAAgB;GACvC;AACD,MAAI,YAAY,cAAc,SAAS;AACvC,SAAO,IAAI,MAAM;GAChB;CACH"}
@@ -40,35 +40,8 @@ interface ForkUnsupportedError {
40
40
  readonly surface: string;
41
41
  readonly hint: string;
42
42
  }
43
- /** Raised when fork meta-config drifts between supervisor boots.
44
- * Carries previous + current snapshots so the doctor / TUI can
45
- * diff them. Consumed inside Sui's fork acquire — does NOT cross
46
- * plugin boundaries (the recipe is "wipe and re-apply"). */
47
- interface SeedManifestMismatchError {
48
- readonly _tag: 'SeedManifestMismatchError';
49
- readonly previous: {
50
- readonly upstream: string;
51
- readonly checkpoint?: string;
52
- readonly configHash: string;
53
- };
54
- readonly current: {
55
- readonly upstream: string;
56
- readonly checkpoint?: string;
57
- readonly configHash: string;
58
- };
59
- readonly hint: string;
60
- }
61
- /** Raised when the funds-ready gate times out against a real
62
- * faucet. Plugin-internal — Sui contributes this strategy and
63
- * consumes its own error. */
64
- interface SuiFundsReadyError {
65
- readonly _tag: 'SuiFundsReadyError';
66
- readonly attempts: number;
67
- readonly lastBody?: string;
68
- readonly hint: string;
69
- }
70
43
  /** Union of every error a Sui-plugin caller may encounter. */
71
- type SuiError = SuiPluginError | SuiCliError | SuiConfigError | ForkUnsupportedError | SeedManifestMismatchError | SuiFundsReadyError;
44
+ type SuiError = SuiPluginError | SuiCliError | SuiConfigError | ForkUnsupportedError;
72
45
  //#endregion
73
- export { ForkUnsupportedError, SeedManifestMismatchError, SuiCliError, SuiConfigError, SuiError, SuiFundsReadyError, SuiPluginError };
46
+ export { ForkUnsupportedError, SuiCliError, SuiConfigError, SuiError, SuiPluginError };
74
47
  //# sourceMappingURL=errors.d.mts.map
@@ -18,9 +18,7 @@ const SUI_ERROR_TAGS = [
18
18
  "SuiPluginError",
19
19
  "SuiCliError",
20
20
  "SuiConfigError",
21
- "ForkUnsupportedError",
22
- "SeedManifestMismatchError",
23
- "SuiFundsReadyError"
21
+ "ForkUnsupportedError"
24
22
  ];
25
23
  //#endregion
26
24
  export { SUI_ERROR_TAGS, forkUnsupportedError, suiConfigError, suiPluginError };
@@ -1 +1 @@
1
- {"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/sui/errors.ts"],"sourcesContent":["// Sui plugin — typed errors.\n//\n// Distilled-doc finding: today's codebase centralises EVERY tagged\n// error in one engine file, but consumer boundaries cross service\n// lines. The architecture lets us redistribute: errors raised AND\n// consumed inside the Sui plugin live here. Cross-service errors\n// (`ForkIncompatibleError`, `SeedManifestMismatchError`) live with\n// the plugin that consumes them — Walrus/Seal/Deepbook own\n// `ForkIncompatibleError`; the seed-manifest error stays here\n// because Sui's fork acquire is the only raise site AND the only\n// consumer.\n//\n// Effect v4: errors are plain interfaces with a `_tag` discriminator\n// — we don't subclass an Effect base class; `Effect.catchTag` /\n// `catchTags` match on `_tag` literal. See architecture § Effect.\n\nimport { defineConfigError, type ConfigIssue } from '../../substrate/runtime/config-validation.ts';\n\n/** Phases for `SuiError`. Closed sum — keeps the cause-walker's\n * display table small. Add a phase only after editing the\n * catalog in the plugin doc. */\nexport type SuiPhase =\n\t| 'image-build'\n\t| 'port-allocate'\n\t| 'container-start'\n\t| 'rpc-probe'\n\t| 'faucet-probe'\n\t| 'graphql-probe'\n\t| 'fork-status-probe'\n\t| 'chain-id-fetch'\n\t| 'wait-funds-ready'\n\t| 'fork-impersonate'\n\t| 'fork-advance-clock'\n\t| 'fork-advance-checkpoint'\n\t| 'fork-lock'\n\t| 'fork-data-dir'\n\t| 'move-build'\n\t| 'move-publish';\n\n/** Generic Sui plugin error. Raised by the plugin's acquire body\n * and its admin surface (`advanceClock`, `impersonate`, …). */\nexport interface SuiPluginError {\n\treadonly _tag: 'SuiPluginError';\n\treadonly phase: SuiPhase;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiPluginError = (\n\tphase: SuiPhase,\n\tmessage: string,\n\tcause?: unknown,\n): SuiPluginError => ({ _tag: 'SuiPluginError', phase, message, cause });\n\nexport interface SuiConfigError extends ConfigIssue {\n\treadonly _tag: 'SuiConfigError';\n}\n\nexport const suiConfigError = defineConfigError('SuiConfigError');\n\n/** Move-build / sui-cli error. Carries the sub-process capture\n * envelope (exit + stderr + stdout). The plugin doc lists 11\n * shell-shaped phases today; we tighten to a much smaller set\n * and use `op` as a free-form column.\n *\n * Stub: the closed-vs-open phase decision is deferred to the\n * cli-driver implementation pass. */\nexport interface SuiCliError {\n\treadonly _tag: 'SuiCliError';\n\treadonly op: 'build' | 'publish' | 'summary' | 'scrub' | 'spawn';\n\treadonly exitCode?: number;\n\treadonly stderr?: string;\n\treadonly stdout?: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiCliError = (\n\top: SuiCliError['op'],\n\tparts: Omit<SuiCliError, '_tag' | 'op'>,\n): SuiCliError => ({ _tag: 'SuiCliError', op, ...parts });\n\n/** Synchronous refusal raised by the fork SDK guard. The guard\n * intercepts at property-access time so the wire call never\n * happens — failing fast lets callers branch on this without\n * awaiting a transport-level reject. */\nexport interface ForkUnsupportedError {\n\treadonly _tag: 'ForkUnsupportedError';\n\treadonly surface: string;\n\treadonly hint: string;\n}\n\nexport const forkUnsupportedError = (surface: string, hint: string): ForkUnsupportedError => ({\n\t_tag: 'ForkUnsupportedError',\n\tsurface,\n\thint,\n});\n\n/** Raised when fork meta-config drifts between supervisor boots.\n * Carries previous + current snapshots so the doctor / TUI can\n * diff them. Consumed inside Sui's fork acquire — does NOT cross\n * plugin boundaries (the recipe is \"wipe and re-apply\"). */\nexport interface SeedManifestMismatchError {\n\treadonly _tag: 'SeedManifestMismatchError';\n\treadonly previous: {\n\t\treadonly upstream: string;\n\t\treadonly checkpoint?: string;\n\t\treadonly configHash: string;\n\t};\n\treadonly current: {\n\t\treadonly upstream: string;\n\t\treadonly checkpoint?: string;\n\t\treadonly configHash: string;\n\t};\n\treadonly hint: string;\n}\n\n/** Raised when the funds-ready gate times out against a real\n * faucet. Plugin-internal — Sui contributes this strategy and\n * consumes its own error. */\nexport interface SuiFundsReadyError {\n\treadonly _tag: 'SuiFundsReadyError';\n\treadonly attempts: number;\n\treadonly lastBody?: string;\n\treadonly hint: string;\n}\n\n/** Union of every error a Sui-plugin caller may encounter. */\nexport type SuiError =\n\t| SuiPluginError\n\t| SuiCliError\n\t| SuiConfigError\n\t| ForkUnsupportedError\n\t| SeedManifestMismatchError\n\t| SuiFundsReadyError;\n\n/** Error tags this plugin contributes — surfaced to the cause\n * walker via `PluginErrorContribution`. */\nexport const SUI_ERROR_TAGS: ReadonlyArray<SuiError['_tag']> = [\n\t'SuiPluginError',\n\t'SuiCliError',\n\t'SuiConfigError',\n\t'ForkUnsupportedError',\n\t'SeedManifestMismatchError',\n\t'SuiFundsReadyError',\n] as const;\n"],"mappings":";;AAgDA,MAAa,kBACZ,OACA,SACA,WACqB;CAAE,MAAM;CAAkB;CAAO;CAAS;CAAO;AAMvE,MAAa,iBAAiB,kBAAkB,iBAAiB;AAiCjE,MAAa,wBAAwB,SAAiB,UAAwC;CAC7F,MAAM;CACN;CACA;CACA;;;AA0CD,MAAa,iBAAkD;CAC9D;CACA;CACA;CACA;CACA;CACA;CACA"}
1
+ {"version":3,"file":"errors.mjs","names":[],"sources":["../../../src/plugins/sui/errors.ts"],"sourcesContent":["// Sui plugin — typed errors.\n//\n// Distilled-doc finding: today's codebase centralises EVERY tagged\n// error in one engine file, but consumer boundaries cross service\n// lines. The architecture lets us redistribute: errors raised AND\n// consumed inside the Sui plugin live here. Cross-service errors\n// (`ForkIncompatibleError`) live with the plugin that consumes them\n// — Walrus/Seal/Deepbook own `ForkIncompatibleError`.\n//\n// Effect v4: errors are plain interfaces with a `_tag` discriminator\n// — we don't subclass an Effect base class; `Effect.catchTag` /\n// `catchTags` match on `_tag` literal. See architecture § Effect.\n\nimport { defineConfigError, type ConfigIssue } from '../../substrate/runtime/config-validation.ts';\n\n/** Phases for `SuiError`. Closed sum — keeps the cause-walker's\n * display table small. Add a phase only after editing the\n * catalog in the plugin doc. */\nexport type SuiPhase =\n\t| 'image-build'\n\t| 'port-allocate'\n\t| 'container-start'\n\t| 'rpc-probe'\n\t| 'faucet-probe'\n\t| 'graphql-probe'\n\t| 'fork-status-probe'\n\t| 'chain-id-fetch'\n\t| 'wait-funds-ready'\n\t| 'fork-impersonate'\n\t| 'fork-advance-clock'\n\t| 'fork-advance-checkpoint'\n\t| 'fork-lock'\n\t| 'fork-data-dir'\n\t| 'move-build'\n\t| 'move-publish';\n\n/** Generic Sui plugin error. Raised by the plugin's acquire body\n * and its admin surface (`advanceClock`, `impersonate`, …). */\nexport interface SuiPluginError {\n\treadonly _tag: 'SuiPluginError';\n\treadonly phase: SuiPhase;\n\treadonly message: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiPluginError = (\n\tphase: SuiPhase,\n\tmessage: string,\n\tcause?: unknown,\n): SuiPluginError => ({ _tag: 'SuiPluginError', phase, message, cause });\n\nexport interface SuiConfigError extends ConfigIssue {\n\treadonly _tag: 'SuiConfigError';\n}\n\nexport const suiConfigError = defineConfigError('SuiConfigError');\n\n/** Move-build / sui-cli error. Carries the sub-process capture\n * envelope (exit + stderr + stdout). The plugin doc lists 11\n * shell-shaped phases today; we tighten to a much smaller set\n * and use `op` as a free-form column.\n *\n * Stub: the closed-vs-open phase decision is deferred to the\n * cli-driver implementation pass. */\nexport interface SuiCliError {\n\treadonly _tag: 'SuiCliError';\n\treadonly op: 'build' | 'publish' | 'summary' | 'scrub' | 'spawn';\n\treadonly exitCode?: number;\n\treadonly stderr?: string;\n\treadonly stdout?: string;\n\treadonly cause?: unknown;\n}\n\nexport const suiCliError = (\n\top: SuiCliError['op'],\n\tparts: Omit<SuiCliError, '_tag' | 'op'>,\n): SuiCliError => ({ _tag: 'SuiCliError', op, ...parts });\n\n/** Synchronous refusal raised by the fork SDK guard. The guard\n * intercepts at property-access time so the wire call never\n * happens — failing fast lets callers branch on this without\n * awaiting a transport-level reject. */\nexport interface ForkUnsupportedError {\n\treadonly _tag: 'ForkUnsupportedError';\n\treadonly surface: string;\n\treadonly hint: string;\n}\n\nexport const forkUnsupportedError = (surface: string, hint: string): ForkUnsupportedError => ({\n\t_tag: 'ForkUnsupportedError',\n\tsurface,\n\thint,\n});\n\n/** Union of every error a Sui-plugin caller may encounter. */\nexport type SuiError =\n\t| SuiPluginError\n\t| SuiCliError\n\t| SuiConfigError\n\t| ForkUnsupportedError;\n\n/** Error tags this plugin contributes — surfaced to the cause\n * walker via `PluginErrorContribution`. */\nexport const SUI_ERROR_TAGS: ReadonlyArray<SuiError['_tag']> = [\n\t'SuiPluginError',\n\t'SuiCliError',\n\t'SuiConfigError',\n\t'ForkUnsupportedError',\n] as const;\n"],"mappings":";;AA6CA,MAAa,kBACZ,OACA,SACA,WACqB;CAAE,MAAM;CAAkB;CAAO;CAAS;CAAO;AAMvE,MAAa,iBAAiB,kBAAkB,iBAAiB;AAiCjE,MAAa,wBAAwB,SAAiB,UAAwC;CAC7F,MAAM;CACN;CACA;CACA;;;AAWD,MAAa,iBAAkD;CAC9D;CACA;CACA;CACA;CACA"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,55 @@
1
+ import { leaseKey } from "../../substrate/runtime/lease-broker/service.mjs";
2
+ import "../../substrate/runtime/lease-broker/index.mjs";
3
+ import { formatUnknownError } from "../../substrate/runtime/format-unknown-error.mjs";
4
+ import { SuiSpans } from "./spans.mjs";
5
+ import { FORK_IMPERSONATION_GAS_BUDGET, buildForkImpersonationTransactionBytes, selectSufficientForkCoin } from "./fork-transaction.mjs";
6
+ import { faucetBodyError } from "../faucet/errors.mjs";
7
+ import "../faucet/index.mjs";
8
+ import { Effect } from "effect";
9
+ import { Transaction } from "@mysten/sui/transactions";
10
+ //#region src/plugins/sui/fork-faucet-strategy.ts
11
+ const sentinelUrl = (whale) => `fork-impersonation://${whale}`;
12
+ const bodyError = (whale, address, amount, message) => faucetBodyError({
13
+ url: sentinelUrl(whale),
14
+ address,
15
+ amount,
16
+ status: 0,
17
+ reason: "failure-status",
18
+ message
19
+ });
20
+ const withSerialization = (serialization, effect) => {
21
+ if (serialization === void 0) return effect;
22
+ return Effect.scoped(Effect.gen(function* () {
23
+ yield* serialization.broker.acquire(leaseKey(serialization.key), serialization.owner);
24
+ yield* effect;
25
+ })).pipe(Effect.withSpan("devstack.plugin.sui.forkFaucet.serializedRequest", { attributes: {
26
+ [SuiSpans.localFaucetLeaseKey]: serialization.key,
27
+ [SuiSpans.localFaucetLeaseOwner]: serialization.owner
28
+ } }));
29
+ };
30
+ /** Build a SUI fork-faucet strategy that funds via whale impersonation. */
31
+ const suiForkFaucetStrategy = (opts) => ({ request: ({ address, amount }) => {
32
+ const gasClient = opts.sdk.core;
33
+ const mapErr = (cause) => bodyError(opts.whale, address, amount, `sui fork faucet: ${cause.message}`);
34
+ const transfer = Effect.gen(function* () {
35
+ if (amount <= 0n) return;
36
+ if (amount > opts.perRequestCapMist) return yield* Effect.fail(bodyError(opts.whale, address, amount, `sui fork faucet: requested ${amount} MIST exceeds the per-request cap ${opts.perRequestCapMist} MIST (whale ${opts.whale}).`));
37
+ const { coin } = yield* selectSufficientForkCoin(gasClient, opts.whale, amount + FORK_IMPERSONATION_GAS_BUDGET).pipe(Effect.mapError(mapErr));
38
+ const tx = new Transaction();
39
+ tx.setSender(opts.whale);
40
+ const [funded] = tx.splitCoins(tx.gas, [tx.pure.u64(amount)]);
41
+ tx.transferObjects([funded], address);
42
+ const bytes = yield* buildForkImpersonationTransactionBytes(tx, opts.whale, gasClient, coin).pipe(Effect.mapError(mapErr));
43
+ const submitted = yield* opts.fork.impersonate(opts.whale, bytes).pipe(Effect.mapError(mapErr));
44
+ if (!submitted.success) return yield* Effect.fail(bodyError(opts.whale, address, amount, `sui fork faucet: impersonation tx ${submitted.digest} failed on-chain.`));
45
+ yield* Effect.tryPromise({
46
+ try: () => opts.sdk.core.waitForTransaction({ digest: submitted.digest }),
47
+ catch: (cause) => bodyError(opts.whale, address, amount, `sui fork faucet: waitForTransaction(${submitted.digest}) failed: ${formatUnknownError(cause)}`)
48
+ });
49
+ });
50
+ return withSerialization(opts.serialization, transfer).pipe(Effect.withSpan("devstack.plugin.sui.forkFaucet.request", { attributes: { [SuiSpans.forkFaucetWhale]: opts.whale } }));
51
+ } });
52
+ //#endregion
53
+ export { suiForkFaucetStrategy };
54
+
55
+ //# sourceMappingURL=fork-faucet-strategy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork-faucet-strategy.mjs","names":[],"sources":["../../../src/plugins/sui/fork-faucet-strategy.ts"],"sourcesContent":["// SUI fork-faucet strategy — impersonation-based funding.\n//\n// Fork networks have no real faucet. This strategy funds a recipient by\n// IMPERSONATING a large-reserve \"whale\" address on the forked upstream\n// and transferring SUI from it: it builds `splitCoins(tx.gas, [amount])`\n// + `transferObjects([coin], recipient)` with the whale as sender, runs\n// it through the SAME impersonation path the package/action plugins use\n// (`buildForkImpersonationTransactionBytes` -> `fork.impersonate`, with\n// empty signatures), and waits for finality.\n//\n// It is registered into the `faucet:request:<chainId>` strategy registry\n// from `sui/index.ts` exactly like the local-faucet HTTP strategy, so\n// ephemeral-account auto-funding and cross-cutting SUI funding \"just\n// work\" in fork mode. (Dependency direction faucet <- sui: the sui\n// plugin imports the faucet contract/error types, never the reverse.)\n//\n// Error channel: account funding only catches FaucetUnreachable |\n// FaucetExhausted | FaucetBodyError (see account/funding.ts). The\n// impersonation path fails with SuiPluginError, so every internal\n// failure is mapped to FaucetBodyError here — otherwise it would escape\n// funding's `catchTags` and surface as an unhandled error.\n//\n// Concurrency: every request selects one sufficient whale SUI coin as\n// both gas payment and split source. Concurrent requests would race the\n// same coin version, so requests serialize on a chain-scoped lease.\n\nimport { Effect } from 'effect';\n\nimport { Transaction } from '@mysten/sui/transactions';\n\nimport { formatUnknownError } from '../../substrate/runtime/format-unknown-error.ts';\nimport { leaseKey, type LeaseBroker } from '../../substrate/runtime/lease-broker/index.ts';\nimport { faucetBodyError, type FaucetBodyError, type FaucetStrategy } from '../faucet/index.ts';\n\nimport type { SuiSdkShim } from './chain-probe.ts';\nimport type { SuiPluginError } from './errors.ts';\nimport {\n\tFORK_IMPERSONATION_GAS_BUDGET,\n\tbuildForkImpersonationTransactionBytes,\n\tselectSufficientForkCoin,\n\ttype ForkImpersonationGasClient,\n} from './fork-transaction.ts';\nimport type { ForkAdminSurface } from './mode/shared.ts';\nimport { SuiSpans } from './spans.ts';\n\n/** Serialization for the shared whale funding coin (mirrors\n * `SuiLocalFaucetSerialization` in `local-faucet-strategy.ts`). */\nexport interface SuiForkFaucetSerialization {\n\treadonly broker: LeaseBroker;\n\treadonly key: string;\n\treadonly owner: string;\n}\n\nexport interface SuiForkFaucetStrategyOptions {\n\t/** Address impersonated as the funding source. Must hold a large SUI\n\t * coin in the fork (auto-seeded + validated at boot). */\n\treadonly whale: string;\n\t/** Fork admin surface (`client.fork`) — submits the impersonation tx. */\n\treadonly fork: ForkAdminSurface;\n\t/** SDK shim (`client.sdk`) — `.core` selects the whale gas coin and\n\t * waits for finality. */\n\treadonly sdk: SuiSdkShim;\n\t/** Upper bound per request (MIST). Requests above this are rejected. */\n\treadonly perRequestCapMist: bigint;\n\t/** Serialize requests so concurrent funds don't race the whale coin. */\n\treadonly serialization?: SuiForkFaucetSerialization;\n}\n\nconst sentinelUrl = (whale: string): string => `fork-impersonation://${whale}`;\n\nconst bodyError = (\n\twhale: string,\n\taddress: string,\n\tamount: bigint,\n\tmessage: string,\n): FaucetBodyError =>\n\tfaucetBodyError({\n\t\turl: sentinelUrl(whale),\n\t\taddress,\n\t\tamount,\n\t\tstatus: 0,\n\t\treason: 'failure-status',\n\t\tmessage,\n\t});\n\nconst withSerialization = (\n\tserialization: SuiForkFaucetSerialization | undefined,\n\teffect: Effect.Effect<void, FaucetBodyError>,\n): Effect.Effect<void, FaucetBodyError> => {\n\tif (serialization === undefined) {\n\t\treturn effect;\n\t}\n\treturn Effect.scoped(\n\t\tEffect.gen(function* () {\n\t\t\tyield* serialization.broker.acquire(leaseKey(serialization.key), serialization.owner);\n\t\t\tyield* effect;\n\t\t}),\n\t).pipe(\n\t\tEffect.withSpan('devstack.plugin.sui.forkFaucet.serializedRequest', {\n\t\t\tattributes: {\n\t\t\t\t[SuiSpans.localFaucetLeaseKey]: serialization.key,\n\t\t\t\t[SuiSpans.localFaucetLeaseOwner]: serialization.owner,\n\t\t\t},\n\t\t}),\n\t);\n};\n\n/** Build a SUI fork-faucet strategy that funds via whale impersonation. */\nexport const suiForkFaucetStrategy = (opts: SuiForkFaucetStrategyOptions): FaucetStrategy => ({\n\trequest: ({ address, amount }) => {\n\t\tconst gasClient: ForkImpersonationGasClient = opts.sdk.core;\n\t\t// Internal SuiPluginError -> FaucetBodyError so account funding's\n\t\t// catchTags handle it; carry the actionable root message through.\n\t\tconst mapErr = (cause: SuiPluginError): FaucetBodyError =>\n\t\t\tbodyError(opts.whale, address, amount, `sui fork faucet: ${cause.message}`);\n\n\t\tconst transfer = Effect.gen(function* () {\n\t\t\tif (amount <= 0n) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (amount > opts.perRequestCapMist) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: requested ${amount} MIST exceeds the per-request cap ` +\n\t\t\t\t\t\t\t`${opts.perRequestCapMist} MIST (whale ${opts.whale}).`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// A sufficient whale SUI coin (first past any dust) pays gas AND sources the split, so\n\t\t\t// it must cover amount + the impersonation gas budget.\n\t\t\tconst { coin } = yield* selectSufficientForkCoin(\n\t\t\t\tgasClient,\n\t\t\t\topts.whale,\n\t\t\t\tamount + FORK_IMPERSONATION_GAS_BUDGET,\n\t\t\t).pipe(Effect.mapError(mapErr));\n\n\t\t\tconst tx = new Transaction();\n\t\t\ttx.setSender(opts.whale);\n\t\t\tconst [funded] = tx.splitCoins(tx.gas, [tx.pure.u64(amount)]);\n\t\t\ttx.transferObjects([funded], address);\n\n\t\t\tconst bytes = yield* buildForkImpersonationTransactionBytes(\n\t\t\t\ttx,\n\t\t\t\topts.whale,\n\t\t\t\tgasClient,\n\t\t\t\tcoin,\n\t\t\t).pipe(Effect.mapError(mapErr));\n\n\t\t\tconst submitted = yield* opts.fork\n\t\t\t\t.impersonate(opts.whale, bytes)\n\t\t\t\t.pipe(Effect.mapError(mapErr));\n\t\t\tif (!submitted.success) {\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: impersonation tx ${submitted.digest} failed on-chain.`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tyield* Effect.tryPromise({\n\t\t\t\ttry: () => opts.sdk.core.waitForTransaction({ digest: submitted.digest }),\n\t\t\t\tcatch: (cause): FaucetBodyError =>\n\t\t\t\t\tbodyError(\n\t\t\t\t\t\topts.whale,\n\t\t\t\t\t\taddress,\n\t\t\t\t\t\tamount,\n\t\t\t\t\t\t`sui fork faucet: waitForTransaction(${submitted.digest}) failed: ${formatUnknownError(cause)}`,\n\t\t\t\t\t),\n\t\t\t});\n\t\t});\n\n\t\treturn withSerialization(opts.serialization, transfer).pipe(\n\t\t\tEffect.withSpan('devstack.plugin.sui.forkFaucet.request', {\n\t\t\t\tattributes: { [SuiSpans.forkFaucetWhale]: opts.whale },\n\t\t\t}),\n\t\t);\n\t},\n});\n"],"mappings":";;;;;;;;;;AAoEA,MAAM,eAAe,UAA0B,wBAAwB;AAEvE,MAAM,aACL,OACA,SACA,QACA,YAEA,gBAAgB;CACf,KAAK,YAAY,MAAM;CACvB;CACA;CACA,QAAQ;CACR,QAAQ;CACR;CACA,CAAC;AAEH,MAAM,qBACL,eACA,WAC0C;AAC1C,KAAI,kBAAkB,KAAA,EACrB,QAAO;AAER,QAAO,OAAO,OACb,OAAO,IAAI,aAAa;AACvB,SAAO,cAAc,OAAO,QAAQ,SAAS,cAAc,IAAI,EAAE,cAAc,MAAM;AACrF,SAAO;GACN,CACF,CAAC,KACD,OAAO,SAAS,oDAAoD,EACnE,YAAY;GACV,SAAS,sBAAsB,cAAc;GAC7C,SAAS,wBAAwB,cAAc;EAChD,EACD,CAAC,CACF;;;AAIF,MAAa,yBAAyB,UAAwD,EAC7F,UAAU,EAAE,SAAS,aAAa;CACjC,MAAM,YAAwC,KAAK,IAAI;CAGvD,MAAM,UAAU,UACf,UAAU,KAAK,OAAO,SAAS,QAAQ,oBAAoB,MAAM,UAAU;CAE5E,MAAM,WAAW,OAAO,IAAI,aAAa;AACxC,MAAI,UAAU,GACb;AAED,MAAI,SAAS,KAAK,kBACjB,QAAO,OAAO,OAAO,KACpB,UACC,KAAK,OACL,SACA,QACA,8BAA8B,OAAO,oCACjC,KAAK,kBAAkB,eAAe,KAAK,MAAM,IACrD,CACD;EAKF,MAAM,EAAE,SAAS,OAAO,yBACvB,WACA,KAAK,OACL,SAAS,8BACT,CAAC,KAAK,OAAO,SAAS,OAAO,CAAC;EAE/B,MAAM,KAAK,IAAI,aAAa;AAC5B,KAAG,UAAU,KAAK,MAAM;EACxB,MAAM,CAAC,UAAU,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC;AAC7D,KAAG,gBAAgB,CAAC,OAAO,EAAE,QAAQ;EAErC,MAAM,QAAQ,OAAO,uCACpB,IACA,KAAK,OACL,WACA,KACA,CAAC,KAAK,OAAO,SAAS,OAAO,CAAC;EAE/B,MAAM,YAAY,OAAO,KAAK,KAC5B,YAAY,KAAK,OAAO,MAAM,CAC9B,KAAK,OAAO,SAAS,OAAO,CAAC;AAC/B,MAAI,CAAC,UAAU,QACd,QAAO,OAAO,OAAO,KACpB,UACC,KAAK,OACL,SACA,QACA,qCAAqC,UAAU,OAAO,mBACtD,CACD;AAGF,SAAO,OAAO,WAAW;GACxB,WAAW,KAAK,IAAI,KAAK,mBAAmB,EAAE,QAAQ,UAAU,QAAQ,CAAC;GACzE,QAAQ,UACP,UACC,KAAK,OACL,SACA,QACA,uCAAuC,UAAU,OAAO,YAAY,mBAAmB,MAAM,GAC7F;GACF,CAAC;GACD;AAEF,QAAO,kBAAkB,KAAK,eAAe,SAAS,CAAC,KACtD,OAAO,SAAS,0CAA0C,EACzD,YAAY,GAAG,SAAS,kBAAkB,KAAK,OAAO,EACtD,CAAC,CACF;GAEF"}
@@ -0,0 +1 @@
1
+ import { Effect, Scope } from "effect";
@@ -1,5 +1,170 @@
1
- import { forkUnsupportedError } from "./errors.mjs";
1
+ import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
2
+ import { selfPid } from "../../substrate/runtime/cross-process/self-pid.mjs";
3
+ import { atomicWriteJsonSync } from "../../substrate/runtime/atomic-write.mjs";
4
+ import { parseVersionedDocumentBodyOrNull } from "../../substrate/versioned-doc-sync.mjs";
5
+ import { isPidAlive, processStartTime } from "../../substrate/runtime/cross-process/liveness.mjs";
6
+ import { acquireStackLock } from "../../substrate/runtime/cross-process/stack-lock.mjs";
7
+ import { mintRandomSuffix } from "../../substrate/runtime/random-suffix.mjs";
8
+ import { forkUnsupportedError, suiPluginError } from "./errors.mjs";
9
+ import "../../substrate/runtime/cross-process/index.mjs";
10
+ import { Effect, Schedule, Schema } from "effect";
11
+ import { readFileSync, unlinkSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { hostname } from "node:os";
2
14
  //#region src/plugins/sui/fork-orchestration.ts
15
+ /** Heartbeat cadence — refresh `startedAt` every 10s. Matches the
16
+ * roster's `heartbeatIntervalMillis`. The heartbeat keeps the holder's
17
+ * `startedAt`/`startTime` fresh for diagnostics and so a peer that DOES
18
+ * later add a foreign-host liveness signal has recent data; with the
19
+ * current conservative foreign-host policy (always-alive) it is not a
20
+ * reclaim gate, mirroring the roster heartbeat fiber. */
21
+ const FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS = 1e4;
22
+ /** Brief acquire timeout for the holder critical section. The OS lock
23
+ * is held only across a read → liveness-check → write, never across
24
+ * I/O — a tight budget keeps peers reacting quickly to a release. */
25
+ const FORK_HOLDER_LOCK_TIMEOUT_MILLIS = 5e3;
26
+ const ForkLockHolderSchema = Schema.Struct({
27
+ pid: Schema.Number,
28
+ host: Schema.String,
29
+ instanceId: Schema.String,
30
+ startedAt: Schema.Number,
31
+ startTime: Schema.NullOr(Schema.Number)
32
+ });
33
+ /** Holder file lives inside the data dir so it travels with the dir's
34
+ * lifecycle (wipe removes it). */
35
+ const forkHolderPath = (dataDir) => join(dataDir, "holder.json");
36
+ /** Is an existing holder alive? Mirrors `liveness.checkHolderLiveness`
37
+ * exactly (the `RosterHolder` shape doesn't fit — that carries
38
+ * `hostname`/`heartbeatAt`, not our `host`/`startedAt` — so we
39
+ * replicate its logic against the `ForkLockHolder` fields):
40
+ *
41
+ * - Foreign-host → ALWAYS ALIVE. Cross-host pid comparison is
42
+ * meaningless, and comparing our `Date.now()` to the holder's
43
+ * `startedAt` (a different host's clock) is clock-skew-unsafe — a
44
+ * >~20s skew on an NFS root could reclaim a LIVE foreign holder and
45
+ * produce dual-writer RocksDB corruption. The NFS-safe trade is to
46
+ * never auto-reclaim a foreign holder; a truly-abandoned one needs
47
+ * manual cleanup (`rm <dataDir>/holder.json`).
48
+ * - Same-host → pid must be live AND its start-time must match, so a
49
+ * crashed-then-recycled pid (an abandoned dir whose pid the kernel
50
+ * handed to an unrelated process) no longer reads as "in use".
51
+ *
52
+ * A `null` start-time on either side is handled conservatively the
53
+ * same way roster does — ALIVE — because we have nothing to dispute
54
+ * the recorded identity with (mismatching a probed stamp against a
55
+ * recorded `null`, or vice versa, would falsely harvest a live
56
+ * holder). */
57
+ const isForkHolderAlive = (holder) => {
58
+ if (holder.host !== hostname()) return true;
59
+ if (!isPidAlive(holder.pid)) return false;
60
+ const probedStart = processStartTime(holder.pid);
61
+ if (probedStart === null) return true;
62
+ if (holder.startTime === null) return true;
63
+ return probedStart === holder.startTime;
64
+ };
65
+ const readForkHolder = (path) => parseVersionedDocumentBodyOrNull(safeReadHolderRaw(path), ForkLockHolderSchema, "sui-fork.holder");
66
+ /** Read the holder file's bytes, returning `''` (→ parses to null) on
67
+ * any I/O error. A missing/unreadable holder means "no live claim";
68
+ * the caller writes its own. Sync read is correct here — we are
69
+ * inside the brief OS-lock critical section, same non-yielding
70
+ * discipline as the cross-process roster reader. */
71
+ const safeReadHolderRaw = (path) => {
72
+ try {
73
+ return readFileSync(path, "utf8");
74
+ } catch {
75
+ return "";
76
+ }
77
+ };
78
+ const ownForkHolder = () => {
79
+ const pid = selfPid();
80
+ return {
81
+ pid,
82
+ host: hostname(),
83
+ instanceId: mintRandomSuffix(8),
84
+ startedAt: Date.now(),
85
+ startTime: processStartTime(pid)
86
+ };
87
+ };
88
+ /** Run `body` under a BRIEFLY-held `stack.lock`. The lock serializes
89
+ * the holder file's read → liveness-check → write critical section so
90
+ * two claimers never both decide the dir is free. Released the moment
91
+ * `body` completes — never held across the fork's lifetime. */
92
+ const underStackLock = (stackLockFile, holderPath, body) => Effect.scoped(Effect.gen(function* () {
93
+ yield* acquireStackLock(stackLockFile, FORK_HOLDER_LOCK_TIMEOUT_MILLIS).pipe(Effect.mapError((cause) => suiPluginError("fork-lock", `sui fork mode: failed to acquire stack lock for data dir ${holderPath}: ${cause._tag}`, cause)));
94
+ return yield* body;
95
+ }));
96
+ /** The brief critical section: under `stack.lock`, read any existing
97
+ * holder; if a LIVE one is present, fail with an actionable error;
98
+ * otherwise claim by writing our own holder atomically. Returns the
99
+ * holder we wrote so the heartbeat fiber can refresh it. */
100
+ const claimForkHolder = (stackLockFile, holderPath) => underStackLock(stackLockFile, holderPath, Effect.gen(function* () {
101
+ const existing = readForkHolder(holderPath);
102
+ if (existing !== null && isForkHolderAlive(existing)) return yield* Effect.fail(suiPluginError("fork-lock", `sui fork mode: fork data dir ${holderPath} is in use by pid ${existing.pid} on ${existing.host}; stop that stack or use a different fork key.`));
103
+ const self = ownForkHolder();
104
+ yield* writeForkHolder(holderPath, self);
105
+ return self;
106
+ }));
107
+ /** Heartbeat: under the brief lock, re-stamp `startedAt` IF the holder
108
+ * on disk is still ours. A peer that reclaimed us (same-host recycled-
109
+ * pid takeover) owns the file now; we must not clobber its claim, so a
110
+ * mismatched `instanceId` makes this a no-op. */
111
+ const refreshForkHolder = (stackLockFile, holderPath, self) => underStackLock(stackLockFile, holderPath, Effect.gen(function* () {
112
+ const current = readForkHolder(holderPath);
113
+ if (current !== null && current.instanceId !== self.instanceId) return;
114
+ yield* writeForkHolder(holderPath, {
115
+ ...self,
116
+ startedAt: Date.now()
117
+ });
118
+ }));
119
+ /** Scope-finalizer release: unlink the holder file ONLY if it is still
120
+ * ours. A finalizer that unconditionally `unlinkSync`d by path would,
121
+ * after a legitimate same-host reclaim (our pid crashed-and-recycled,
122
+ * a peer took over), delete the PEER's holder and unprotect a dir the
123
+ * peer is actively writing. Re-reading and matching `instanceId` makes
124
+ * the release a no-op once we no longer own the file. A missing/
125
+ * unreadable holder is already-gone — also a no-op. Best-effort: a
126
+ * crash that skips this is recovered by the next peer's same-host
127
+ * liveness check. */
128
+ const releaseOwnForkHolder = (holderPath, self) => {
129
+ const current = readForkHolder(holderPath);
130
+ if (current !== null && current.instanceId !== self.instanceId) return;
131
+ try {
132
+ unlinkSync(holderPath);
133
+ } catch {}
134
+ };
135
+ const writeForkHolder = (path, holder) => Effect.try({
136
+ try: () => atomicWriteJsonSync(path, holder),
137
+ catch: (cause) => suiPluginError("fork-lock", `sui fork mode: failed to write fork data-dir holder ${path}.`, cause)
138
+ });
139
+ /**
140
+ * Acquire the data-dir holder for the lifetime of the surrounding
141
+ * scope.
142
+ *
143
+ * 1. Briefly take `stack.lock`, read any existing holder, fail if a
144
+ * live peer holds it, else write our own holder. Release the OS
145
+ * lock immediately (the claim outlives the lock).
146
+ * 2. Fork a scope-bound heartbeat fiber that re-takes the brief lock
147
+ * every `FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS` and refreshes
148
+ * `startedAt` (only while the file is still ours). A heartbeat
149
+ * failure is non-fatal — log and retry next tick (same policy as
150
+ * the roster heartbeat fiber).
151
+ * 3. Register a finalizer that removes our holder file on scope
152
+ * close (wipe / restart / Ctrl-C) — but ONLY if the on-disk holder
153
+ * is still ours, so a legitimate peer reclaim is never clobbered.
154
+ * A crash that skips the finalizer is recovered same-host by the
155
+ * next peer's liveness check (foreign-host needs manual cleanup —
156
+ * the NFS-safe trade in `isForkHolderAlive`).
157
+ */
158
+ const acquireForkDataDirHolder = (stackLockFile, dataDir) => Effect.gen(function* () {
159
+ const holderPath = forkHolderPath(dataDir);
160
+ const self = yield* claimForkHolder(stackLockFile, holderPath);
161
+ yield* Effect.addFinalizer(() => Effect.sync(() => releaseOwnForkHolder(holderPath, self)));
162
+ yield* refreshForkHolder(stackLockFile, holderPath, self).pipe(Effect.catch((err) => Effect.logWarning("sui fork data-dir holder heartbeat failed; next tick will retry").pipe(Effect.annotateLogs({
163
+ [SpanAttr.phase]: err.phase,
164
+ [SpanAttr.errorMessage]: err.message
165
+ })))).pipe(Effect.repeat(Schedule.spaced(`${FORK_HOLDER_HEARTBEAT_INTERVAL_MILLIS} millis`)), Effect.forkScoped);
166
+ return self;
167
+ }).pipe(Effect.withSpan("devstack.plugin.sui.fork.acquireDataDirHolder"));
3
168
  /** Surfaces that the sui-fork binary explicitly panics on. New
4
169
  * upstream additions fail OPEN by default — architecture
5
170
  * invariant. */
@@ -8,6 +173,9 @@ const FORK_UNSUPPORTED_SURFACES = [
8
173
  "listBalances",
9
174
  "getCoinInfo"
10
175
  ];
176
+ /** Wrap a Sui SDK shim with the fork guard. Property access for a
177
+ * blocklisted surface SYNCHRONOUSLY throws — the wire call never
178
+ * happens, so the fork binary stays up. */
11
179
  const wrapWithForkGuard = (sdk) => {
12
180
  const guardedCore = new Proxy(sdk.core, { get(target, prop, receiver) {
13
181
  if (typeof prop === "string" && FORK_UNSUPPORTED_SURFACES.includes(prop)) throw forkUnsupportedError(`client.core.${prop}`, "fork mode does not implement this SDK surface — use the impersonation helper or read state via ChainProbe.");
@@ -19,6 +187,6 @@ const wrapWithForkGuard = (sdk) => {
19
187
  };
20
188
  };
21
189
  //#endregion
22
- export { FORK_UNSUPPORTED_SURFACES, wrapWithForkGuard };
190
+ export { FORK_UNSUPPORTED_SURFACES, acquireForkDataDirHolder, wrapWithForkGuard };
23
191
 
24
192
  //# sourceMappingURL=fork-orchestration.mjs.map