@mysten-incubation/devstack 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (838) hide show
  1. package/README.md +7 -3
  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 +40 -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 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Logger"],"sources":["../../../src/plugins/host-service/index.ts"],"sourcesContent":["// Generic host-process service plugin.\n//\n// Use this for browser dev servers and other local host processes that\n// should be supervised by devstack rather than launched manually in a\n// sibling terminal.\n\nimport { Effect } from 'effect';\n\nimport { definePlugin, resource, type AnyResourceRef } from '../../api/define-plugin.ts';\nimport { pluginErrorContributions } from '../../api/plugin-errors.ts';\nimport {\n\tPortBrokerService,\n\ttype PortProbeHost,\n} from '../../substrate/runtime/port-broker/index.ts';\nimport { Logger } from '../../substrate/runtime/observability/index.ts';\nimport { CurrentPluginKey } from '../../substrate/runtime/current-plugin.ts';\n\nimport {\n\tHOST_SERVICE_ERROR_TAGS,\n\tHostServiceAcquireError,\n\ttype HostServiceConfigError,\n\ttype HostServiceError,\n} from './errors.ts';\nimport {\n\tacquireHostService,\n\tnormalizeHostServiceOptions,\n\tprepareHostService,\n\tHOST_SERVICE_PORT_TOKEN,\n\ttype HostServiceOptions,\n\ttype PreparedHostService,\n\ttype HostServiceResolvedOptions,\n\ttype HostServiceValue,\n\ttype HostServiceReadyProbe,\n\ttype HostProcessChild,\n\ttype HostProcessSpawner,\n\ttype HostProcessSpawnOptions,\n\ttype HostServiceAcquireContext,\n} from './service.ts';\nimport { HOST_SERVICE_DEFAULT_ENDPOINT_NAME, makeHostServiceRoutable } from './routable.ts';\n\nexport const hostServiceResourceId = <Name extends string>(name: Name): `host-service/${Name}` =>\n\t`host-service/${name}`;\n\nexport const hostServiceResource = <Name extends string>(name: Name) =>\n\tresource<`host-service/${Name}`, HostServiceValue>(hostServiceResourceId(name));\n\nconst hostServiceErrorContributions = pluginErrorContributions(HOST_SERVICE_ERROR_TAGS);\nconst HOST_SERVICE_PORT_PROBE_HOST: PortProbeHost = '0.0.0.0';\n\nexport type HostServiceAfter = ReadonlyArray<AnyResourceRef>;\n\nexport const hostService = <const After extends HostServiceAfter = readonly []>(\n\toptions: HostServiceOptions<After>,\n) => {\n\tconst normalized = normalizeHostServiceOptions(options);\n\tconst serviceResource = hostServiceResource(normalized.serviceName);\n\tconst after = options.after ?? ([] as unknown as After);\n\n\treturn definePlugin({\n\t\tid: serviceResource.id,\n\t\tdependsOn: after,\n\t\trole: 'service',\n\t\tstart: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst portBroker = yield* PortBrokerService;\n\t\t\t\tconst logger = yield* Logger;\n\t\t\t\tconst currentPlugin = yield* CurrentPluginKey;\n\t\t\t\tconst acquireContext = {\n\t\t\t\t\tallocatePort: (preferredPort) =>\n\t\t\t\t\t\tportBroker\n\t\t\t\t\t\t\t.allocate({\n\t\t\t\t\t\t\t\tkind: 'http',\n\t\t\t\t\t\t\t\tprobeHost: HOST_SERVICE_PORT_PROBE_HOST,\n\t\t\t\t\t\t\t\t...(preferredPort === undefined ? {} : { preferredPort }),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.pipe(Effect.map((allocation) => allocation.port)),\n\t\t\t\t\tlogger,\n\t\t\t\t\tpluginKey: currentPlugin.key,\n\t\t\t\t} satisfies HostServiceAcquireContext;\n\t\t\t\tconst prepared = yield* prepareHostService(normalized, acquireContext);\n\t\t\t\tyield* prepared.start;\n\t\t\t\treturn prepared.value;\n\t\t\t}),\n\t\terrorContributions: hostServiceErrorContributions,\n\t\tcapabilities: ({ value }) =>\n\t\t\t[\n\t\t\t\tmakeHostServiceRoutable({\n\t\t\t\t\tendpointName: value.endpointName,\n\t\t\t\t\tserviceName: value.name,\n\t\t\t\t\tport: value.port,\n\t\t\t\t}),\n\t\t\t] as const,\n\t});\n};\n\nexport type {\n\tHostServiceAcquireContext,\n\tHostServiceError,\n\tHostServiceOptions,\n\tPreparedHostService,\n\tHostServiceReadyProbe,\n\tHostServiceResolvedOptions,\n\tHostServiceValue,\n\tHostProcessChild,\n\tHostProcessSpawner,\n\tHostProcessSpawnOptions,\n\tHostServiceConfigError,\n};\nexport {\n\tacquireHostService,\n\tprepareHostService,\n\tHOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\tHOST_SERVICE_ERROR_TAGS,\n\tHOST_SERVICE_PORT_TOKEN,\n\tHostServiceAcquireError,\n\tmakeHostServiceRoutable,\n\tnormalizeHostServiceOptions,\n};\n"],"mappings":";;;;;;;;;;AAwCA,MAAa,yBAA8C,SAC1D,gBAAgB;AAEjB,MAAa,uBAA4C,SACxD,SAAmD,sBAAsB,KAAK,CAAC;AAEhF,MAAM,gCAAgC,yBAAyB,wBAAwB;AACvF,MAAM,+BAA8C;AAIpD,MAAa,eACZ,YACI;CACJ,MAAM,aAAa,4BAA4B,QAAQ;CACvD,MAAM,kBAAkB,oBAAoB,WAAW,YAAY;CACnE,MAAM,QAAQ,QAAQ,SAAU,EAAE;AAElC,QAAO,aAAa;EACnB,IAAI,gBAAgB;EACpB,WAAW;EACX,MAAM;EACN,aACC,OAAO,IAAI,aAAa;GACvB,MAAM,aAAa,OAAO;GAe1B,MAAM,WAAW,OAAO,mBAAmB,YAAY;IAXtD,eAAe,kBACd,WACE,SAAS;KACT,MAAM;KACN,WAAW;KACX,GAAI,kBAAkB,KAAA,IAAY,EAAE,GAAG,EAAE,eAAe;KACxD,CAAC,CACD,KAAK,OAAO,KAAK,eAAe,WAAW,KAAK,CAAC;IACpD,QAAA,OAXqBA;IAYrB,YAAW,OAXiB,kBAWH;IAE2C,CAAC;AACtE,UAAO,SAAS;AAChB,UAAO,SAAS;IACf;EACH,oBAAoB;EACpB,eAAe,EAAE,YAChB,CACC,wBAAwB;GACvB,cAAc,MAAM;GACpB,aAAa,MAAM;GACnB,MAAM,MAAM;GACZ,CAAC,CACF;EACF,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["Logger"],"sources":["../../../src/plugins/host-service/index.ts"],"sourcesContent":["// Generic host-process service plugin.\n//\n// Use this for browser dev servers and other local host processes that\n// should be supervised by devstack rather than launched manually in a\n// sibling terminal.\n\nimport { Effect } from 'effect';\n\nimport { definePlugin, resource, type AnyResourceRef } from '../../api/define-plugin.ts';\nimport { pluginErrorContributions } from '../../api/plugin-errors.ts';\nimport {\n\tPortBrokerService,\n\ttype PortProbeHost,\n} from '../../substrate/runtime/port-broker/index.ts';\nimport { PostAcquireTasksService } from '../../substrate/runtime/post-acquire-tasks.ts';\nimport { Logger } from '../../substrate/runtime/observability/index.ts';\nimport { CurrentPluginKey } from '../../substrate/runtime/current-plugin.ts';\nimport { IdentityContext, RuntimeRoot } from '../../substrate/runtime/paths.ts';\nimport { renderUrl, routedHostname } from '../../substrate/runtime/routed-url.ts';\n\nimport {\n\tHOST_SERVICE_ERROR_TAGS,\n\tHostServiceAcquireError,\n\ttype HostServiceConfigError,\n\ttype HostServiceError,\n} from './errors.ts';\nimport {\n\tacquireHostService,\n\tnormalizeHostServiceOptions,\n\tprepareHostService,\n\tHOST_SERVICE_PORT_TOKEN,\n\ttype HostServiceOptions,\n\ttype PreparedHostService,\n\ttype HostServiceResolvedOptions,\n\ttype HostServiceValue,\n\ttype HostServiceReadyProbe,\n\ttype HostProcessChild,\n\ttype HostProcessSpawner,\n\ttype HostProcessSpawnOptions,\n\ttype HostServiceAcquireContext,\n} from './service.ts';\nimport {\n\tHOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\tHOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\tmakeHostServiceRoutable,\n} from './routable.ts';\n\nexport const hostServiceResourceId = <Name extends string>(name: Name): `host-service/${Name}` =>\n\t`host-service/${name}`;\n\nexport const hostServiceResource = <Name extends string>(name: Name) =>\n\tresource<`host-service/${Name}`, HostServiceValue>(hostServiceResourceId(name));\n\nconst hostServiceErrorContributions = pluginErrorContributions(HOST_SERVICE_ERROR_TAGS);\nconst HOST_SERVICE_PORT_PROBE_HOST: PortProbeHost = '0.0.0.0';\n\nexport type HostServiceAfter = ReadonlyArray<AnyResourceRef>;\n\nexport const hostService = <const After extends HostServiceAfter = readonly []>(\n\toptions: HostServiceOptions<After>,\n) => {\n\tconst normalized = normalizeHostServiceOptions(options);\n\tconst serviceResource = hostServiceResource(normalized.serviceName);\n\tconst after = options.after ?? ([] as unknown as After);\n\n\treturn definePlugin({\n\t\tid: serviceResource.id,\n\t\tdependsOn: after,\n\t\trole: 'service',\n\t\tsection: 'service',\n\t\tstart: () =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst portBroker = yield* PortBrokerService;\n\t\t\t\tconst logger = yield* Logger;\n\t\t\t\tconst currentPlugin = yield* CurrentPluginKey;\n\t\t\t\tconst postAcquireTasks = yield* PostAcquireTasksService;\n\t\t\t\t// Effective stack + runtime root for this supervised run, so\n\t\t\t\t// the host-service can publish them into the spawned child's\n\t\t\t\t// env. The Vite plugin runs IN that child and re-discovers the\n\t\t\t\t// manifest via `resolveDiscoveryEnv(process.env)`; `--stack` is\n\t\t\t\t// a CLI flag that never reaches the child otherwise. Sourced\n\t\t\t\t// from the same boot-wired `Identity` / `RuntimeRoot` the rest\n\t\t\t\t// of the run uses, so the values point at the real manifest at\n\t\t\t\t// `<root>/stacks/<stack>/manifest.json`.\n\t\t\t\tconst identity = yield* IdentityContext;\n\t\t\t\tconst { root: runtimeRoot } = yield* RuntimeRoot;\n\t\t\t\t// Best-effort canonical routed URL for this endpoint. This is the\n\t\t\t\t// URL the dev-wallet CORS allowlist accepts (the wallet allowlists\n\t\t\t\t// `routedHostname(identity, dev) : 5175`, NOT the raw Vite bind), so\n\t\t\t\t// publishing it as the host-service's `value.url` points `devstack\n\t\t\t\t// up` output (and any consumer holding the resolved value) at the\n\t\t\t\t// URL that pairs the wallet successfully. The routed entrypoint port is the\n\t\t\t\t// shared Traefik port for every built-in endpoint\n\t\t\t\t// (`HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT` ===\n\t\t\t\t// `DEFAULT_ROUTER_ENTRYPOINT_PORT`); the role is THIS service's\n\t\t\t\t// `endpointName`, matching `makeHostServiceRoutable`'s\n\t\t\t\t// `dispatchId.role`. A hostname-validation failure (an\n\t\t\t\t// out-of-RFC-1035 app/stack/endpoint label) must NOT fail the\n\t\t\t\t// host-service boot — fall back to the raw loopback `value.url` via\n\t\t\t\t// `Effect.orElseSucceed(() => null)`. The raw bind still exists for\n\t\t\t\t// Vite's listen + the readiness probe (which derives its own\n\t\t\t\t// `127.0.0.1:<port>` literal independently of `value.url`).\n\t\t\t\tconst routedUrl = yield* routedHostname(identity, normalized.endpointName).pipe(\n\t\t\t\t\tEffect.map((hostname) =>\n\t\t\t\t\t\trenderUrl({\n\t\t\t\t\t\t\tprotocol: 'http',\n\t\t\t\t\t\t\thostname,\n\t\t\t\t\t\t\tport: HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t\tEffect.orElseSucceed(() => null),\n\t\t\t\t);\n\t\t\t\tconst acquireContext = {\n\t\t\t\t\tallocatePort: (preferredPort) =>\n\t\t\t\t\t\tportBroker\n\t\t\t\t\t\t\t.allocate({\n\t\t\t\t\t\t\t\towner: `host-service:${normalized.serviceName}`,\n\t\t\t\t\t\t\t\tprobeHost: HOST_SERVICE_PORT_PROBE_HOST,\n\t\t\t\t\t\t\t\t...(preferredPort === undefined ? {} : { preferredPort }),\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.pipe(Effect.map((allocation) => allocation.port)),\n\t\t\t\t\tlogger,\n\t\t\t\t\tpluginKey: currentPlugin.key,\n\t\t\t\t\tdiscoveryIdentity: { stack: identity.stack, runtimeRoot },\n\t\t\t\t\troutedUrl,\n\t\t\t\t} satisfies HostServiceAcquireContext;\n\t\t\t\tconst prepared = yield* prepareHostService(normalized, acquireContext);\n\t\t\t\tyield* postAcquireTasks.register({\n\t\t\t\t\tpluginKey: currentPlugin.key,\n\t\t\t\t\tlabel: `host-service:${normalized.serviceName}.start`,\n\t\t\t\t\trun: prepared.start,\n\t\t\t\t});\n\t\t\t\treturn prepared.value;\n\t\t\t}),\n\t\terrorContributions: hostServiceErrorContributions,\n\t\tcapabilities: ({ value }) =>\n\t\t\t[\n\t\t\t\tmakeHostServiceRoutable({\n\t\t\t\t\tendpointName: value.endpointName,\n\t\t\t\t\tserviceName: value.name,\n\t\t\t\t\tport: value.port,\n\t\t\t\t}),\n\t\t\t] as const,\n\t});\n};\n\nexport type {\n\tHostServiceAcquireContext,\n\tHostServiceError,\n\tHostServiceOptions,\n\tPreparedHostService,\n\tHostServiceReadyProbe,\n\tHostServiceResolvedOptions,\n\tHostServiceValue,\n\tHostProcessChild,\n\tHostProcessSpawner,\n\tHostProcessSpawnOptions,\n\tHostServiceConfigError,\n};\nexport {\n\tacquireHostService,\n\tprepareHostService,\n\tHOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\tHOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\tHOST_SERVICE_ERROR_TAGS,\n\tHOST_SERVICE_PORT_TOKEN,\n\tHostServiceAcquireError,\n\tmakeHostServiceRoutable,\n\tnormalizeHostServiceOptions,\n};\n"],"mappings":";;;;;;;;;;;;;;;;AA+CA,MAAa,yBAA8C,SAC1D,gBAAgB;AAEjB,MAAa,uBAA4C,SACxD,SAAmD,sBAAsB,KAAK,CAAC;AAEhF,MAAM,gCAAgC,yBAAyB,wBAAwB;AACvF,MAAM,+BAA8C;AAIpD,MAAa,eACZ,YACI;CACJ,MAAM,aAAa,4BAA4B,QAAQ;CACvD,MAAM,kBAAkB,oBAAoB,WAAW,YAAY;CACnE,MAAM,QAAQ,QAAQ,SAAU,EAAE;AAElC,QAAO,aAAa;EACnB,IAAI,gBAAgB;EACpB,WAAW;EACX,MAAM;EACN,SAAS;EACT,aACC,OAAO,IAAI,aAAa;GACvB,MAAM,aAAa,OAAO;GAC1B,MAAM,SAAS,OAAOA;GACtB,MAAM,gBAAgB,OAAO;GAC7B,MAAM,mBAAmB,OAAO;GAShC,MAAM,WAAW,OAAO;GACxB,MAAM,EAAE,MAAM,gBAAgB,OAAO;GAiBrC,MAAM,YAAY,OAAO,eAAe,UAAU,WAAW,aAAa,CAAC,KAC1E,OAAO,KAAK,aACX,UAAU;IACT,UAAU;IACV;IACA,MAAM;IACN,CAAC,CACF,EACD,OAAO,oBAAoB,KAAK,CAChC;GAeD,MAAM,WAAW,OAAO,mBAAmB,YAAY;IAbtD,eAAe,kBACd,WACE,SAAS;KACT,OAAO,gBAAgB,WAAW;KAClC,WAAW;KACX,GAAI,kBAAkB,KAAA,IAAY,EAAE,GAAG,EAAE,eAAe;KACxD,CAAC,CACD,KAAK,OAAO,KAAK,eAAe,WAAW,KAAK,CAAC;IACpD;IACA,WAAW,cAAc;IACzB,mBAAmB;KAAE,OAAO,SAAS;KAAO;KAAa;IACzD;IAEoE,CAAC;AACtE,UAAO,iBAAiB,SAAS;IAChC,WAAW,cAAc;IACzB,OAAO,gBAAgB,WAAW,YAAY;IAC9C,KAAK,SAAS;IACd,CAAC;AACF,UAAO,SAAS;IACf;EACH,oBAAoB;EACpB,eAAe,EAAE,YAChB,CACC,wBAAwB;GACvB,cAAc,MAAM;GACpB,aAAa,MAAM;GACnB,MAAM,MAAM;GACZ,CAAC,CACF;EACF,CAAC"}
@@ -16,7 +16,8 @@ const makeHostServiceRoutable = (parts) => ({
16
16
  port: parts.port
17
17
  },
18
18
  cors: true,
19
- wireProtocol: "http"
19
+ wireProtocol: "http",
20
+ readiness: "deferred"
20
21
  });
21
22
  //#endregion
22
23
  export { HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT, HOST_SERVICE_ENTRYPOINTS, makeHostServiceRoutable };
@@ -1 +1 @@
1
- {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/host-service/routable.ts"],"sourcesContent":["import type { EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\nexport const HOST_SERVICE_DEFAULT_ENDPOINT_NAME = 'dev' as const;\nexport const HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT = 5175;\n\nexport const HOST_SERVICE_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{\n\t\tname: HOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\t\tport: HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\t\tprotocol: 'http',\n\t},\n];\n\nexport const makeHostServiceRoutable = (parts: {\n\treadonly endpointName: string;\n\treadonly serviceName: string;\n\treadonly port: number;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: parts.endpointName,\n\tdispatchId: {\n\t\tserviceKey: `host-service.${parts.serviceName}`,\n\t\trole: parts.endpointName,\n\t},\n\tupstream: { type: 'host-loopback', port: parts.port },\n\tcors: true,\n\twireProtocol: 'http',\n});\n"],"mappings":"AAGA,MAAa,uCAAuC;AAEpD,MAAa,2BAA0D,CACtE;CACC,MAAA;CACA,MAAM;CACN,UAAU;CACV,CACD;AAED,MAAa,2BAA2B,WAInB;CACpB,MAAM;CACN,cAAc,MAAM;CACpB,YAAY;EACX,YAAY,gBAAgB,MAAM;EAClC,MAAM,MAAM;EACZ;CACD,UAAU;EAAE,MAAM;EAAiB,MAAM,MAAM;EAAM;CACrD,MAAM;CACN,cAAc;CACd"}
1
+ {"version":3,"file":"routable.mjs","names":[],"sources":["../../../src/plugins/host-service/routable.ts"],"sourcesContent":["import type { EntrypointDecl, RoutableDecl } from '../../contracts/routable.ts';\n\nexport const HOST_SERVICE_DEFAULT_ENDPOINT_NAME = 'dev' as const;\nexport const HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT = 5175;\n\nexport const HOST_SERVICE_ENTRYPOINTS: ReadonlyArray<EntrypointDecl> = [\n\t{\n\t\tname: HOST_SERVICE_DEFAULT_ENDPOINT_NAME,\n\t\tport: HOST_SERVICE_DEFAULT_ENTRYPOINT_PORT,\n\t\tprotocol: 'http',\n\t},\n];\n\nexport const makeHostServiceRoutable = (parts: {\n\treadonly endpointName: string;\n\treadonly serviceName: string;\n\treadonly port: number;\n}): RoutableDecl => ({\n\tkind: 'routable',\n\tendpointName: parts.endpointName,\n\tdispatchId: {\n\t\tserviceKey: `host-service.${parts.serviceName}`,\n\t\trole: parts.endpointName,\n\t},\n\tupstream: { type: 'host-loopback', port: parts.port },\n\tcors: true,\n\twireProtocol: 'http',\n\treadiness: 'deferred',\n});\n"],"mappings":"AAGA,MAAa,uCAAuC;AAEpD,MAAa,2BAA0D,CACtE;CACC,MAAA;CACA,MAAM;CACN,UAAU;CACV,CACD;AAED,MAAa,2BAA2B,WAInB;CACpB,MAAM;CACN,cAAc,MAAM;CACpB,YAAY;EACX,YAAY,gBAAgB,MAAM;EAClC,MAAM,MAAM;EACZ;CACD,UAAU;EAAE,MAAM;EAAiB,MAAM,MAAM;EAAM;CACrD,MAAM;CACN,cAAc;CACd,WAAW;CACX"}
@@ -10,6 +10,14 @@ type HostServiceReadyProbe = {
10
10
  readonly intervalMs?: number;
11
11
  } | {
12
12
  readonly kind: 'log';
13
+ /** Pattern matched against each stdout/stderr line. `string` is a
14
+ * fast substring match. `RegExp` is evaluated via `.test(line)`
15
+ * per line and runs synchronously on the observer fiber —
16
+ * AVOID catastrophic-backtracking shapes like `(a+)+b` or
17
+ * `(a|a)*c` which can wedge the fiber on adversarial output.
18
+ * Prefer anchored, non-nested-quantifier patterns. The
19
+ * plugin emits a one-time warning at registration if it
20
+ * detects nested-quantifier shapes. */
13
21
  readonly pattern: string | RegExp;
14
22
  readonly stream?: 'stdout' | 'stderr' | 'both';
15
23
  readonly timeoutMs?: number;
@@ -41,7 +49,20 @@ interface HostServiceValue {
41
49
  readonly command: string;
42
50
  readonly args: ReadonlyArray<string>;
43
51
  readonly cwd: string;
52
+ /** The real loopback port the child (Vite) binds. Always the bound
53
+ * port, regardless of how `url` is shaped — readiness probes and
54
+ * direct host tooling read this. */
44
55
  readonly port: number;
56
+ /** Canonical URL for this service: the router-fronted routed origin
57
+ * (`http://<endpoint>.<stack?>.<app>.localhost:5175`) when the
58
+ * supervisor derived one, the raw `http://127.0.0.1:<port>` loopback
59
+ * bind otherwise. The routed form is what the dev-wallet CORS
60
+ * allowlist accepts, so any consumer that hands this URL to a browser
61
+ * — `devstack up` output, an app or build integration holding the
62
+ * resolved `HostServiceValue` — gets a working wallet pairing.
63
+ * Consumers that need the bind target read `port`. Mirrors
64
+ * `WalletValue.url` ("router-fronted when available, loopback
65
+ * otherwise"). */
45
66
  readonly url: string;
46
67
  }
47
68
  //#endregion
@@ -1,8 +1,10 @@
1
- import { observeProcessLines, readableToByteStream } from "../../substrate/runtime/observability/process-lines.mjs";
2
1
  import { SpanAttr } from "../../substrate/runtime/observability/spans.mjs";
3
- import { expectNonEmptyString, expectOneOf, expectOptionalNonEmptyString, expectOptionalPort, expectOptionalPositiveInteger, expectStringRecord } from "../../substrate/runtime/config-validation.mjs";
4
- import { waitForHttpEndpoint } from "../../substrate/runtime/http-probe.mjs";
2
+ import { observeProcessLines, readableToByteStream } from "../../substrate/runtime/observability/process-lines.mjs";
3
+ import "../../substrate/runtime/observability/index.mjs";
5
4
  import { awaitManagedProcessReady, describeProcessExitStatus, nodeProcessSpawner, onceProcessError, onceProcessExit, terminateManagedProcess } from "../../substrate/runtime/process-supervisor.mjs";
5
+ import { waitForHttpEndpoint } from "../../substrate/runtime/http-probe.mjs";
6
+ import "./routable.mjs";
7
+ import { expectNonEmptyString, expectOptionalPositiveInteger } from "../../substrate/runtime/config-validation.mjs";
6
8
  import { HostServiceAcquireError, hostServiceConfigError } from "./errors.mjs";
7
9
  import { Effect, Exit, Ref } from "effect";
8
10
  import { resolve } from "node:path";
@@ -12,6 +14,11 @@ const DEFAULT_SHUTDOWN_GRACE_MS = 5e3;
12
14
  const DEFAULT_HTTP_READY_TIMEOUT_MS = 6e4;
13
15
  const DEFAULT_HTTP_READY_INTERVAL_MS = 250;
14
16
  const DEFAULT_LOG_READY_TIMEOUT_MS = 6e4;
17
+ const READY_STREAM_VALUES = [
18
+ "stdout",
19
+ "stderr",
20
+ "both"
21
+ ];
15
22
  const shellInvocationFor = (script) => {
16
23
  if (process.platform === "win32") return {
17
24
  command: process.env.ComSpec ?? process.env.COMSPEC ?? "cmd.exe",
@@ -32,7 +39,7 @@ const normalizeReadyProbe = (serviceName, ready) => {
32
39
  if (ready === void 0) return void 0;
33
40
  const mkError = configErrorFor(serviceName);
34
41
  if (ready.kind === "http") {
35
- expectOptionalNonEmptyString(ready.url, {
42
+ if (ready.url !== void 0) expectNonEmptyString(ready.url, {
36
43
  field: "ready.url",
37
44
  mkError
38
45
  });
@@ -51,13 +58,9 @@ const normalizeReadyProbe = (serviceName, ready) => {
51
58
  field: "ready.pattern",
52
59
  message: "must be a string or RegExp"
53
60
  });
54
- if (ready.stream !== void 0) expectOneOf(ready.stream, [
55
- "stdout",
56
- "stderr",
57
- "both"
58
- ], {
61
+ if (ready.stream !== void 0 && !READY_STREAM_VALUES.includes(ready.stream)) throw mkError({
59
62
  field: "ready.stream",
60
- mkError
63
+ message: "must be one of 'stdout', 'stderr', 'both'"
61
64
  });
62
65
  expectOptionalPositiveInteger(ready.timeoutMs, {
63
66
  field: "ready.timeoutMs",
@@ -97,15 +100,30 @@ const normalizeHostServiceOptions = (options) => {
97
100
  field: "args",
98
101
  message: "args are only supported with command"
99
102
  });
100
- const preferredPort = expectOptionalPort(options.port, {
103
+ if (options.port !== void 0 && !(typeof options.port === "number" && Number.isInteger(options.port) && options.port > 0 && options.port <= 65535)) throw mkError({
101
104
  field: "port",
102
- mkError
105
+ message: "must be an integer between 1 and 65535"
103
106
  });
107
+ const preferredPort = options.port;
104
108
  const cwd = resolve(options.cwd ?? process.cwd());
105
- const env = expectStringRecord(options.env, {
106
- field: "env",
107
- mkError
108
- });
109
+ const rawEnv = options.env;
110
+ if (rawEnv !== void 0) {
111
+ if (typeof rawEnv !== "object" || rawEnv === null || Array.isArray(rawEnv)) throw mkError({
112
+ field: "env",
113
+ message: "must be an object of string values"
114
+ });
115
+ for (const [key, entry] of Object.entries(rawEnv)) {
116
+ if (key.length === 0) throw mkError({
117
+ field: "env",
118
+ message: "environment variable names must be non-empty"
119
+ });
120
+ if (typeof entry !== "string") throw mkError({
121
+ field: `env.${key}`,
122
+ message: "must be a string"
123
+ });
124
+ }
125
+ }
126
+ const env = rawEnv ?? {};
109
127
  const shutdownGraceMs = expectOptionalPositiveInteger(options.shutdownGraceMs, {
110
128
  field: "shutdownGraceMs",
111
129
  mkError
@@ -134,6 +152,19 @@ const normalizeHostServiceOptions = (options) => {
134
152
  };
135
153
  };
136
154
  const renderPortToken = (value, port) => value.replaceAll(HOST_SERVICE_PORT_TOKEN, String(port));
155
+ /** Heuristic: catastrophic-backtracking patterns typically nest a
156
+ * quantifier inside another quantifier (e.g. `(a+)+`, `(a*)*`,
157
+ * `(a|a)*`). This is intentionally conservative — it flags clearly
158
+ * risky shapes without trying to be a real ReDoS analyzer. The
159
+ * guard runs once at host-service start and only emits a warning,
160
+ * not a fail-stop. */
161
+ const looksRedosProne = (pattern) => {
162
+ const source = pattern.source;
163
+ if (/\)[*+?](?:\{[^}]*\})?[*+?]/.test(source)) return true;
164
+ if (/\([^()]*[*+?][^()]*\)[*+?]/.test(source)) return true;
165
+ if (/\([^()]*\|[^()]*\)[*+]/.test(source)) return true;
166
+ return false;
167
+ };
137
168
  const renderCommand = (options, port) => {
138
169
  const renderedEnv = {};
139
170
  for (const [key, value] of Object.entries(options.env)) renderedEnv[key] = renderPortToken(value, port);
@@ -143,14 +174,14 @@ const renderCommand = (options, port) => {
143
174
  env: renderedEnv
144
175
  };
145
176
  };
146
- const hostServiceValue = (options, port, rendered) => ({
177
+ const hostServiceValue = (options, port, rendered, routedUrl) => ({
147
178
  name: options.serviceName,
148
179
  endpointName: options.endpointName,
149
180
  command: rendered.command,
150
181
  args: rendered.args,
151
182
  cwd: options.cwd,
152
183
  port,
153
- url: `http://127.0.0.1:${port}`
184
+ url: routedUrl ?? `http://127.0.0.1:${port}`
154
185
  });
155
186
  const terminateChild = (child, timeoutMs, logger, pluginKey, tag) => terminateManagedProcess(child, {
156
187
  graceMs: timeoutMs,
@@ -166,7 +197,8 @@ const httpReady = (url, timeoutMs, intervalMs, exit, processError, error) => awa
166
197
  endpoint: url,
167
198
  timeoutMs,
168
199
  intervalMs,
169
- validate: () => true
200
+ requestInit: { redirect: "manual" },
201
+ validate: (response) => response.status === 200
170
202
  }).pipe(Effect.mapError((cause) => new HostServiceAcquireError({
171
203
  ...error,
172
204
  phase: "ready",
@@ -202,9 +234,22 @@ const logReady = (ready, readySignal, exit, processError, error) => awaitManaged
202
234
  readySignal.then(() => {
203
235
  clearTimeout(timeout);
204
236
  resolveReady();
237
+ }, (cause) => {
238
+ clearTimeout(timeout);
239
+ rejectReady(cause);
205
240
  });
206
241
  }),
207
- catch: (cause) => cause instanceof HostServiceAcquireError ? cause : error
242
+ catch: (cause) => cause instanceof HostServiceAcquireError ? cause : new HostServiceAcquireError({
243
+ serviceName: error.serviceName,
244
+ cwd: error.cwd,
245
+ command: error.command,
246
+ args: error.args,
247
+ phase: error.phase,
248
+ message: error.message,
249
+ exitCode: error.exitCode,
250
+ signal: error.signal,
251
+ cause
252
+ })
208
253
  }),
209
254
  exit,
210
255
  processError,
@@ -234,11 +279,24 @@ const allocateHostPort = (options, ctx) => ctx.allocatePort(options.preferredPor
234
279
  const startHostProcess = (options, ctx, port) => Effect.gen(function* () {
235
280
  const rendered = renderCommand(options, port);
236
281
  const env = {
282
+ ...ctx.discoveryIdentity === void 0 ? {} : {
283
+ DEVSTACK_STACK: ctx.discoveryIdentity.stack,
284
+ DEVSTACK_RUNTIME_ROOT: ctx.discoveryIdentity.runtimeRoot
285
+ },
237
286
  ...ctx.processEnv ?? process.env,
238
287
  ...rendered.env,
239
288
  PORT: String(port)
240
289
  };
241
290
  const tag = `host-service/${options.serviceName}`;
291
+ if (options.ready?.kind === "log" && options.ready.pattern instanceof RegExp && looksRedosProne(options.ready.pattern)) yield* ctx.logger.log(tag, ctx.pluginKey, {
292
+ level: "warn",
293
+ message: "host service readiness pattern has a nested-quantifier shape that may exhibit catastrophic backtracking on adversarial output; prefer anchored, non-nested patterns",
294
+ fields: {
295
+ [SpanAttr.serviceName]: options.serviceName,
296
+ [SpanAttr.event]: "host-service.ready-pattern.redos-warning",
297
+ "host-service.ready-pattern.source": options.ready.pattern.source
298
+ }
299
+ });
242
300
  let resolveLogReady;
243
301
  const logReadySignal = options.ready?.kind === "log" ? new Promise((resolveReady) => {
244
302
  resolveLogReady = resolveReady;
@@ -249,47 +307,50 @@ const startHostProcess = (options, ctx, port) => Effect.gen(function* () {
249
307
  if (typeof options.ready.pattern === "string" ? line.includes(options.ready.pattern) : options.ready.pattern.test(line)) resolveLogReady?.();
250
308
  };
251
309
  const spawnChild = ctx.spawner ?? nodeProcessSpawner;
252
- const child = yield* Effect.try({
253
- try: () => spawnChild(rendered.command, rendered.args, {
254
- cwd: options.cwd,
255
- env,
256
- stdio: "pipe",
257
- detached: process.platform !== "win32"
258
- }),
259
- catch: (cause) => new HostServiceAcquireError({
260
- serviceName: options.serviceName,
261
- cwd: options.cwd,
262
- command: rendered.command,
263
- args: rendered.args,
264
- phase: "spawn",
265
- message: "host service spawn failed",
266
- cause
267
- })
268
- });
269
310
  let shuttingDown = false;
270
311
  let exitStatus = null;
312
+ const child = yield* Effect.uninterruptible(Effect.gen(function* () {
313
+ const spawned = yield* Effect.try({
314
+ try: () => spawnChild(rendered.command, rendered.args, {
315
+ cwd: options.cwd,
316
+ env,
317
+ stdio: "pipe",
318
+ detached: process.platform !== "win32"
319
+ }),
320
+ catch: (cause) => new HostServiceAcquireError({
321
+ serviceName: options.serviceName,
322
+ cwd: options.cwd,
323
+ command: rendered.command,
324
+ args: rendered.args,
325
+ phase: "spawn",
326
+ message: "host service spawn failed",
327
+ cause
328
+ })
329
+ });
330
+ yield* observeProcessLines({
331
+ stdout: readableToByteStream(spawned.stdout),
332
+ stderr: readableToByteStream(spawned.stderr)
333
+ }, {
334
+ logger: ctx.logger,
335
+ pluginKey: ctx.pluginKey,
336
+ tag,
337
+ fields: { [SpanAttr.serviceName]: options.serviceName },
338
+ onLine: ({ line, stream }) => Effect.sync(() => {
339
+ observeReadinessLine(line, stream);
340
+ })
341
+ });
342
+ yield* Effect.addFinalizer(() => Effect.gen(function* () {
343
+ shuttingDown = true;
344
+ if (exitStatus !== null) return;
345
+ yield* terminateChild(spawned, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);
346
+ }));
347
+ return spawned;
348
+ }));
271
349
  const exited = onceProcessExit(child).then((status) => {
272
350
  exitStatus = status;
273
351
  return status;
274
352
  });
275
353
  const processError = onceProcessError(child);
276
- yield* observeProcessLines({
277
- stdout: readableToByteStream(child.stdout),
278
- stderr: readableToByteStream(child.stderr)
279
- }, {
280
- logger: ctx.logger,
281
- pluginKey: ctx.pluginKey,
282
- tag,
283
- fields: { [SpanAttr.serviceName]: options.serviceName },
284
- onLine: ({ line, stream }) => Effect.sync(() => {
285
- observeReadinessLine(line, stream);
286
- })
287
- });
288
- yield* Effect.addFinalizer(() => Effect.gen(function* () {
289
- shuttingDown = true;
290
- if (exitStatus !== null) return;
291
- yield* terminateChild(child, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);
292
- }));
293
354
  const baseError = new HostServiceAcquireError({
294
355
  serviceName: options.serviceName,
295
356
  cwd: options.cwd,
@@ -328,32 +389,26 @@ const startHostProcess = (options, ctx, port) => Effect.gen(function* () {
328
389
  if (exitStatus === null) yield* terminateChild(child, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);
329
390
  return yield* Effect.failCause(readinessExit.cause);
330
391
  }
331
- exited.then((status) => {
332
- if (shuttingDown) return;
333
- Effect.runPromise(ctx.logger.log(tag, ctx.pluginKey, {
334
- level: "error",
335
- message: "host service exited after readiness",
336
- fields: {
337
- [SpanAttr.event]: "process.exited",
338
- [SpanAttr.serviceName]: options.serviceName,
339
- [SpanAttr.exitCode]: status.code,
340
- [SpanAttr.exitSignal]: status.signal,
341
- [SpanAttr.exitStatus]: describeProcessExitStatus(status)
342
- }
343
- })).catch(() => {});
344
- });
345
- processError.then((cause) => {
346
- if (shuttingDown) return;
347
- Effect.runPromise(ctx.logger.log(tag, ctx.pluginKey, {
348
- level: "error",
349
- message: "host service process emitted an error after readiness",
350
- fields: {
351
- [SpanAttr.event]: "process.error",
352
- [SpanAttr.serviceName]: options.serviceName,
353
- [SpanAttr.errorCause]: cause
354
- }
355
- })).catch(() => {});
356
- });
392
+ yield* Effect.forkScoped(Effect.promise(() => exited).pipe(Effect.flatMap((status) => shuttingDown ? Effect.void : ctx.logger.log(tag, ctx.pluginKey, {
393
+ level: "error",
394
+ message: "host service exited after readiness",
395
+ fields: {
396
+ [SpanAttr.event]: "process.exited",
397
+ [SpanAttr.serviceName]: options.serviceName,
398
+ [SpanAttr.exitCode]: status.code,
399
+ [SpanAttr.exitSignal]: status.signal,
400
+ [SpanAttr.exitStatus]: describeProcessExitStatus(status)
401
+ }
402
+ }))));
403
+ yield* Effect.forkScoped(Effect.promise(() => processError).pipe(Effect.flatMap((cause) => shuttingDown ? Effect.void : ctx.logger.log(tag, ctx.pluginKey, {
404
+ level: "error",
405
+ message: "host service process emitted an error after readiness",
406
+ fields: {
407
+ [SpanAttr.event]: "process.error",
408
+ [SpanAttr.serviceName]: options.serviceName,
409
+ [SpanAttr.errorCause]: cause
410
+ }
411
+ }))));
357
412
  });
358
413
  const prepareHostService = (options, ctx) => Effect.gen(function* () {
359
414
  const port = yield* allocateHostPort(options, ctx);
@@ -365,7 +420,7 @@ const prepareHostService = (options, ctx) => Effect.gen(function* () {
365
420
  yield* Ref.set(started, true);
366
421
  });
367
422
  return {
368
- value: hostServiceValue(options, port, rendered),
423
+ value: hostServiceValue(options, port, rendered, ctx.routedUrl ?? null),
369
424
  start
370
425
  };
371
426
  });
@@ -1 +1 @@
1
- {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/host-service/service.ts"],"sourcesContent":["import { resolve } from 'node:path';\n\nimport { Effect, Exit, Ref } from 'effect';\nimport type { Scope } from 'effect';\n\nimport type { PluginKey } from '../../substrate/brand.ts';\nimport type { AnyResourceRef } from '../../api/define-plugin.ts';\nimport {\n\texpectNonEmptyString,\n\texpectOneOf,\n\texpectOptionalNonEmptyString,\n\texpectOptionalPort,\n\texpectOptionalPositiveInteger,\n\texpectStringRecord,\n} from '../../substrate/runtime/config-validation.ts';\nimport {\n\tobserveProcessLines,\n\treadableToByteStream,\n\tSpanAttr,\n\ttype LoggerShape,\n} from '../../substrate/runtime/observability/index.ts';\nimport { waitForHttpEndpoint } from '../../substrate/runtime/http-probe.ts';\nimport type { PortBrokerError } from '../../substrate/runtime/port-broker/index.ts';\nimport {\n\tawaitManagedProcessReady,\n\tdescribeProcessExitStatus,\n\tnodeProcessSpawner,\n\tonceProcessError,\n\tonceProcessExit,\n\tterminateManagedProcess,\n\ttype ManagedProcessChild,\n\ttype ManagedProcessSpawner,\n\ttype ManagedProcessSpawnOptions,\n} from '../../substrate/runtime/process-supervisor.ts';\n\nimport { HOST_SERVICE_DEFAULT_ENDPOINT_NAME } from './routable.ts';\nimport { hostServiceConfigError, HostServiceAcquireError } from './errors.ts';\n\nexport const HOST_SERVICE_PORT_TOKEN = '{port}' as const;\n\nexport type HostServiceReadyProbe =\n\t| {\n\t\t\treadonly kind: 'http';\n\t\t\treadonly url?: string;\n\t\t\treadonly timeoutMs?: number;\n\t\t\treadonly intervalMs?: number;\n\t }\n\t| {\n\t\t\treadonly kind: 'log';\n\t\t\treadonly pattern: string | RegExp;\n\t\t\treadonly stream?: 'stdout' | 'stderr' | 'both';\n\t\t\treadonly timeoutMs?: number;\n\t };\n\ninterface HostServiceBaseOptions<After extends ReadonlyArray<AnyResourceRef>> {\n\treadonly name?: string;\n\treadonly endpointName?: string;\n\treadonly after?: After;\n\treadonly cwd?: string;\n\treadonly port?: number;\n\treadonly env?: Readonly<Record<string, string>>;\n\treadonly ready?: HostServiceReadyProbe;\n\treadonly shutdownGraceMs?: number;\n}\n\ninterface HostServiceCommandOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef>,\n> extends HostServiceBaseOptions<After> {\n\treadonly command: string;\n\treadonly args?: ReadonlyArray<string>;\n\treadonly script?: never;\n}\n\ninterface HostServiceScriptOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef>,\n> extends HostServiceBaseOptions<After> {\n\treadonly script: string;\n\treadonly command?: never;\n\treadonly args?: never;\n}\n\nexport type HostServiceOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef> = ReadonlyArray<AnyResourceRef>,\n> = HostServiceCommandOptions<After> | HostServiceScriptOptions<After>;\n\nexport interface HostServiceResolvedOptions {\n\treadonly serviceName: string;\n\treadonly endpointName: string;\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly cwd: string;\n\treadonly preferredPort?: number;\n\treadonly env: Readonly<Record<string, string>>;\n\treadonly ready?: HostServiceReadyProbe;\n\treadonly shutdownGraceMs: number;\n}\n\nexport interface HostServiceValue {\n\treadonly name: string;\n\treadonly endpointName: string;\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly cwd: string;\n\treadonly port: number;\n\treadonly url: string;\n}\n\nexport interface PreparedHostService {\n\treadonly value: HostServiceValue;\n\treadonly start: Effect.Effect<void, HostServiceAcquireError, Scope.Scope>;\n}\n\nexport type HostProcessChild = ManagedProcessChild;\nexport type HostProcessSpawnOptions = ManagedProcessSpawnOptions;\nexport type HostProcessSpawner = ManagedProcessSpawner;\n\nexport interface HostServiceAcquireContext {\n\treadonly allocatePort: (\n\t\tpreferredPort: number | undefined,\n\t) => Effect.Effect<number, PortBrokerError, Scope.Scope>;\n\treadonly logger: LoggerShape;\n\treadonly pluginKey: PluginKey;\n\treadonly spawner?: HostProcessSpawner;\n\treadonly processEnv?: NodeJS.ProcessEnv;\n}\n\nconst DEFAULT_SHUTDOWN_GRACE_MS = 5_000;\nconst DEFAULT_HTTP_READY_TIMEOUT_MS = 60_000;\nconst DEFAULT_HTTP_READY_INTERVAL_MS = 250;\nconst DEFAULT_LOG_READY_TIMEOUT_MS = 60_000;\n\nconst shellInvocationFor = (script: string): { command: string; args: ReadonlyArray<string> } => {\n\tif (process.platform === 'win32') {\n\t\treturn {\n\t\t\tcommand: process.env.ComSpec ?? process.env.COMSPEC ?? 'cmd.exe',\n\t\t\targs: ['/d', '/s', '/c', script],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: '/bin/sh',\n\t\targs: ['-c', script],\n\t};\n};\n\nconst configErrorFor =\n\t(serviceName: string) => (issue: Parameters<typeof hostServiceConfigError>[1]) =>\n\t\thostServiceConfigError(serviceName, issue);\n\nconst normalizeReadyProbe = (\n\tserviceName: string,\n\tready: HostServiceReadyProbe | undefined,\n): HostServiceReadyProbe | undefined => {\n\tif (ready === undefined) return undefined;\n\tconst mkError = configErrorFor(serviceName);\n\tif (ready.kind === 'http') {\n\t\texpectOptionalNonEmptyString(ready.url, { field: 'ready.url', mkError });\n\t\texpectOptionalPositiveInteger(ready.timeoutMs, { field: 'ready.timeoutMs', mkError });\n\t\texpectOptionalPositiveInteger(ready.intervalMs, { field: 'ready.intervalMs', mkError });\n\t\treturn ready;\n\t}\n\tif (ready.kind === 'log') {\n\t\tif (typeof ready.pattern !== 'string' && !(ready.pattern instanceof RegExp)) {\n\t\t\tthrow mkError({ field: 'ready.pattern', message: 'must be a string or RegExp' });\n\t\t}\n\t\tif (ready.stream !== undefined) {\n\t\t\texpectOneOf(ready.stream, ['stdout', 'stderr', 'both'] as const, {\n\t\t\t\tfield: 'ready.stream',\n\t\t\t\tmkError,\n\t\t\t});\n\t\t}\n\t\texpectOptionalPositiveInteger(ready.timeoutMs, { field: 'ready.timeoutMs', mkError });\n\t\treturn ready;\n\t}\n\tthrow mkError({ field: 'ready.kind', message: \"must be 'http' or 'log'\" });\n};\n\nexport const normalizeHostServiceOptions = (\n\toptions: HostServiceOptions,\n): HostServiceResolvedOptions => {\n\tconst endpointName = options.endpointName ?? HOST_SERVICE_DEFAULT_ENDPOINT_NAME;\n\tconst serviceName = options.name ?? endpointName;\n\tconst mkError = configErrorFor(serviceName);\n\texpectNonEmptyString(serviceName, { field: 'name', mkError });\n\texpectNonEmptyString(endpointName, { field: 'endpointName', mkError });\n\n\tconst rawCommand = (options as { readonly command?: unknown }).command;\n\tconst rawArgs = (options as { readonly args?: unknown }).args;\n\tconst rawScript = (options as { readonly script?: unknown }).script;\n\tif (rawCommand !== undefined && rawScript !== undefined) {\n\t\tthrow mkError({ field: 'command', message: 'use either command or script, not both' });\n\t}\n\tif (rawCommand === undefined && rawScript === undefined) {\n\t\tthrow mkError({ field: 'command', message: 'is required unless script is provided' });\n\t}\n\tif (rawScript !== undefined && rawArgs !== undefined) {\n\t\tthrow mkError({ field: 'args', message: 'args are only supported with command' });\n\t}\n\n\tconst preferredPort = expectOptionalPort(options.port, { field: 'port', mkError });\n\tconst cwd = resolve(options.cwd ?? process.cwd());\n\tconst env = expectStringRecord(options.env, { field: 'env', mkError });\n\tconst shutdownGraceMs =\n\t\texpectOptionalPositiveInteger(options.shutdownGraceMs, {\n\t\t\tfield: 'shutdownGraceMs',\n\t\t\tmkError,\n\t\t}) ?? DEFAULT_SHUTDOWN_GRACE_MS;\n\tconst ready = normalizeReadyProbe(serviceName, options.ready);\n\tconst invocation =\n\t\trawScript !== undefined\n\t\t\t? shellInvocationFor(expectNonEmptyString(rawScript, { field: 'script', mkError }))\n\t\t\t: {\n\t\t\t\t\tcommand: expectNonEmptyString(rawCommand, { field: 'command', mkError }),\n\t\t\t\t\targs: options.args ?? [],\n\t\t\t\t};\n\n\treturn {\n\t\tserviceName,\n\t\tendpointName,\n\t\tcommand: invocation.command,\n\t\targs: invocation.args,\n\t\tcwd,\n\t\t...(preferredPort === undefined ? {} : { preferredPort }),\n\t\tenv,\n\t\t...(ready === undefined ? {} : { ready }),\n\t\tshutdownGraceMs,\n\t};\n};\n\nconst renderPortToken = (value: string, port: number): string =>\n\tvalue.replaceAll(HOST_SERVICE_PORT_TOKEN, String(port));\n\nconst renderCommand = (\n\toptions: HostServiceResolvedOptions,\n\tport: number,\n): {\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly env: NodeJS.ProcessEnv;\n} => {\n\tconst renderedEnv: NodeJS.ProcessEnv = {};\n\tfor (const [key, value] of Object.entries(options.env)) {\n\t\trenderedEnv[key] = renderPortToken(value, port);\n\t}\n\treturn {\n\t\tcommand: renderPortToken(options.command, port),\n\t\targs: options.args.map((arg) => renderPortToken(arg, port)),\n\t\tenv: renderedEnv,\n\t};\n};\n\nconst hostServiceValue = (\n\toptions: HostServiceResolvedOptions,\n\tport: number,\n\trendered: { readonly command: string; readonly args: ReadonlyArray<string> },\n): HostServiceValue => ({\n\tname: options.serviceName,\n\tendpointName: options.endpointName,\n\tcommand: rendered.command,\n\targs: rendered.args,\n\tcwd: options.cwd,\n\tport,\n\turl: `http://127.0.0.1:${port}`,\n});\n\nconst terminateChild = (\n\tchild: HostProcessChild,\n\ttimeoutMs: number,\n\tlogger: LoggerShape,\n\tpluginKey: PluginKey,\n\ttag: string,\n): Effect.Effect<void> =>\n\tterminateManagedProcess(child, {\n\t\tgraceMs: timeoutMs,\n\t\tprocessGroup: true,\n\t\tonEscalate: () =>\n\t\t\tlogger.log(tag, pluginKey, {\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: 'host service did not exit after SIGTERM; sending SIGKILL',\n\t\t\t\tfields: { [SpanAttr.event]: 'process.shutdown.escalated' },\n\t\t\t}),\n\t});\n\nconst httpReady = (\n\turl: string,\n\ttimeoutMs: number,\n\tintervalMs: number,\n\texit: Promise<{ readonly code: number | null; readonly signal: NodeJS.Signals | null }>,\n\tprocessError: Promise<unknown>,\n\terror: HostServiceAcquireError,\n): Effect.Effect<void, HostServiceAcquireError> =>\n\tawaitManagedProcessReady({\n\t\tready: waitForHttpEndpoint({\n\t\t\tendpoint: url,\n\t\t\ttimeoutMs,\n\t\t\tintervalMs,\n\t\t\t// Host services only need to prove their listener is up. App-level\n\t\t\t// 4xx/5xx responses can be transient while devstack writes generated files.\n\t\t\tvalidate: () => true,\n\t\t}).pipe(\n\t\t\tEffect.mapError(\n\t\t\t\t(cause) =>\n\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t...error,\n\t\t\t\t\t\tphase: 'ready',\n\t\t\t\t\t\tmessage: `host service did not become ready at ${url} within ${timeoutMs}ms`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t\texit,\n\t\tprocessError,\n\t\tonExitBeforeReady: (status) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'exit',\n\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\texitCode: status.code,\n\t\t\t\tsignal: status.signal,\n\t\t\t}),\n\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'spawn',\n\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nconst logReady = (\n\tready: Extract<HostServiceReadyProbe, { readonly kind: 'log' }>,\n\treadySignal: Promise<void>,\n\texit: Promise<{ readonly code: number | null; readonly signal: NodeJS.Signals | null }>,\n\tprocessError: Promise<unknown>,\n\terror: HostServiceAcquireError,\n): Effect.Effect<void, HostServiceAcquireError> =>\n\tawaitManagedProcessReady({\n\t\tready: Effect.tryPromise({\n\t\t\ttry: () =>\n\t\t\t\tnew Promise<void>((resolveReady, rejectReady) => {\n\t\t\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\t\t\trejectReady(\n\t\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t\t...error,\n\t\t\t\t\t\t\t\tphase: 'ready',\n\t\t\t\t\t\t\t\tmessage: `host service did not emit readiness log within ${ready.timeoutMs ?? DEFAULT_LOG_READY_TIMEOUT_MS}ms`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}, ready.timeoutMs ?? DEFAULT_LOG_READY_TIMEOUT_MS);\n\t\t\t\t\treadySignal.then(() => {\n\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\tresolveReady();\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t\tcatch: (cause) => (cause instanceof HostServiceAcquireError ? cause : error),\n\t\t}),\n\t\texit,\n\t\tprocessError,\n\t\tonExitBeforeReady: (status) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'exit',\n\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\texitCode: status.code,\n\t\t\t\tsignal: status.signal,\n\t\t\t}),\n\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'spawn',\n\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nconst allocateHostPort = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<number, HostServiceAcquireError, Scope.Scope> =>\n\tctx.allocatePort(options.preferredPort).pipe(\n\t\tEffect.mapError(\n\t\t\t(cause) =>\n\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\tserviceName: options.serviceName,\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\tcommand: options.command,\n\t\t\t\t\targs: options.args,\n\t\t\t\t\tphase: 'allocate-port',\n\t\t\t\t\tmessage: 'host service failed to allocate HTTP port',\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t),\n\t);\n\nconst startHostProcess = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n\tport: number,\n): Effect.Effect<void, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst rendered = renderCommand(options, port);\n\t\tconst env: NodeJS.ProcessEnv = {\n\t\t\t...(ctx.processEnv ?? process.env),\n\t\t\t...rendered.env,\n\t\t\tPORT: String(port),\n\t\t};\n\t\tconst tag = `host-service/${options.serviceName}`;\n\t\tlet resolveLogReady: (() => void) | undefined;\n\t\tconst logReadySignal =\n\t\t\toptions.ready?.kind === 'log'\n\t\t\t\t? new Promise<void>((resolveReady) => {\n\t\t\t\t\t\tresolveLogReady = resolveReady;\n\t\t\t\t\t})\n\t\t\t\t: null;\n\t\tconst observeReadinessLine = (line: string, stream: 'stdout' | 'stderr'): void => {\n\t\t\tif (options.ready?.kind !== 'log') return;\n\t\t\tif (\n\t\t\t\toptions.ready.stream !== undefined &&\n\t\t\t\toptions.ready.stream !== 'both' &&\n\t\t\t\toptions.ready.stream !== stream\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst matches =\n\t\t\t\ttypeof options.ready.pattern === 'string'\n\t\t\t\t\t? line.includes(options.ready.pattern)\n\t\t\t\t\t: options.ready.pattern.test(line);\n\t\t\tif (matches) resolveLogReady?.();\n\t\t};\n\n\t\tconst spawnChild = ctx.spawner ?? nodeProcessSpawner;\n\t\tconst child = yield* Effect.try({\n\t\t\ttry: () =>\n\t\t\t\tspawnChild(rendered.command, rendered.args, {\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\tenv,\n\t\t\t\t\tstdio: 'pipe',\n\t\t\t\t\tdetached: process.platform !== 'win32',\n\t\t\t\t}),\n\t\t\tcatch: (cause) =>\n\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\tserviceName: options.serviceName,\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\tcommand: rendered.command,\n\t\t\t\t\targs: rendered.args,\n\t\t\t\t\tphase: 'spawn',\n\t\t\t\t\tmessage: 'host service spawn failed',\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t});\n\t\tlet shuttingDown = false;\n\t\tlet exitStatus: {\n\t\t\treadonly code: number | null;\n\t\t\treadonly signal: NodeJS.Signals | null;\n\t\t} | null = null;\n\t\tconst exited = onceProcessExit(child).then((status) => {\n\t\t\texitStatus = status;\n\t\t\treturn status;\n\t\t});\n\t\tconst processError = onceProcessError(child);\n\t\tyield* observeProcessLines(\n\t\t\t{\n\t\t\t\tstdout: readableToByteStream(\n\t\t\t\t\tchild.stdout as unknown as AsyncIterable<Uint8Array> | null | undefined,\n\t\t\t\t),\n\t\t\t\tstderr: readableToByteStream(\n\t\t\t\t\tchild.stderr as unknown as AsyncIterable<Uint8Array> | null | undefined,\n\t\t\t\t),\n\t\t\t},\n\t\t\t{\n\t\t\t\tlogger: ctx.logger,\n\t\t\t\tpluginKey: ctx.pluginKey,\n\t\t\t\ttag,\n\t\t\t\tfields: { [SpanAttr.serviceName]: options.serviceName },\n\t\t\t\tonLine: ({ line, stream }) =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tobserveReadinessLine(line, stream);\n\t\t\t\t\t}),\n\t\t\t},\n\t\t);\n\t\tyield* Effect.addFinalizer(() =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tshuttingDown = true;\n\t\t\t\tif (exitStatus !== null) return;\n\t\t\t\tyield* terminateChild(child, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);\n\t\t\t}),\n\t\t);\n\n\t\tconst baseError = new HostServiceAcquireError({\n\t\t\tserviceName: options.serviceName,\n\t\t\tcwd: options.cwd,\n\t\t\tcommand: rendered.command,\n\t\t\targs: rendered.args,\n\t\t\tphase: 'ready',\n\t\t\tmessage: 'host service readiness failed',\n\t\t});\n\t\tconst awaitReadiness = (() => {\n\t\t\tif (options.ready?.kind === 'http') {\n\t\t\t\tconst url = renderPortToken(options.ready.url ?? 'http://127.0.0.1:{port}', port);\n\t\t\t\treturn httpReady(\n\t\t\t\t\turl,\n\t\t\t\t\toptions.ready.timeoutMs ?? DEFAULT_HTTP_READY_TIMEOUT_MS,\n\t\t\t\t\toptions.ready.intervalMs ?? DEFAULT_HTTP_READY_INTERVAL_MS,\n\t\t\t\t\texited,\n\t\t\t\t\tprocessError,\n\t\t\t\t\tbaseError,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (options.ready?.kind === 'log' && logReadySignal !== null) {\n\t\t\t\treturn logReady(options.ready, logReadySignal, exited, processError, baseError);\n\t\t\t}\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tyield* awaitManagedProcessReady({\n\t\t\t\t\tready: Effect.promise(\n\t\t\t\t\t\t() => new Promise<void>((resolveReady) => setTimeout(resolveReady, 0)),\n\t\t\t\t\t),\n\t\t\t\t\texit: exited,\n\t\t\t\t\tprocessError,\n\t\t\t\t\tonExitBeforeReady: (status) =>\n\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t...baseError,\n\t\t\t\t\t\t\tphase: 'exit',\n\t\t\t\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\t\t\t\texitCode: status.code,\n\t\t\t\t\t\t\tsignal: status.signal,\n\t\t\t\t\t\t}),\n\t\t\t\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t...baseError,\n\t\t\t\t\t\t\tphase: 'spawn',\n\t\t\t\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t});\n\t\t})();\n\t\tconst readinessExit = yield* Effect.exit(awaitReadiness);\n\t\tif (Exit.isFailure(readinessExit)) {\n\t\t\tshuttingDown = true;\n\t\t\tif (exitStatus === null) {\n\t\t\t\tyield* terminateChild(child, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);\n\t\t\t}\n\t\t\treturn yield* Effect.failCause(readinessExit.cause);\n\t\t}\n\n\t\tvoid exited.then((status) => {\n\t\t\tif (shuttingDown) return;\n\t\t\tvoid Effect.runPromise(\n\t\t\t\tctx.logger.log(tag, ctx.pluginKey, {\n\t\t\t\t\tlevel: 'error',\n\t\t\t\t\tmessage: 'host service exited after readiness',\n\t\t\t\t\tfields: {\n\t\t\t\t\t\t[SpanAttr.event]: 'process.exited',\n\t\t\t\t\t\t[SpanAttr.serviceName]: options.serviceName,\n\t\t\t\t\t\t[SpanAttr.exitCode]: status.code,\n\t\t\t\t\t\t[SpanAttr.exitSignal]: status.signal,\n\t\t\t\t\t\t[SpanAttr.exitStatus]: describeProcessExitStatus(status),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t).catch(() => {});\n\t\t});\n\t\tvoid processError.then((cause) => {\n\t\t\tif (shuttingDown) return;\n\t\t\tvoid Effect.runPromise(\n\t\t\t\tctx.logger.log(tag, ctx.pluginKey, {\n\t\t\t\t\tlevel: 'error',\n\t\t\t\t\tmessage: 'host service process emitted an error after readiness',\n\t\t\t\t\tfields: {\n\t\t\t\t\t\t[SpanAttr.event]: 'process.error',\n\t\t\t\t\t\t[SpanAttr.serviceName]: options.serviceName,\n\t\t\t\t\t\t[SpanAttr.errorCause]: cause,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t).catch(() => {});\n\t\t});\n\t});\n\nexport const prepareHostService = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<PreparedHostService, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst port = yield* allocateHostPort(options, ctx);\n\t\tconst rendered = renderCommand(options, port);\n\t\tconst started = yield* Ref.make(false);\n\t\tconst start = Effect.gen(function* () {\n\t\t\tif (yield* Ref.get(started)) return;\n\t\t\tyield* startHostProcess(options, ctx, port);\n\t\t\tyield* Ref.set(started, true);\n\t\t});\n\n\t\treturn {\n\t\t\tvalue: hostServiceValue(options, port, rendered),\n\t\t\tstart,\n\t\t};\n\t});\n\nexport const acquireHostService = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<HostServiceValue, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst prepared = yield* prepareHostService(options, ctx);\n\t\tyield* prepared.start;\n\t\treturn prepared.value;\n\t});\n"],"mappings":"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"}
1
+ {"version":3,"file":"service.mjs","names":[],"sources":["../../../src/plugins/host-service/service.ts"],"sourcesContent":["import { resolve } from 'node:path';\n\nimport { Effect, Exit, Ref } from 'effect';\nimport type { Scope } from 'effect';\n\nimport type { PluginKey } from '../../substrate/brand.ts';\nimport type { AnyResourceRef } from '../../api/define-plugin.ts';\nimport {\n\texpectNonEmptyString,\n\texpectOptionalPositiveInteger,\n} from '../../substrate/runtime/config-validation.ts';\nimport {\n\tobserveProcessLines,\n\treadableToByteStream,\n\tSpanAttr,\n\ttype LoggerShape,\n} from '../../substrate/runtime/observability/index.ts';\nimport { waitForHttpEndpoint } from '../../substrate/runtime/http-probe.ts';\nimport type { PortBrokerError } from '../../substrate/runtime/port-broker/index.ts';\nimport {\n\tawaitManagedProcessReady,\n\tdescribeProcessExitStatus,\n\tnodeProcessSpawner,\n\tonceProcessError,\n\tonceProcessExit,\n\tterminateManagedProcess,\n\ttype ManagedProcessChild,\n\ttype ManagedProcessSpawner,\n\ttype ManagedProcessSpawnOptions,\n} from '../../substrate/runtime/process-supervisor.ts';\n\nimport { HOST_SERVICE_DEFAULT_ENDPOINT_NAME } from './routable.ts';\nimport { hostServiceConfigError, HostServiceAcquireError } from './errors.ts';\n\nexport const HOST_SERVICE_PORT_TOKEN = '{port}' as const;\n\nexport type HostServiceReadyProbe =\n\t| {\n\t\t\treadonly kind: 'http';\n\t\t\treadonly url?: string;\n\t\t\treadonly timeoutMs?: number;\n\t\t\treadonly intervalMs?: number;\n\t }\n\t| {\n\t\t\treadonly kind: 'log';\n\t\t\t/** Pattern matched against each stdout/stderr line. `string` is a\n\t\t\t * fast substring match. `RegExp` is evaluated via `.test(line)`\n\t\t\t * per line and runs synchronously on the observer fiber —\n\t\t\t * AVOID catastrophic-backtracking shapes like `(a+)+b` or\n\t\t\t * `(a|a)*c` which can wedge the fiber on adversarial output.\n\t\t\t * Prefer anchored, non-nested-quantifier patterns. The\n\t\t\t * plugin emits a one-time warning at registration if it\n\t\t\t * detects nested-quantifier shapes. */\n\t\t\treadonly pattern: string | RegExp;\n\t\t\treadonly stream?: 'stdout' | 'stderr' | 'both';\n\t\t\treadonly timeoutMs?: number;\n\t };\n\ninterface HostServiceBaseOptions<After extends ReadonlyArray<AnyResourceRef>> {\n\treadonly name?: string;\n\treadonly endpointName?: string;\n\treadonly after?: After;\n\treadonly cwd?: string;\n\treadonly port?: number;\n\treadonly env?: Readonly<Record<string, string>>;\n\treadonly ready?: HostServiceReadyProbe;\n\treadonly shutdownGraceMs?: number;\n}\n\ninterface HostServiceCommandOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef>,\n> extends HostServiceBaseOptions<After> {\n\treadonly command: string;\n\treadonly args?: ReadonlyArray<string>;\n\treadonly script?: never;\n}\n\ninterface HostServiceScriptOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef>,\n> extends HostServiceBaseOptions<After> {\n\treadonly script: string;\n\treadonly command?: never;\n\treadonly args?: never;\n}\n\nexport type HostServiceOptions<\n\tAfter extends ReadonlyArray<AnyResourceRef> = ReadonlyArray<AnyResourceRef>,\n> = HostServiceCommandOptions<After> | HostServiceScriptOptions<After>;\n\nexport interface HostServiceResolvedOptions {\n\treadonly serviceName: string;\n\treadonly endpointName: string;\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly cwd: string;\n\treadonly preferredPort?: number;\n\treadonly env: Readonly<Record<string, string>>;\n\treadonly ready?: HostServiceReadyProbe;\n\treadonly shutdownGraceMs: number;\n}\n\nexport interface HostServiceValue {\n\treadonly name: string;\n\treadonly endpointName: string;\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly cwd: string;\n\t/** The real loopback port the child (Vite) binds. Always the bound\n\t * port, regardless of how `url` is shaped — readiness probes and\n\t * direct host tooling read this. */\n\treadonly port: number;\n\t/** Canonical URL for this service: the router-fronted routed origin\n\t * (`http://<endpoint>.<stack?>.<app>.localhost:5175`) when the\n\t * supervisor derived one, the raw `http://127.0.0.1:<port>` loopback\n\t * bind otherwise. The routed form is what the dev-wallet CORS\n\t * allowlist accepts, so any consumer that hands this URL to a browser\n\t * — `devstack up` output, an app or build integration holding the\n\t * resolved `HostServiceValue` — gets a working wallet pairing.\n\t * Consumers that need the bind target read `port`. Mirrors\n\t * `WalletValue.url` (\"router-fronted when available, loopback\n\t * otherwise\"). */\n\treadonly url: string;\n}\n\nexport interface PreparedHostService {\n\treadonly value: HostServiceValue;\n\treadonly start: Effect.Effect<void, HostServiceAcquireError, Scope.Scope>;\n}\n\nexport type HostProcessChild = ManagedProcessChild;\nexport type HostProcessSpawnOptions = ManagedProcessSpawnOptions;\nexport type HostProcessSpawner = ManagedProcessSpawner;\n\nexport interface HostServiceAcquireContext {\n\treadonly allocatePort: (\n\t\tpreferredPort: number | undefined,\n\t) => Effect.Effect<number, PortBrokerError, Scope.Scope>;\n\treadonly logger: LoggerShape;\n\treadonly pluginKey: PluginKey;\n\treadonly spawner?: HostProcessSpawner;\n\treadonly processEnv?: NodeJS.ProcessEnv;\n\t/**\n\t * Stack identity to publish into the spawned child's environment so\n\t * that in-process build integrations running INSIDE that child (the\n\t * `devstack` Vite plugin in particular) can re-discover the active\n\t * stack's manifest. `--stack` is a CLI flag, not an env var, and the\n\t * supervisor process does not mutate its own `process.env`, so without\n\t * this the child would inherit no `DEVSTACK_STACK` /\n\t * `DEVSTACK_RUNTIME_ROOT` and the Vite plugin's\n\t * `resolveDiscoveryEnv(process.env)` would fall back to the `main`\n\t * stack — aliasing `@generated` at the wrong stack's codegen output.\n\t *\n\t * `stack` is the effective stack name (`Identity.stack`); `runtimeRoot`\n\t * is the absolute on-disk runtime root (`RuntimeRoot.root`). The two\n\t * map directly onto the `<runtimeRoot>/stacks/<stack>/manifest.json`\n\t * path the supervisor writes and `discoverManifestPath` reads. Optional\n\t * so non-supervised callers (and tests) can omit them.\n\t */\n\treadonly discoveryIdentity?: {\n\t\treadonly stack: string;\n\t\treadonly runtimeRoot: string;\n\t};\n\t/**\n\t * Canonical router-fronted URL for this host-service's endpoint, e.g.\n\t * `http://dev.<stack>.<app>.localhost:5175`. When supplied it becomes\n\t * the published `HostServiceValue.url` so every consumer that reads\n\t * \"the host-service's URL\" (`devstack up` output, an app / build\n\t * integration holding the resolved value) is pointed at the URL that\n\t * actually works end-to-end — in particular the one whose Origin the\n\t * dev-wallet CORS allowlist accepts. The raw `http://127.0.0.1:<port>` loopback\n\t * bind is kept INTERNAL (Vite's listen + the readiness probe, which\n\t * derives its own loopback literal) and remains the fallback here when\n\t * no routed URL is available (router disabled, or a hostname-validation\n\t * failure in the caller's best-effort derivation). Optional + nullable\n\t * so non-supervised callers and tests fall back to loopback exactly as\n\t * before.\n\t *\n\t * Mirrors the wallet's own `WalletValue.url` rule (\"router-fronted URL\n\t * when available, loopback otherwise\") and the ARCHITECTURE.md\n\t * \"Host-service = endpoint-defaults bus\" intent that the ROUTED origin\n\t * is canonical.\n\t */\n\treadonly routedUrl?: string | null;\n}\n\nconst DEFAULT_SHUTDOWN_GRACE_MS = 5_000;\nconst DEFAULT_HTTP_READY_TIMEOUT_MS = 60_000;\nconst DEFAULT_HTTP_READY_INTERVAL_MS = 250;\nconst DEFAULT_LOG_READY_TIMEOUT_MS = 60_000;\nconst READY_STREAM_VALUES = ['stdout', 'stderr', 'both'] as const;\n\nconst shellInvocationFor = (script: string): { command: string; args: ReadonlyArray<string> } => {\n\tif (process.platform === 'win32') {\n\t\treturn {\n\t\t\tcommand: process.env.ComSpec ?? process.env.COMSPEC ?? 'cmd.exe',\n\t\t\targs: ['/d', '/s', '/c', script],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: '/bin/sh',\n\t\targs: ['-c', script],\n\t};\n};\n\nconst configErrorFor =\n\t(serviceName: string) => (issue: Parameters<typeof hostServiceConfigError>[1]) =>\n\t\thostServiceConfigError(serviceName, issue);\n\nconst normalizeReadyProbe = (\n\tserviceName: string,\n\tready: HostServiceReadyProbe | undefined,\n): HostServiceReadyProbe | undefined => {\n\tif (ready === undefined) return undefined;\n\tconst mkError = configErrorFor(serviceName);\n\tif (ready.kind === 'http') {\n\t\tif (ready.url !== undefined) {\n\t\t\texpectNonEmptyString(ready.url, { field: 'ready.url', mkError });\n\t\t}\n\t\texpectOptionalPositiveInteger(ready.timeoutMs, { field: 'ready.timeoutMs', mkError });\n\t\texpectOptionalPositiveInteger(ready.intervalMs, { field: 'ready.intervalMs', mkError });\n\t\treturn ready;\n\t}\n\tif (ready.kind === 'log') {\n\t\tif (typeof ready.pattern !== 'string' && !(ready.pattern instanceof RegExp)) {\n\t\t\tthrow mkError({ field: 'ready.pattern', message: 'must be a string or RegExp' });\n\t\t}\n\t\tif (ready.stream !== undefined && !READY_STREAM_VALUES.includes(ready.stream)) {\n\t\t\tthrow mkError({\n\t\t\t\tfield: 'ready.stream',\n\t\t\t\tmessage: \"must be one of 'stdout', 'stderr', 'both'\",\n\t\t\t});\n\t\t}\n\t\texpectOptionalPositiveInteger(ready.timeoutMs, { field: 'ready.timeoutMs', mkError });\n\t\treturn ready;\n\t}\n\tthrow mkError({ field: 'ready.kind', message: \"must be 'http' or 'log'\" });\n};\n\nexport const normalizeHostServiceOptions = (\n\toptions: HostServiceOptions,\n): HostServiceResolvedOptions => {\n\tconst endpointName = options.endpointName ?? HOST_SERVICE_DEFAULT_ENDPOINT_NAME;\n\tconst serviceName = options.name ?? endpointName;\n\tconst mkError = configErrorFor(serviceName);\n\texpectNonEmptyString(serviceName, { field: 'name', mkError });\n\texpectNonEmptyString(endpointName, { field: 'endpointName', mkError });\n\n\tconst rawCommand = (options as { readonly command?: unknown }).command;\n\tconst rawArgs = (options as { readonly args?: unknown }).args;\n\tconst rawScript = (options as { readonly script?: unknown }).script;\n\tif (rawCommand !== undefined && rawScript !== undefined) {\n\t\tthrow mkError({ field: 'command', message: 'use either command or script, not both' });\n\t}\n\tif (rawCommand === undefined && rawScript === undefined) {\n\t\tthrow mkError({ field: 'command', message: 'is required unless script is provided' });\n\t}\n\tif (rawScript !== undefined && rawArgs !== undefined) {\n\t\tthrow mkError({ field: 'args', message: 'args are only supported with command' });\n\t}\n\n\tif (\n\t\toptions.port !== undefined &&\n\t\t!(\n\t\t\ttypeof options.port === 'number' &&\n\t\t\tNumber.isInteger(options.port) &&\n\t\t\toptions.port > 0 &&\n\t\t\toptions.port <= 65_535\n\t\t)\n\t) {\n\t\tthrow mkError({ field: 'port', message: 'must be an integer between 1 and 65535' });\n\t}\n\tconst preferredPort = options.port;\n\tconst cwd = resolve(options.cwd ?? process.cwd());\n\tconst rawEnv = options.env;\n\tif (rawEnv !== undefined) {\n\t\tif (typeof rawEnv !== 'object' || rawEnv === null || Array.isArray(rawEnv)) {\n\t\t\tthrow mkError({ field: 'env', message: 'must be an object of string values' });\n\t\t}\n\t\tfor (const [key, entry] of Object.entries(rawEnv)) {\n\t\t\tif (key.length === 0) {\n\t\t\t\tthrow mkError({ field: 'env', message: 'environment variable names must be non-empty' });\n\t\t\t}\n\t\t\tif (typeof entry !== 'string') {\n\t\t\t\tthrow mkError({ field: `env.${key}`, message: 'must be a string' });\n\t\t\t}\n\t\t}\n\t}\n\tconst env: Readonly<Record<string, string>> = rawEnv ?? {};\n\tconst shutdownGraceMs =\n\t\texpectOptionalPositiveInteger(options.shutdownGraceMs, {\n\t\t\tfield: 'shutdownGraceMs',\n\t\t\tmkError,\n\t\t}) ?? DEFAULT_SHUTDOWN_GRACE_MS;\n\tconst ready = normalizeReadyProbe(serviceName, options.ready);\n\tconst invocation =\n\t\trawScript !== undefined\n\t\t\t? shellInvocationFor(expectNonEmptyString(rawScript, { field: 'script', mkError }))\n\t\t\t: {\n\t\t\t\t\tcommand: expectNonEmptyString(rawCommand, { field: 'command', mkError }),\n\t\t\t\t\targs: options.args ?? [],\n\t\t\t\t};\n\n\treturn {\n\t\tserviceName,\n\t\tendpointName,\n\t\tcommand: invocation.command,\n\t\targs: invocation.args,\n\t\tcwd,\n\t\t...(preferredPort === undefined ? {} : { preferredPort }),\n\t\tenv,\n\t\t...(ready === undefined ? {} : { ready }),\n\t\tshutdownGraceMs,\n\t};\n};\n\nconst renderPortToken = (value: string, port: number): string =>\n\tvalue.replaceAll(HOST_SERVICE_PORT_TOKEN, String(port));\n\n/** Heuristic: catastrophic-backtracking patterns typically nest a\n * quantifier inside another quantifier (e.g. `(a+)+`, `(a*)*`,\n * `(a|a)*`). This is intentionally conservative — it flags clearly\n * risky shapes without trying to be a real ReDoS analyzer. The\n * guard runs once at host-service start and only emits a warning,\n * not a fail-stop. */\nconst looksRedosProne = (pattern: RegExp): boolean => {\n\tconst source = pattern.source;\n\t// `(...)<quant><quant>` — quantifier directly after a group's quantifier.\n\tif (/\\)[*+?](?:\\{[^}]*\\})?[*+?]/.test(source)) return true;\n\t// `(...<quant>...)<quant>` — quantifier inside a group that itself is quantified.\n\tif (/\\([^()]*[*+?][^()]*\\)[*+?]/.test(source)) return true;\n\t// `(a|a)*` style — alternation with overlapping branches under a quantifier.\n\tif (/\\([^()]*\\|[^()]*\\)[*+]/.test(source)) return true;\n\treturn false;\n};\n\nconst renderCommand = (\n\toptions: HostServiceResolvedOptions,\n\tport: number,\n): {\n\treadonly command: string;\n\treadonly args: ReadonlyArray<string>;\n\treadonly env: NodeJS.ProcessEnv;\n} => {\n\tconst renderedEnv: NodeJS.ProcessEnv = {};\n\tfor (const [key, value] of Object.entries(options.env)) {\n\t\trenderedEnv[key] = renderPortToken(value, port);\n\t}\n\treturn {\n\t\tcommand: renderPortToken(options.command, port),\n\t\targs: options.args.map((arg) => renderPortToken(arg, port)),\n\t\tenv: renderedEnv,\n\t};\n};\n\nconst hostServiceValue = (\n\toptions: HostServiceResolvedOptions,\n\tport: number,\n\trendered: { readonly command: string; readonly args: ReadonlyArray<string> },\n\troutedUrl: string | null,\n): HostServiceValue => ({\n\tname: options.serviceName,\n\tendpointName: options.endpointName,\n\tcommand: rendered.command,\n\targs: rendered.args,\n\tcwd: options.cwd,\n\tport,\n\t// Canonical routed URL when the supervisor derived one, raw loopback\n\t// otherwise. `port` above always stays the real bound loopback port —\n\t// callers that need the bind target (readiness, direct host tooling)\n\t// read `.port`, not `.url`.\n\turl: routedUrl ?? `http://127.0.0.1:${port}`,\n});\n\nconst terminateChild = (\n\tchild: HostProcessChild,\n\ttimeoutMs: number,\n\tlogger: LoggerShape,\n\tpluginKey: PluginKey,\n\ttag: string,\n): Effect.Effect<void> =>\n\tterminateManagedProcess(child, {\n\t\tgraceMs: timeoutMs,\n\t\tprocessGroup: true,\n\t\tonEscalate: () =>\n\t\t\tlogger.log(tag, pluginKey, {\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage: 'host service did not exit after SIGTERM; sending SIGKILL',\n\t\t\t\tfields: { [SpanAttr.event]: 'process.shutdown.escalated' },\n\t\t\t}),\n\t});\n\nconst httpReady = (\n\turl: string,\n\ttimeoutMs: number,\n\tintervalMs: number,\n\texit: Promise<{ readonly code: number | null; readonly signal: NodeJS.Signals | null }>,\n\tprocessError: Promise<unknown>,\n\terror: HostServiceAcquireError,\n): Effect.Effect<void, HostServiceAcquireError> =>\n\tawaitManagedProcessReady({\n\t\tready: waitForHttpEndpoint({\n\t\t\tendpoint: url,\n\t\t\ttimeoutMs,\n\t\t\tintervalMs,\n\t\t\t// HTTP readiness is a health check: require a 200 from the probed\n\t\t\t// `url` ITSELF. `redirect: 'manual'` means a 3xx is not followed —\n\t\t\t// it reads as `status 0`, so a server that 302s to a 200 login page\n\t\t\t// is NOT counted as ready off the redirect target. Point `url` at an\n\t\t\t// endpoint that returns 200 when the service is up (default: the\n\t\t\t// service root). Anything else — a still-compiling dev server, a\n\t\t\t// 5xx, a redirect — keeps polling until the readiness timeout. Use a\n\t\t\t// `log` probe instead when 200-at-a-URL isn't the right signal.\n\t\t\trequestInit: { redirect: 'manual' },\n\t\t\tvalidate: (response) => response.status === 200,\n\t\t}).pipe(\n\t\t\tEffect.mapError(\n\t\t\t\t(cause) =>\n\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t...error,\n\t\t\t\t\t\tphase: 'ready',\n\t\t\t\t\t\tmessage: `host service did not become ready at ${url} within ${timeoutMs}ms`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t}),\n\t\t\t),\n\t\t),\n\t\texit,\n\t\tprocessError,\n\t\tonExitBeforeReady: (status) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'exit',\n\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\texitCode: status.code,\n\t\t\t\tsignal: status.signal,\n\t\t\t}),\n\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'spawn',\n\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nexport const logReady = (\n\tready: Extract<HostServiceReadyProbe, { readonly kind: 'log' }>,\n\treadySignal: Promise<void>,\n\texit: Promise<{ readonly code: number | null; readonly signal: NodeJS.Signals | null }>,\n\tprocessError: Promise<unknown>,\n\terror: HostServiceAcquireError,\n): Effect.Effect<void, HostServiceAcquireError> =>\n\tawaitManagedProcessReady({\n\t\tready: Effect.tryPromise({\n\t\t\ttry: () =>\n\t\t\t\tnew Promise<void>((resolveReady, rejectReady) => {\n\t\t\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\t\t\trejectReady(\n\t\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t\t...error,\n\t\t\t\t\t\t\t\tphase: 'ready',\n\t\t\t\t\t\t\t\tmessage: `host service did not emit readiness log within ${ready.timeoutMs ?? DEFAULT_LOG_READY_TIMEOUT_MS}ms`,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}, ready.timeoutMs ?? DEFAULT_LOG_READY_TIMEOUT_MS);\n\t\t\t\t\treadySignal.then(\n\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\tresolveReady();\n\t\t\t\t\t\t},\n\t\t\t\t\t\t// Thread a rejecting readiness signal through as the\n\t\t\t\t\t\t// inner-Promise rejection (a non-tagged cause). Without\n\t\t\t\t\t\t// this `onRejected` handler a rejected signal would be an\n\t\t\t\t\t\t// unhandled rejection and the `catch:` arm below could\n\t\t\t\t\t\t// never see it. The `catch` arm preserves this raw cause\n\t\t\t\t\t\t// on `HostServiceAcquireError.cause`.\n\t\t\t\t\t\t(cause: unknown) => {\n\t\t\t\t\t\t\tclearTimeout(timeout);\n\t\t\t\t\t\t\trejectReady(cause);\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t}),\n\t\t\tcatch: (cause) =>\n\t\t\t\tcause instanceof HostServiceAcquireError\n\t\t\t\t\t? cause\n\t\t\t\t\t: new HostServiceAcquireError({\n\t\t\t\t\t\t\tserviceName: error.serviceName,\n\t\t\t\t\t\t\tcwd: error.cwd,\n\t\t\t\t\t\t\tcommand: error.command,\n\t\t\t\t\t\t\targs: error.args,\n\t\t\t\t\t\t\tphase: error.phase,\n\t\t\t\t\t\t\tmessage: error.message,\n\t\t\t\t\t\t\texitCode: error.exitCode,\n\t\t\t\t\t\t\tsignal: error.signal,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t}),\n\t\texit,\n\t\tprocessError,\n\t\tonExitBeforeReady: (status) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'exit',\n\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\texitCode: status.code,\n\t\t\t\tsignal: status.signal,\n\t\t\t}),\n\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\tnew HostServiceAcquireError({\n\t\t\t\t...error,\n\t\t\t\tphase: 'spawn',\n\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\tcause,\n\t\t\t}),\n\t});\n\nconst allocateHostPort = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<number, HostServiceAcquireError, Scope.Scope> =>\n\tctx.allocatePort(options.preferredPort).pipe(\n\t\tEffect.mapError(\n\t\t\t(cause) =>\n\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\tserviceName: options.serviceName,\n\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\tcommand: options.command,\n\t\t\t\t\targs: options.args,\n\t\t\t\t\tphase: 'allocate-port',\n\t\t\t\t\tmessage: 'host service failed to allocate HTTP port',\n\t\t\t\t\tcause,\n\t\t\t\t}),\n\t\t),\n\t);\n\nconst startHostProcess = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n\tport: number,\n): Effect.Effect<void, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst rendered = renderCommand(options, port);\n\t\t// Per-stack discovery identity for in-child build integrations\n\t\t// (the `devstack` Vite plugin). These are a LOW-precedence base\n\t\t// layer: the inherited process env and the user's explicit\n\t\t// `options.env` both spread on top, so a user-set\n\t\t// `DEVSTACK_STACK` / `DEVSTACK_RUNTIME_ROOT` always wins. The\n\t\t// literal var names + the `RUNTIME_ROOT`-over-`STATE_DIR`\n\t\t// preference mirror `resolveDiscoveryEnv` (the plugin's reader);\n\t\t// `runtimeRoot` is absolute, so `discoverManifestPath` resolves\n\t\t// `<runtimeRoot>/stacks/<stack>/manifest.json` directly — exactly\n\t\t// where the supervisor writes the manifest.\n\t\tconst discoveryEnv: NodeJS.ProcessEnv =\n\t\t\tctx.discoveryIdentity === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tDEVSTACK_STACK: ctx.discoveryIdentity.stack,\n\t\t\t\t\t\tDEVSTACK_RUNTIME_ROOT: ctx.discoveryIdentity.runtimeRoot,\n\t\t\t\t\t};\n\t\tconst env: NodeJS.ProcessEnv = {\n\t\t\t...discoveryEnv,\n\t\t\t...(ctx.processEnv ?? process.env),\n\t\t\t...rendered.env,\n\t\t\tPORT: String(port),\n\t\t};\n\t\tconst tag = `host-service/${options.serviceName}`;\n\t\t// One-time ReDoS-shape warning. The log observer runs `RegExp.test`\n\t\t// synchronously per stdout/stderr line; a catastrophic-backtracking\n\t\t// pattern would wedge the observer fiber on adversarial output.\n\t\tif (\n\t\t\toptions.ready?.kind === 'log' &&\n\t\t\toptions.ready.pattern instanceof RegExp &&\n\t\t\tlooksRedosProne(options.ready.pattern)\n\t\t) {\n\t\t\tyield* ctx.logger.log(tag, ctx.pluginKey, {\n\t\t\t\tlevel: 'warn',\n\t\t\t\tmessage:\n\t\t\t\t\t'host service readiness pattern has a nested-quantifier shape that may exhibit catastrophic backtracking on adversarial output; prefer anchored, non-nested patterns',\n\t\t\t\tfields: {\n\t\t\t\t\t[SpanAttr.serviceName]: options.serviceName,\n\t\t\t\t\t[SpanAttr.event]: 'host-service.ready-pattern.redos-warning',\n\t\t\t\t\t// Namespaced diagnostic field (the offending pattern source),\n\t\t\t\t\t// consistent with the `event` name above. A bare `pattern`\n\t\t\t\t\t// key collides with the generic attribute vocabulary.\n\t\t\t\t\t'host-service.ready-pattern.source': options.ready.pattern.source,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\tlet resolveLogReady: (() => void) | undefined;\n\t\tconst logReadySignal =\n\t\t\toptions.ready?.kind === 'log'\n\t\t\t\t? new Promise<void>((resolveReady) => {\n\t\t\t\t\t\tresolveLogReady = resolveReady;\n\t\t\t\t\t})\n\t\t\t\t: null;\n\t\tconst observeReadinessLine = (line: string, stream: 'stdout' | 'stderr'): void => {\n\t\t\tif (options.ready?.kind !== 'log') return;\n\t\t\tif (\n\t\t\t\toptions.ready.stream !== undefined &&\n\t\t\t\toptions.ready.stream !== 'both' &&\n\t\t\t\toptions.ready.stream !== stream\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst matches =\n\t\t\t\ttypeof options.ready.pattern === 'string'\n\t\t\t\t\t? line.includes(options.ready.pattern)\n\t\t\t\t\t: options.ready.pattern.test(line);\n\t\t\tif (matches) resolveLogReady?.();\n\t\t};\n\n\t\tconst spawnChild = ctx.spawner ?? nodeProcessSpawner;\n\t\t// Mutable cells declared before the setup block so the terminator\n\t\t// finalizer below can observe them.\n\t\tlet shuttingDown = false;\n\t\tlet exitStatus: {\n\t\t\treadonly code: number | null;\n\t\t\treadonly signal: NodeJS.Signals | null;\n\t\t} | null = null;\n\t\t// Atomic, deadlock-free process setup.\n\t\t//\n\t\t// Three things happen in one `Effect.uninterruptible` region — spawn,\n\t\t// fork the stdout/stderr line drains (`observeProcessLines`), and\n\t\t// register the kill finalizer — so that:\n\t\t//\n\t\t// 1. No interrupt can land between a successful spawn and the finalizer\n\t\t// registration. That gap was the original leak window: a SIGINT\n\t\t// mid-boot could orphan a detached child still holding its port.\n\t\t//\n\t\t// 2. The terminator finalizer is registered *after* the drain fibers,\n\t\t// so on scope close (LIFO) it runs *before* they are interrupted.\n\t\t// This ordering is load-bearing: the drains read the child's stdout/\n\t\t// stderr via `Stream.fromAsyncIterable`, whose `iterator.next()`\n\t\t// park is NON-interruptible — it only unblocks when the stream ends.\n\t\t// The child's streams end when the child is killed. So the\n\t\t// terminator must run first to kill the child (ending the streams),\n\t\t// which lets the drains drain-to-end and their interrupts complete.\n\t\t// Registering the terminator *before* the drains (e.g. via\n\t\t// `acquireRelease` at the top, or any pre-`observeProcessLines`\n\t\t// finalizer) inverts this and deadlocks scope close: the drain\n\t\t// interrupt can never complete because the terminator that would end\n\t\t// its stream is queued to run after it.\n\t\t//\n\t\t// The post-readiness `exited`/`processError` observers below are\n\t\t// registered later still, so they are interrupted before the terminator\n\t\t// runs — their `Effect.promise` waits are interruptible, so that unwinds\n\t\t// cleanly without needing the child to exit first.\n\t\tconst child = yield* Effect.uninterruptible(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst spawned = yield* Effect.try({\n\t\t\t\t\ttry: () =>\n\t\t\t\t\t\tspawnChild(rendered.command, rendered.args, {\n\t\t\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\t\t\tenv,\n\t\t\t\t\t\t\tstdio: 'pipe',\n\t\t\t\t\t\t\tdetached: process.platform !== 'win32',\n\t\t\t\t\t\t}),\n\t\t\t\t\tcatch: (cause) =>\n\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\tserviceName: options.serviceName,\n\t\t\t\t\t\t\tcwd: options.cwd,\n\t\t\t\t\t\t\tcommand: rendered.command,\n\t\t\t\t\t\t\targs: rendered.args,\n\t\t\t\t\t\t\tphase: 'spawn',\n\t\t\t\t\t\t\tmessage: 'host service spawn failed',\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\tyield* observeProcessLines(\n\t\t\t\t\t{\n\t\t\t\t\t\tstdout: readableToByteStream(\n\t\t\t\t\t\t\tspawned.stdout as unknown as AsyncIterable<Uint8Array> | null | undefined,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tstderr: readableToByteStream(\n\t\t\t\t\t\t\tspawned.stderr as unknown as AsyncIterable<Uint8Array> | null | undefined,\n\t\t\t\t\t\t),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tlogger: ctx.logger,\n\t\t\t\t\t\tpluginKey: ctx.pluginKey,\n\t\t\t\t\t\ttag,\n\t\t\t\t\t\tfields: { [SpanAttr.serviceName]: options.serviceName },\n\t\t\t\t\t\tonLine: ({ line, stream }) =>\n\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\tobserveReadinessLine(line, stream);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tshuttingDown = true;\n\t\t\t\t\t\tif (exitStatus !== null) return;\n\t\t\t\t\t\tyield* terminateChild(spawned, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\treturn spawned;\n\t\t\t}),\n\t\t);\n\t\tconst exited = onceProcessExit(child).then((status) => {\n\t\t\texitStatus = status;\n\t\t\treturn status;\n\t\t});\n\t\tconst processError = onceProcessError(child);\n\n\t\tconst baseError = new HostServiceAcquireError({\n\t\t\tserviceName: options.serviceName,\n\t\t\tcwd: options.cwd,\n\t\t\tcommand: rendered.command,\n\t\t\targs: rendered.args,\n\t\t\tphase: 'ready',\n\t\t\tmessage: 'host service readiness failed',\n\t\t});\n\t\tconst awaitReadiness = (() => {\n\t\t\tif (options.ready?.kind === 'http') {\n\t\t\t\tconst url = renderPortToken(options.ready.url ?? 'http://127.0.0.1:{port}', port);\n\t\t\t\treturn httpReady(\n\t\t\t\t\turl,\n\t\t\t\t\toptions.ready.timeoutMs ?? DEFAULT_HTTP_READY_TIMEOUT_MS,\n\t\t\t\t\toptions.ready.intervalMs ?? DEFAULT_HTTP_READY_INTERVAL_MS,\n\t\t\t\t\texited,\n\t\t\t\t\tprocessError,\n\t\t\t\t\tbaseError,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (options.ready?.kind === 'log' && logReadySignal !== null) {\n\t\t\t\treturn logReady(options.ready, logReadySignal, exited, processError, baseError);\n\t\t\t}\n\t\t\treturn Effect.gen(function* () {\n\t\t\t\tyield* awaitManagedProcessReady({\n\t\t\t\t\tready: Effect.promise(\n\t\t\t\t\t\t() => new Promise<void>((resolveReady) => setTimeout(resolveReady, 0)),\n\t\t\t\t\t),\n\t\t\t\t\texit: exited,\n\t\t\t\t\tprocessError,\n\t\t\t\t\tonExitBeforeReady: (status) =>\n\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t...baseError,\n\t\t\t\t\t\t\tphase: 'exit',\n\t\t\t\t\t\t\tmessage: 'host service exited before readiness',\n\t\t\t\t\t\t\texitCode: status.code,\n\t\t\t\t\t\t\tsignal: status.signal,\n\t\t\t\t\t\t}),\n\t\t\t\t\tonProcessErrorBeforeReady: (cause) =>\n\t\t\t\t\t\tnew HostServiceAcquireError({\n\t\t\t\t\t\t\t...baseError,\n\t\t\t\t\t\t\tphase: 'spawn',\n\t\t\t\t\t\t\tmessage: 'host service process failed before readiness',\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t});\n\t\t})();\n\t\tconst readinessExit = yield* Effect.exit(awaitReadiness);\n\t\tif (Exit.isFailure(readinessExit)) {\n\t\t\tshuttingDown = true;\n\t\t\tif (exitStatus === null) {\n\t\t\t\tyield* terminateChild(child, options.shutdownGraceMs, ctx.logger, ctx.pluginKey, tag);\n\t\t\t}\n\t\t\treturn yield* Effect.failCause(readinessExit.cause);\n\t\t}\n\n\t\t// Post-readiness observers. These previously used `void\n\t\t// promise.then(() => Effect.runPromise(...))` which could fire\n\t\t// AFTER the surrounding Scope had already closed (running logger\n\t\t// effects outside any scope, with `.catch(() => {})` swallowing\n\t\t// any failures). Fork into the Scope via `Effect.forkScoped` so\n\t\t// that scope-close interrupts the observer fiber cleanly — the\n\t\t// finalizer flips `shuttingDown` first, so expected-exit cases\n\t\t// still no-op as before. These observers are registered after the\n\t\t// terminator finalizer, so on scope close they are interrupted before\n\t\t// it runs; their `Effect.promise` waits are interruptible, so they\n\t\t// unwind cleanly without waiting on the child to exit.\n\t\tyield* Effect.forkScoped(\n\t\t\tEffect.promise(() => exited).pipe(\n\t\t\t\tEffect.flatMap((status) =>\n\t\t\t\t\tshuttingDown\n\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t: ctx.logger.log(tag, ctx.pluginKey, {\n\t\t\t\t\t\t\t\tlevel: 'error',\n\t\t\t\t\t\t\t\tmessage: 'host service exited after readiness',\n\t\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\t\t[SpanAttr.event]: 'process.exited',\n\t\t\t\t\t\t\t\t\t[SpanAttr.serviceName]: options.serviceName,\n\t\t\t\t\t\t\t\t\t[SpanAttr.exitCode]: status.code,\n\t\t\t\t\t\t\t\t\t[SpanAttr.exitSignal]: status.signal,\n\t\t\t\t\t\t\t\t\t[SpanAttr.exitStatus]: describeProcessExitStatus(status),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t\tyield* Effect.forkScoped(\n\t\t\tEffect.promise(() => processError).pipe(\n\t\t\t\tEffect.flatMap((cause) =>\n\t\t\t\t\tshuttingDown\n\t\t\t\t\t\t? Effect.void\n\t\t\t\t\t\t: ctx.logger.log(tag, ctx.pluginKey, {\n\t\t\t\t\t\t\t\tlevel: 'error',\n\t\t\t\t\t\t\t\tmessage: 'host service process emitted an error after readiness',\n\t\t\t\t\t\t\t\tfields: {\n\t\t\t\t\t\t\t\t\t[SpanAttr.event]: 'process.error',\n\t\t\t\t\t\t\t\t\t[SpanAttr.serviceName]: options.serviceName,\n\t\t\t\t\t\t\t\t\t[SpanAttr.errorCause]: cause,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\t});\n\nexport const prepareHostService = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<PreparedHostService, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst port = yield* allocateHostPort(options, ctx);\n\t\tconst rendered = renderCommand(options, port);\n\t\tconst started = yield* Ref.make(false);\n\t\tconst start = Effect.gen(function* () {\n\t\t\tif (yield* Ref.get(started)) return;\n\t\t\tyield* startHostProcess(options, ctx, port);\n\t\t\tyield* Ref.set(started, true);\n\t\t});\n\n\t\treturn {\n\t\t\tvalue: hostServiceValue(options, port, rendered, ctx.routedUrl ?? null),\n\t\t\tstart,\n\t\t};\n\t});\n\nexport const acquireHostService = (\n\toptions: HostServiceResolvedOptions,\n\tctx: HostServiceAcquireContext,\n): Effect.Effect<HostServiceValue, HostServiceAcquireError, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst prepared = yield* prepareHostService(options, ctx);\n\t\tyield* prepared.start;\n\t\treturn prepared.value;\n\t});\n"],"mappings":";;;;;;;;;;;AAkCA,MAAa,0BAA0B;AAuJvC,MAAM,4BAA4B;AAClC,MAAM,gCAAgC;AACtC,MAAM,iCAAiC;AACvC,MAAM,+BAA+B;AACrC,MAAM,sBAAsB;CAAC;CAAU;CAAU;CAAO;AAExD,MAAM,sBAAsB,WAAqE;AAChG,KAAI,QAAQ,aAAa,QACxB,QAAO;EACN,SAAS,QAAQ,IAAI,WAAW,QAAQ,IAAI,WAAW;EACvD,MAAM;GAAC;GAAM;GAAM;GAAM;GAAO;EAChC;AAEF,QAAO;EACN,SAAS;EACT,MAAM,CAAC,MAAM,OAAO;EACpB;;AAGF,MAAM,kBACJ,iBAAyB,UACzB,uBAAuB,aAAa,MAAM;AAE5C,MAAM,uBACL,aACA,UACuC;AACvC,KAAI,UAAU,KAAA,EAAW,QAAO,KAAA;CAChC,MAAM,UAAU,eAAe,YAAY;AAC3C,KAAI,MAAM,SAAS,QAAQ;AAC1B,MAAI,MAAM,QAAQ,KAAA,EACjB,sBAAqB,MAAM,KAAK;GAAE,OAAO;GAAa;GAAS,CAAC;AAEjE,gCAA8B,MAAM,WAAW;GAAE,OAAO;GAAmB;GAAS,CAAC;AACrF,gCAA8B,MAAM,YAAY;GAAE,OAAO;GAAoB;GAAS,CAAC;AACvF,SAAO;;AAER,KAAI,MAAM,SAAS,OAAO;AACzB,MAAI,OAAO,MAAM,YAAY,YAAY,EAAE,MAAM,mBAAmB,QACnE,OAAM,QAAQ;GAAE,OAAO;GAAiB,SAAS;GAA8B,CAAC;AAEjF,MAAI,MAAM,WAAW,KAAA,KAAa,CAAC,oBAAoB,SAAS,MAAM,OAAO,CAC5E,OAAM,QAAQ;GACb,OAAO;GACP,SAAS;GACT,CAAC;AAEH,gCAA8B,MAAM,WAAW;GAAE,OAAO;GAAmB;GAAS,CAAC;AACrF,SAAO;;AAER,OAAM,QAAQ;EAAE,OAAO;EAAc,SAAS;EAA2B,CAAC;;AAG3E,MAAa,+BACZ,YACgC;CAChC,MAAM,eAAe,QAAQ,gBAAA;CAC7B,MAAM,cAAc,QAAQ,QAAQ;CACpC,MAAM,UAAU,eAAe,YAAY;AAC3C,sBAAqB,aAAa;EAAE,OAAO;EAAQ;EAAS,CAAC;AAC7D,sBAAqB,cAAc;EAAE,OAAO;EAAgB;EAAS,CAAC;CAEtE,MAAM,aAAc,QAA2C;CAC/D,MAAM,UAAW,QAAwC;CACzD,MAAM,YAAa,QAA0C;AAC7D,KAAI,eAAe,KAAA,KAAa,cAAc,KAAA,EAC7C,OAAM,QAAQ;EAAE,OAAO;EAAW,SAAS;EAA0C,CAAC;AAEvF,KAAI,eAAe,KAAA,KAAa,cAAc,KAAA,EAC7C,OAAM,QAAQ;EAAE,OAAO;EAAW,SAAS;EAAyC,CAAC;AAEtF,KAAI,cAAc,KAAA,KAAa,YAAY,KAAA,EAC1C,OAAM,QAAQ;EAAE,OAAO;EAAQ,SAAS;EAAwC,CAAC;AAGlF,KACC,QAAQ,SAAS,KAAA,KACjB,EACC,OAAO,QAAQ,SAAS,YACxB,OAAO,UAAU,QAAQ,KAAK,IAC9B,QAAQ,OAAO,KACf,QAAQ,QAAQ,OAGjB,OAAM,QAAQ;EAAE,OAAO;EAAQ,SAAS;EAA0C,CAAC;CAEpF,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,MAAM,QAAQ,QAAQ,OAAO,QAAQ,KAAK,CAAC;CACjD,MAAM,SAAS,QAAQ;AACvB,KAAI,WAAW,KAAA,GAAW;AACzB,MAAI,OAAO,WAAW,YAAY,WAAW,QAAQ,MAAM,QAAQ,OAAO,CACzE,OAAM,QAAQ;GAAE,OAAO;GAAO,SAAS;GAAsC,CAAC;AAE/E,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,EAAE;AAClD,OAAI,IAAI,WAAW,EAClB,OAAM,QAAQ;IAAE,OAAO;IAAO,SAAS;IAAgD,CAAC;AAEzF,OAAI,OAAO,UAAU,SACpB,OAAM,QAAQ;IAAE,OAAO,OAAO;IAAO,SAAS;IAAoB,CAAC;;;CAItE,MAAM,MAAwC,UAAU,EAAE;CAC1D,MAAM,kBACL,8BAA8B,QAAQ,iBAAiB;EACtD,OAAO;EACP;EACA,CAAC,IAAI;CACP,MAAM,QAAQ,oBAAoB,aAAa,QAAQ,MAAM;CAC7D,MAAM,aACL,cAAc,KAAA,IACX,mBAAmB,qBAAqB,WAAW;EAAE,OAAO;EAAU;EAAS,CAAC,CAAC,GACjF;EACA,SAAS,qBAAqB,YAAY;GAAE,OAAO;GAAW;GAAS,CAAC;EACxE,MAAM,QAAQ,QAAQ,EAAE;EACxB;AAEJ,QAAO;EACN;EACA;EACA,SAAS,WAAW;EACpB,MAAM,WAAW;EACjB;EACA,GAAI,kBAAkB,KAAA,IAAY,EAAE,GAAG,EAAE,eAAe;EACxD;EACA,GAAI,UAAU,KAAA,IAAY,EAAE,GAAG,EAAE,OAAO;EACxC;EACA;;AAGF,MAAM,mBAAmB,OAAe,SACvC,MAAM,WAAW,yBAAyB,OAAO,KAAK,CAAC;;;;;;;AAQxD,MAAM,mBAAmB,YAA6B;CACrD,MAAM,SAAS,QAAQ;AAEvB,KAAI,6BAA6B,KAAK,OAAO,CAAE,QAAO;AAEtD,KAAI,6BAA6B,KAAK,OAAO,CAAE,QAAO;AAEtD,KAAI,yBAAyB,KAAK,OAAO,CAAE,QAAO;AAClD,QAAO;;AAGR,MAAM,iBACL,SACA,SAKI;CACJ,MAAM,cAAiC,EAAE;AACzC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,IAAI,CACrD,aAAY,OAAO,gBAAgB,OAAO,KAAK;AAEhD,QAAO;EACN,SAAS,gBAAgB,QAAQ,SAAS,KAAK;EAC/C,MAAM,QAAQ,KAAK,KAAK,QAAQ,gBAAgB,KAAK,KAAK,CAAC;EAC3D,KAAK;EACL;;AAGF,MAAM,oBACL,SACA,MACA,UACA,eACuB;CACvB,MAAM,QAAQ;CACd,cAAc,QAAQ;CACtB,SAAS,SAAS;CAClB,MAAM,SAAS;CACf,KAAK,QAAQ;CACb;CAKA,KAAK,aAAa,oBAAoB;CACtC;AAED,MAAM,kBACL,OACA,WACA,QACA,WACA,QAEA,wBAAwB,OAAO;CAC9B,SAAS;CACT,cAAc;CACd,kBACC,OAAO,IAAI,KAAK,WAAW;EAC1B,OAAO;EACP,SAAS;EACT,QAAQ,GAAG,SAAS,QAAQ,8BAA8B;EAC1D,CAAC;CACH,CAAC;AAEH,MAAM,aACL,KACA,WACA,YACA,MACA,cACA,UAEA,yBAAyB;CACxB,OAAO,oBAAoB;EAC1B,UAAU;EACV;EACA;EASA,aAAa,EAAE,UAAU,UAAU;EACnC,WAAW,aAAa,SAAS,WAAW;EAC5C,CAAC,CAAC,KACF,OAAO,UACL,UACA,IAAI,wBAAwB;EAC3B,GAAG;EACH,OAAO;EACP,SAAS,wCAAwC,IAAI,UAAU,UAAU;EACzE;EACA,CAAC,CACH,CACD;CACD;CACA;CACA,oBAAoB,WACnB,IAAI,wBAAwB;EAC3B,GAAG;EACH,OAAO;EACP,SAAS;EACT,UAAU,OAAO;EACjB,QAAQ,OAAO;EACf,CAAC;CACH,4BAA4B,UAC3B,IAAI,wBAAwB;EAC3B,GAAG;EACH,OAAO;EACP,SAAS;EACT;EACA,CAAC;CACH,CAAC;AAEH,MAAa,YACZ,OACA,aACA,MACA,cACA,UAEA,yBAAyB;CACxB,OAAO,OAAO,WAAW;EACxB,WACC,IAAI,SAAe,cAAc,gBAAgB;GAChD,MAAM,UAAU,iBAAiB;AAChC,gBACC,IAAI,wBAAwB;KAC3B,GAAG;KACH,OAAO;KACP,SAAS,kDAAkD,MAAM,aAAa,6BAA6B;KAC3G,CAAC,CACF;MACC,MAAM,aAAa,6BAA6B;AACnD,eAAY,WACL;AACL,iBAAa,QAAQ;AACrB,kBAAc;OAQd,UAAmB;AACnB,iBAAa,QAAQ;AACrB,gBAAY,MAAM;KAEnB;IACA;EACH,QAAQ,UACP,iBAAiB,0BACd,QACA,IAAI,wBAAwB;GAC5B,aAAa,MAAM;GACnB,KAAK,MAAM;GACX,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,OAAO,MAAM;GACb,SAAS,MAAM;GACf,UAAU,MAAM;GAChB,QAAQ,MAAM;GACd;GACA,CAAC;EACL,CAAC;CACF;CACA;CACA,oBAAoB,WACnB,IAAI,wBAAwB;EAC3B,GAAG;EACH,OAAO;EACP,SAAS;EACT,UAAU,OAAO;EACjB,QAAQ,OAAO;EACf,CAAC;CACH,4BAA4B,UAC3B,IAAI,wBAAwB;EAC3B,GAAG;EACH,OAAO;EACP,SAAS;EACT;EACA,CAAC;CACH,CAAC;AAEH,MAAM,oBACL,SACA,QAEA,IAAI,aAAa,QAAQ,cAAc,CAAC,KACvC,OAAO,UACL,UACA,IAAI,wBAAwB;CAC3B,aAAa,QAAQ;CACrB,KAAK,QAAQ;CACb,SAAS,QAAQ;CACjB,MAAM,QAAQ;CACd,OAAO;CACP,SAAS;CACT;CACA,CAAC,CACH,CACD;AAEF,MAAM,oBACL,SACA,KACA,SAEA,OAAO,IAAI,aAAa;CACvB,MAAM,WAAW,cAAc,SAAS,KAAK;CAkB7C,MAAM,MAAyB;EAC9B,GAPA,IAAI,sBAAsB,KAAA,IACvB,EAAE,GACF;GACA,gBAAgB,IAAI,kBAAkB;GACtC,uBAAuB,IAAI,kBAAkB;GAC7C;EAGH,GAAI,IAAI,cAAc,QAAQ;EAC9B,GAAG,SAAS;EACZ,MAAM,OAAO,KAAK;EAClB;CACD,MAAM,MAAM,gBAAgB,QAAQ;AAIpC,KACC,QAAQ,OAAO,SAAS,SACxB,QAAQ,MAAM,mBAAmB,UACjC,gBAAgB,QAAQ,MAAM,QAAQ,CAEtC,QAAO,IAAI,OAAO,IAAI,KAAK,IAAI,WAAW;EACzC,OAAO;EACP,SACC;EACD,QAAQ;IACN,SAAS,cAAc,QAAQ;IAC/B,SAAS,QAAQ;GAIlB,qCAAqC,QAAQ,MAAM,QAAQ;GAC3D;EACD,CAAC;CAEH,IAAI;CACJ,MAAM,iBACL,QAAQ,OAAO,SAAS,QACrB,IAAI,SAAe,iBAAiB;AACpC,oBAAkB;GACjB,GACD;CACJ,MAAM,wBAAwB,MAAc,WAAsC;AACjF,MAAI,QAAQ,OAAO,SAAS,MAAO;AACnC,MACC,QAAQ,MAAM,WAAW,KAAA,KACzB,QAAQ,MAAM,WAAW,UACzB,QAAQ,MAAM,WAAW,OAEzB;AAMD,MAHC,OAAO,QAAQ,MAAM,YAAY,WAC9B,KAAK,SAAS,QAAQ,MAAM,QAAQ,GACpC,QAAQ,MAAM,QAAQ,KAAK,KAAK,CACvB,oBAAmB;;CAGjC,MAAM,aAAa,IAAI,WAAW;CAGlC,IAAI,eAAe;CACnB,IAAI,aAGO;CA6BX,MAAM,QAAQ,OAAO,OAAO,gBAC3B,OAAO,IAAI,aAAa;EACvB,MAAM,UAAU,OAAO,OAAO,IAAI;GACjC,WACC,WAAW,SAAS,SAAS,SAAS,MAAM;IAC3C,KAAK,QAAQ;IACb;IACA,OAAO;IACP,UAAU,QAAQ,aAAa;IAC/B,CAAC;GACH,QAAQ,UACP,IAAI,wBAAwB;IAC3B,aAAa,QAAQ;IACrB,KAAK,QAAQ;IACb,SAAS,SAAS;IAClB,MAAM,SAAS;IACf,OAAO;IACP,SAAS;IACT;IACA,CAAC;GACH,CAAC;AACF,SAAO,oBACN;GACC,QAAQ,qBACP,QAAQ,OACR;GACD,QAAQ,qBACP,QAAQ,OACR;GACD,EACD;GACC,QAAQ,IAAI;GACZ,WAAW,IAAI;GACf;GACA,QAAQ,GAAG,SAAS,cAAc,QAAQ,aAAa;GACvD,SAAS,EAAE,MAAM,aAChB,OAAO,WAAW;AACjB,yBAAqB,MAAM,OAAO;KACjC;GACH,CACD;AACD,SAAO,OAAO,mBACb,OAAO,IAAI,aAAa;AACvB,kBAAe;AACf,OAAI,eAAe,KAAM;AACzB,UAAO,eAAe,SAAS,QAAQ,iBAAiB,IAAI,QAAQ,IAAI,WAAW,IAAI;IACtF,CACF;AACD,SAAO;GACN,CACF;CACD,MAAM,SAAS,gBAAgB,MAAM,CAAC,MAAM,WAAW;AACtD,eAAa;AACb,SAAO;GACN;CACF,MAAM,eAAe,iBAAiB,MAAM;CAE5C,MAAM,YAAY,IAAI,wBAAwB;EAC7C,aAAa,QAAQ;EACrB,KAAK,QAAQ;EACb,SAAS,SAAS;EAClB,MAAM,SAAS;EACf,OAAO;EACP,SAAS;EACT,CAAC;CACF,MAAM,wBAAwB;AAC7B,MAAI,QAAQ,OAAO,SAAS,OAE3B,QAAO,UADK,gBAAgB,QAAQ,MAAM,OAAO,2BAA2B,KAExE,EACH,QAAQ,MAAM,aAAa,+BAC3B,QAAQ,MAAM,cAAc,gCAC5B,QACA,cACA,UACA;AAEF,MAAI,QAAQ,OAAO,SAAS,SAAS,mBAAmB,KACvD,QAAO,SAAS,QAAQ,OAAO,gBAAgB,QAAQ,cAAc,UAAU;AAEhF,SAAO,OAAO,IAAI,aAAa;AAC9B,UAAO,yBAAyB;IAC/B,OAAO,OAAO,cACP,IAAI,SAAe,iBAAiB,WAAW,cAAc,EAAE,CAAC,CACtE;IACD,MAAM;IACN;IACA,oBAAoB,WACnB,IAAI,wBAAwB;KAC3B,GAAG;KACH,OAAO;KACP,SAAS;KACT,UAAU,OAAO;KACjB,QAAQ,OAAO;KACf,CAAC;IACH,4BAA4B,UAC3B,IAAI,wBAAwB;KAC3B,GAAG;KACH,OAAO;KACP,SAAS;KACT;KACA,CAAC;IACH,CAAC;IACD;KACC;CACJ,MAAM,gBAAgB,OAAO,OAAO,KAAK,eAAe;AACxD,KAAI,KAAK,UAAU,cAAc,EAAE;AAClC,iBAAe;AACf,MAAI,eAAe,KAClB,QAAO,eAAe,OAAO,QAAQ,iBAAiB,IAAI,QAAQ,IAAI,WAAW,IAAI;AAEtF,SAAO,OAAO,OAAO,UAAU,cAAc,MAAM;;AAcpD,QAAO,OAAO,WACb,OAAO,cAAc,OAAO,CAAC,KAC5B,OAAO,SAAS,WACf,eACG,OAAO,OACP,IAAI,OAAO,IAAI,KAAK,IAAI,WAAW;EACnC,OAAO;EACP,SAAS;EACT,QAAQ;IACN,SAAS,QAAQ;IACjB,SAAS,cAAc,QAAQ;IAC/B,SAAS,WAAW,OAAO;IAC3B,SAAS,aAAa,OAAO;IAC7B,SAAS,aAAa,0BAA0B,OAAO;GACxD;EACD,CAAC,CACJ,CACD,CACD;AACD,QAAO,OAAO,WACb,OAAO,cAAc,aAAa,CAAC,KAClC,OAAO,SAAS,UACf,eACG,OAAO,OACP,IAAI,OAAO,IAAI,KAAK,IAAI,WAAW;EACnC,OAAO;EACP,SAAS;EACT,QAAQ;IACN,SAAS,QAAQ;IACjB,SAAS,cAAc,QAAQ;IAC/B,SAAS,aAAa;GACvB;EACD,CAAC,CACJ,CACD,CACD;EACA;AAEH,MAAa,sBACZ,SACA,QAEA,OAAO,IAAI,aAAa;CACvB,MAAM,OAAO,OAAO,iBAAiB,SAAS,IAAI;CAClD,MAAM,WAAW,cAAc,SAAS,KAAK;CAC7C,MAAM,UAAU,OAAO,IAAI,KAAK,MAAM;CACtC,MAAM,QAAQ,OAAO,IAAI,aAAa;AACrC,MAAI,OAAO,IAAI,IAAI,QAAQ,CAAE;AAC7B,SAAO,iBAAiB,SAAS,KAAK,KAAK;AAC3C,SAAO,IAAI,IAAI,SAAS,KAAK;GAC5B;AAEF,QAAO;EACN,OAAO,iBAAiB,SAAS,MAAM,UAAU,IAAI,aAAa,KAAK;EACvE;EACA;EACA"}
@@ -0,0 +1,23 @@
1
+ import "../../primitives/artifact-publisher.mjs";
2
+ import { Effect } from "effect";
3
+ //#region src/plugins/internal/acquire-on-chain-artifact.ts
4
+ /** Submit an on-chain artifact spec with the universal
5
+ * `register: () => Effect.void` no-op baked in. Returns the substrate's
6
+ * resolved `Produced` payload (decoded cached payload on verify-hit;
7
+ * freshly produced payload on miss).
8
+ *
9
+ * Callers that need a non-void `register` (or a phase-preserving
10
+ * produce wrap) should consume the underlying `publisher.publish`
11
+ * surface directly. */
12
+ const acquireOnChainArtifact = (publisher, spec) => publisher.publish({
13
+ namespace: spec.namespace,
14
+ chain: spec.chain,
15
+ contentHash: spec.contentHash,
16
+ verify: spec.verify,
17
+ produce: spec.produce,
18
+ register: () => Effect.void
19
+ });
20
+ //#endregion
21
+ export { acquireOnChainArtifact };
22
+
23
+ //# sourceMappingURL=acquire-on-chain-artifact.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acquire-on-chain-artifact.mjs","names":[],"sources":["../../../src/plugins/internal/acquire-on-chain-artifact.ts"],"sourcesContent":["// acquireOnChainArtifact — thin compactor over `ArtifactPublisher.publish`.\n//\n// Recurs across plugins that publish on-chain artifacts (coin/mint,\n// deepbook/pyth, deepbook/deploy, …). All three sites share:\n//\n// - the `register: () => Effect.void` no-op (these plugins keep no\n// in-process registry — the cached payload IS the resolved value),\n// - the `publish<Produced, Verified>({namespace, chain, contentHash,\n// verify, produce, register})` skeleton.\n//\n// The helper does NOT touch the `produce` body itself: the three\n// consumers' produce pipelines diverge meaningfully (coin/mint uses\n// `signAndDispatch` against the Account bus; deepbook/{pyth,deploy} use\n// `executeSuiTx` against the raw SDK client). Forcing a union over those\n// shapes would either widen the helper to the point of unhelpfulness or\n// regress one of the consumers. Each consumer continues to compose its\n// own `produce`; the helper centralises the surrounding boilerplate.\n//\n// For the rarer \"phase-preserving produce\" pattern (action plugin's\n// Ref-stash to recover typed-error phases across the substrate's\n// ArtifactPublishError wrap), see\n// `substrate/runtime/phase-preserving-produce.ts`.\n//\n// Boundary discipline: this module lives under `plugins/internal/`\n// because it consumes the public `ArtifactPublisher` surface AND the\n// public `ChainId`/`ContentHash` brands. No plugin-domain types leak in;\n// callers project the `Produced` payload to their resolved value\n// themselves.\n\nimport { Effect, type Scope } from 'effect';\n\nimport type { ChainId, ContentHash } from '../../substrate/brand.ts';\nimport {\n\ttype ArtifactPublishError,\n\ttype ArtifactPublisher,\n\ttype ArtifactSpec,\n} from '../../primitives/artifact-publisher.ts';\n\n/** Spec slice consumed by `acquireOnChainArtifact`. Mirrors\n * `ArtifactSpec<Produced, Verified>` minus the `register` field — the\n * helper supplies the universal `() => Effect.void` register for\n * artifact plugins with no in-process registry to feed. */\nexport interface AcquireOnChainArtifactSpec<Produced, Verified> {\n\treadonly namespace: string;\n\treadonly chain: ChainId;\n\treadonly contentHash: ContentHash;\n\treadonly verify: ArtifactSpec<Produced, Verified>['verify'];\n\treadonly produce: ArtifactSpec<Produced, Verified>['produce'];\n}\n\n/** Submit an on-chain artifact spec with the universal\n * `register: () => Effect.void` no-op baked in. Returns the substrate's\n * resolved `Produced` payload (decoded cached payload on verify-hit;\n * freshly produced payload on miss).\n *\n * Callers that need a non-void `register` (or a phase-preserving\n * produce wrap) should consume the underlying `publisher.publish`\n * surface directly. */\nexport const acquireOnChainArtifact = <Produced, Verified>(\n\tpublisher: ArtifactPublisher,\n\tspec: AcquireOnChainArtifactSpec<Produced, Verified>,\n): Effect.Effect<Produced, ArtifactPublishError, Scope.Scope> =>\n\tpublisher.publish<Produced, Verified>({\n\t\tnamespace: spec.namespace,\n\t\tchain: spec.chain,\n\t\tcontentHash: spec.contentHash,\n\t\tverify: spec.verify,\n\t\tproduce: spec.produce,\n\t\t// Register on EVERY cycle (hit AND miss) — substrate contract\n\t\t// (architecture §10). The on-chain-artifact plugins this helper\n\t\t// serves keep no in-process registry; the cached payload carries\n\t\t// everything callers need.\n\t\tregister: () => Effect.void,\n\t});\n"],"mappings":";;;;;;;;;;;AA0DA,MAAa,0BACZ,WACA,SAEA,UAAU,QAA4B;CACrC,WAAW,KAAK;CAChB,OAAO,KAAK;CACZ,aAAa,KAAK;CAClB,QAAQ,KAAK;CACb,SAAS,KAAK;CAKd,gBAAgB,OAAO;CACvB,CAAC"}