@mysten-incubation/devstack 0.0.1 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (838) hide show
  1. package/README.md +8 -4
  2. package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  3. package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  4. package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  5. package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  6. package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  7. package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  8. package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  9. package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  10. package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  11. package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  12. package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  13. package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
  14. package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
  15. package/dashboard-ui/assets/index-Deml9drg.css +1 -0
  16. package/dashboard-ui/index.html +13 -0
  17. package/dist/api/define-capabilities.d.mts +14 -3
  18. package/dist/api/define-capabilities.mjs +18 -1
  19. package/dist/api/define-capabilities.mjs.map +1 -1
  20. package/dist/api/define-devstack.d.mts +1 -1
  21. package/dist/api/define-devstack.mjs +6 -26
  22. package/dist/api/define-devstack.mjs.map +1 -1
  23. package/dist/api/define-plugin.d.mts +1 -0
  24. package/dist/api/define-plugin.mjs +2 -0
  25. package/dist/api/inference-network.d.mts +132 -0
  26. package/dist/api/inference-network.mjs +105 -16
  27. package/dist/api/inference-network.mjs.map +1 -1
  28. package/dist/api/plugin-errors.d.mts +7 -0
  29. package/dist/api/run-stack.d.mts +20 -9
  30. package/dist/api/run-stack.mjs +56 -29
  31. package/dist/api/run-stack.mjs.map +1 -1
  32. package/dist/build-integrations/playwright/config.d.mts +6 -4
  33. package/dist/build-integrations/playwright/config.mjs +5 -3
  34. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  35. package/dist/build-integrations/playwright/errors.d.mts +1 -1
  36. package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
  37. package/dist/build-integrations/playwright/global-setup.mjs +250 -13
  38. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  39. package/dist/build-integrations/playwright/index.d.mts +5 -3
  40. package/dist/build-integrations/playwright/index.mjs +4 -2
  41. package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
  42. package/dist/build-integrations/playwright/stack-context.mjs +24 -63
  43. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  44. package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
  45. package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
  46. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  47. package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
  48. package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
  49. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
  51. package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
  52. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
  53. package/dist/build-integrations/runtime/discover.d.mts +38 -30
  54. package/dist/build-integrations/runtime/discover.mjs +73 -70
  55. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
  57. package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
  58. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  59. package/dist/build-integrations/runtime/index.d.mts +7 -2
  60. package/dist/build-integrations/runtime/index.mjs +9 -2
  61. package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
  62. package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
  63. package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
  64. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
  65. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
  66. package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
  67. package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
  68. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  69. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
  70. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
  71. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
  72. package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
  73. package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
  74. package/dist/build-integrations/vite/index.d.mts +51 -0
  75. package/dist/build-integrations/vite/index.mjs +73 -0
  76. package/dist/build-integrations/vite/index.mjs.map +1 -0
  77. package/dist/build-integrations/vitest/env.d.mts +4 -3
  78. package/dist/build-integrations/vitest/env.mjs +6 -4
  79. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  80. package/dist/build-integrations/vitest/errors.d.mts +25 -4
  81. package/dist/build-integrations/vitest/errors.mjs +15 -2
  82. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  83. package/dist/build-integrations/vitest/index.d.mts +2 -2
  84. package/dist/build-integrations/vitest/index.mjs +3 -3
  85. package/dist/build-integrations/vitest/setup.d.mts +4 -2
  86. package/dist/build-integrations/vitest/setup.mjs +2 -2
  87. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  88. package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
  89. package/dist/build-integrations/vitest/stack-context.mjs +33 -13
  90. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  91. package/dist/cli/bail.mjs +23 -0
  92. package/dist/cli/bail.mjs.map +1 -0
  93. package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
  94. package/dist/cli/doctor-probes.mjs.map +1 -0
  95. package/dist/cli/main.d.mts +15 -1
  96. package/dist/cli/main.mjs +166 -482
  97. package/dist/cli/main.mjs.map +1 -1
  98. package/dist/cli/prune-direct.mjs +31 -201
  99. package/dist/cli/prune-direct.mjs.map +1 -1
  100. package/dist/cli/snapshot-reader.mjs +14 -11
  101. package/dist/cli/snapshot-reader.mjs.map +1 -1
  102. package/dist/cli/up-lifecycle.mjs +4 -1
  103. package/dist/cli/up-lifecycle.mjs.map +1 -1
  104. package/dist/cli/wirings/apply.mjs +95 -0
  105. package/dist/cli/wirings/apply.mjs.map +1 -0
  106. package/dist/cli/wirings/build-verb-layers.mjs +42 -0
  107. package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
  108. package/dist/cli/wirings/config-loader.mjs +69 -0
  109. package/dist/cli/wirings/config-loader.mjs.map +1 -0
  110. package/dist/cli/wirings/engine-command.mjs +30 -0
  111. package/dist/cli/wirings/engine-command.mjs.map +1 -0
  112. package/dist/cli/wirings/identity.mjs +72 -0
  113. package/dist/cli/wirings/identity.mjs.map +1 -0
  114. package/dist/cli/wirings/provide-file-system.mjs +7 -0
  115. package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
  116. package/dist/cli/wirings/snapshot.mjs +177 -0
  117. package/dist/cli/wirings/snapshot.mjs.map +1 -0
  118. package/dist/cli/wirings/up.mjs +287 -0
  119. package/dist/cli/wirings/up.mjs.map +1 -0
  120. package/dist/cli/wirings/wipe.mjs +40 -0
  121. package/dist/cli/wirings/wipe.mjs.map +1 -0
  122. package/dist/contracts/capability-decl.d.mts +0 -2
  123. package/dist/contracts/codegenable.d.mts +43 -0
  124. package/dist/contracts/container-runtime.d.mts +26 -1
  125. package/dist/contracts/faucet-strategy.d.mts +25 -0
  126. package/dist/contracts/funding-strategy.d.mts +42 -0
  127. package/dist/contracts/plugin-expander.mjs +60 -0
  128. package/dist/contracts/plugin-expander.mjs.map +1 -0
  129. package/dist/contracts/projection.d.mts +5 -3
  130. package/dist/contracts/renderer.d.mts +23 -0
  131. package/dist/contracts/routable.d.mts +14 -1
  132. package/dist/contracts/snapshotable.d.mts +25 -3
  133. package/dist/contracts/wallet-protocol.d.mts +52 -0
  134. package/dist/contracts/wallet-protocol.mjs +52 -0
  135. package/dist/contracts/wallet-protocol.mjs.map +1 -0
  136. package/dist/index.d.mts +26 -25
  137. package/dist/index.mjs +20 -13
  138. package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
  139. package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
  140. package/dist/orchestrators/codegen/bindings.d.mts +1 -2
  141. package/dist/orchestrators/codegen/bindings.mjs +52 -186
  142. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/emit.mjs +19 -1
  144. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  145. package/dist/orchestrators/codegen/errors.mjs +8 -3
  146. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/format.mjs +47 -39
  148. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/gitignore.mjs +3 -1
  150. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  151. package/dist/orchestrators/codegen/output-location.mjs +41 -0
  152. package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
  153. package/dist/orchestrators/codegen/paths.d.mts +1 -1
  154. package/dist/orchestrators/codegen/paths.mjs +40 -14
  155. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  156. package/dist/orchestrators/codegen/permissions.mjs +3 -1
  157. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  158. package/dist/orchestrators/codegen/service.mjs +157 -105
  159. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  160. package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
  161. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
  162. package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
  163. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
  164. package/dist/orchestrators/router/cleanup.mjs +26 -27
  165. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  166. package/dist/orchestrators/router/entrypoints.mjs +2 -2
  167. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  168. package/dist/orchestrators/router/file-provider.mjs +14 -5
  169. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  170. package/dist/orchestrators/router/hostname.mjs +19 -55
  171. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  172. package/dist/orchestrators/router/index.mjs +11 -0
  173. package/dist/orchestrators/router/profile.mjs +2 -2
  174. package/dist/orchestrators/router/sentinels.mjs +26 -0
  175. package/dist/orchestrators/router/sentinels.mjs.map +1 -0
  176. package/dist/orchestrators/router/service.mjs +40 -37
  177. package/dist/orchestrators/router/service.mjs.map +1 -1
  178. package/dist/orchestrators/router/traefik-container.mjs +27 -16
  179. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  180. package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
  181. package/dist/orchestrators/run.mjs.map +1 -0
  182. package/dist/orchestrators/runtime-composition.d.mts +1 -1
  183. package/dist/orchestrators/runtime-composition.mjs +123 -39
  184. package/dist/orchestrators/runtime-composition.mjs.map +1 -1
  185. package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
  186. package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
  187. package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
  188. package/dist/orchestrators/snapshot/capture.mjs +42 -28
  189. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  190. package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
  191. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  192. package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
  193. package/dist/orchestrators/snapshot/index.mjs +13 -0
  194. package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
  195. package/dist/orchestrators/snapshot/integrity.mjs +73 -17
  196. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  197. package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
  198. package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
  199. package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
  200. package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
  201. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
  202. package/dist/orchestrators/snapshot/prune.mjs +20 -55
  203. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  204. package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
  205. package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
  206. package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
  207. package/dist/orchestrators/snapshot/restore.mjs +118 -84
  208. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  209. package/dist/orchestrators/snapshot/service.mjs +53 -56
  210. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  211. package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
  212. package/dist/orchestrators/snapshot/state-document.mjs +47 -7
  213. package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
  214. package/dist/orchestrators/snapshot/wipe.mjs +67 -10
  215. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  216. package/dist/plugins/account/codegen.mjs +9 -8
  217. package/dist/plugins/account/codegen.mjs.map +1 -1
  218. package/dist/plugins/account/errors.d.mts +33 -6
  219. package/dist/plugins/account/errors.mjs.map +1 -1
  220. package/dist/plugins/account/funding.d.mts +29 -19
  221. package/dist/plugins/account/funding.mjs +84 -66
  222. package/dist/plugins/account/funding.mjs.map +1 -1
  223. package/dist/plugins/account/index.d.mts +2 -4
  224. package/dist/plugins/account/index.mjs +64 -31
  225. package/dist/plugins/account/index.mjs.map +1 -1
  226. package/dist/plugins/account/keypair.mjs +6 -9
  227. package/dist/plugins/account/keypair.mjs.map +1 -1
  228. package/dist/plugins/account/lease.mjs +1 -0
  229. package/dist/plugins/account/lease.mjs.map +1 -1
  230. package/dist/plugins/account/registry.d.mts +14 -1
  231. package/dist/plugins/account/registry.mjs +18 -18
  232. package/dist/plugins/account/registry.mjs.map +1 -1
  233. package/dist/plugins/account/service.d.mts +23 -4
  234. package/dist/plugins/account/service.mjs +83 -45
  235. package/dist/plugins/account/service.mjs.map +1 -1
  236. package/dist/plugins/account/snapshot.mjs +2 -5
  237. package/dist/plugins/account/snapshot.mjs.map +1 -1
  238. package/dist/plugins/account/spans.mjs +16 -0
  239. package/dist/plugins/account/spans.mjs.map +1 -0
  240. package/dist/plugins/account/variants/keystore.mjs +6 -8
  241. package/dist/plugins/account/variants/keystore.mjs.map +1 -1
  242. package/dist/plugins/action/build-context.d.mts +3 -2
  243. package/dist/plugins/action/errors.d.mts +16 -12
  244. package/dist/plugins/action/errors.mjs.map +1 -1
  245. package/dist/plugins/action/execute.mjs +65 -103
  246. package/dist/plugins/action/execute.mjs.map +1 -1
  247. package/dist/plugins/action/index.d.mts +0 -2
  248. package/dist/plugins/action/index.mjs +17 -13
  249. package/dist/plugins/action/index.mjs.map +1 -1
  250. package/dist/plugins/action/service.mjs +38 -35
  251. package/dist/plugins/action/service.mjs.map +1 -1
  252. package/dist/plugins/action/spans.mjs +11 -0
  253. package/dist/plugins/action/spans.mjs.map +1 -0
  254. package/dist/plugins/coin/codegen.mjs +9 -8
  255. package/dist/plugins/coin/codegen.mjs.map +1 -1
  256. package/dist/plugins/coin/discovery.mjs +8 -4
  257. package/dist/plugins/coin/discovery.mjs.map +1 -1
  258. package/dist/plugins/coin/index.d.mts +11 -29
  259. package/dist/plugins/coin/index.mjs +56 -27
  260. package/dist/plugins/coin/index.mjs.map +1 -1
  261. package/dist/plugins/coin/metadata.mjs +8 -15
  262. package/dist/plugins/coin/metadata.mjs.map +1 -1
  263. package/dist/plugins/coin/mint.d.mts +30 -11
  264. package/dist/plugins/coin/mint.mjs +78 -74
  265. package/dist/plugins/coin/mint.mjs.map +1 -1
  266. package/dist/plugins/coin/registry.mjs +4 -7
  267. package/dist/plugins/coin/registry.mjs.map +1 -1
  268. package/dist/plugins/coin/service.d.mts +39 -1
  269. package/dist/plugins/coin/service.mjs +11 -4
  270. package/dist/plugins/coin/service.mjs.map +1 -1
  271. package/dist/plugins/coin/spans.mjs +20 -0
  272. package/dist/plugins/coin/spans.mjs.map +1 -0
  273. package/dist/plugins/dashboard/domain.mjs +402 -0
  274. package/dist/plugins/dashboard/domain.mjs.map +1 -0
  275. package/dist/plugins/dashboard/index.d.mts +29 -0
  276. package/dist/plugins/dashboard/index.mjs +91 -0
  277. package/dist/plugins/dashboard/index.mjs.map +1 -0
  278. package/dist/plugins/dashboard/origin-policy.mjs +36 -0
  279. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
  280. package/dist/plugins/dashboard/routable.mjs +27 -0
  281. package/dist/plugins/dashboard/routable.mjs.map +1 -0
  282. package/dist/plugins/dashboard/schema/builder.mjs +21 -0
  283. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
  284. package/dist/plugins/dashboard/schema/enums.mjs +72 -0
  285. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
  286. package/dist/plugins/dashboard/schema/root.mjs +351 -0
  287. package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
  288. package/dist/plugins/dashboard/schema/types.mjs +508 -0
  289. package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
  290. package/dist/plugins/dashboard/schema.mjs +11 -0
  291. package/dist/plugins/dashboard/schema.mjs.map +1 -0
  292. package/dist/plugins/dashboard/server.mjs +166 -0
  293. package/dist/plugins/dashboard/server.mjs.map +1 -0
  294. package/dist/plugins/deepbook/deploy.mjs +53 -115
  295. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  296. package/dist/plugins/deepbook/errors.mjs +1 -0
  297. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  298. package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
  299. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  300. package/dist/plugins/deepbook/hash.mjs +9 -0
  301. package/dist/plugins/deepbook/hash.mjs.map +1 -0
  302. package/dist/plugins/deepbook/index.d.mts +1 -10
  303. package/dist/plugins/deepbook/index.mjs +25 -22
  304. package/dist/plugins/deepbook/index.mjs.map +1 -1
  305. package/dist/plugins/deepbook/pyth/index.mjs +26 -55
  306. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  307. package/dist/plugins/deepbook/snapshot.mjs +17 -29
  308. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  309. package/dist/plugins/deepbook/spans.mjs +18 -0
  310. package/dist/plugins/deepbook/spans.mjs.map +1 -0
  311. package/dist/plugins/deepbook/type-strings.mjs +65 -0
  312. package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
  313. package/dist/plugins/deepbook/types.d.mts +2 -3
  314. package/dist/plugins/deepbook/types.mjs.map +1 -1
  315. package/dist/plugins/faucet/dispatcher.d.mts +21 -2
  316. package/dist/plugins/faucet/dispatcher.mjs +1 -2
  317. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  318. package/dist/plugins/faucet/errors.d.mts +11 -24
  319. package/dist/plugins/faucet/errors.mjs.map +1 -1
  320. package/dist/plugins/faucet/http.mjs +33 -14
  321. package/dist/plugins/faucet/http.mjs.map +1 -1
  322. package/dist/plugins/faucet/index.d.mts +15 -5
  323. package/dist/plugins/faucet/index.mjs +3 -0
  324. package/dist/plugins/faucet/index.mjs.map +1 -1
  325. package/dist/plugins/faucet/spans.mjs +12 -0
  326. package/dist/plugins/faucet/spans.mjs.map +1 -0
  327. package/dist/plugins/host-service/errors.d.mts +1 -1
  328. package/dist/plugins/host-service/index.mjs +34 -8
  329. package/dist/plugins/host-service/index.mjs.map +1 -1
  330. package/dist/plugins/host-service/routable.mjs +2 -1
  331. package/dist/plugins/host-service/routable.mjs.map +1 -1
  332. package/dist/plugins/host-service/service.d.mts +21 -0
  333. package/dist/plugins/host-service/service.mjs +136 -81
  334. package/dist/plugins/host-service/service.mjs.map +1 -1
  335. package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
  336. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
  337. package/dist/plugins/internal/codegen-helpers.mjs +18 -0
  338. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
  339. package/dist/plugins/internal/funding-failure-error.mjs +32 -0
  340. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
  341. package/dist/plugins/package/build.mjs +1 -1
  342. package/dist/plugins/package/build.mjs.map +1 -1
  343. package/dist/plugins/package/codegen.mjs +26 -0
  344. package/dist/plugins/package/codegen.mjs.map +1 -1
  345. package/dist/plugins/package/errors.d.mts +16 -6
  346. package/dist/plugins/package/errors.mjs.map +1 -1
  347. package/dist/plugins/package/index.d.mts +0 -4
  348. package/dist/plugins/package/index.mjs +27 -21
  349. package/dist/plugins/package/index.mjs.map +1 -1
  350. package/dist/plugins/package/mode-known.mjs +26 -12
  351. package/dist/plugins/package/mode-known.mjs.map +1 -1
  352. package/dist/plugins/package/mode-local.mjs +47 -41
  353. package/dist/plugins/package/mode-local.mjs.map +1 -1
  354. package/dist/plugins/package/publish-executor.mjs +55 -114
  355. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  356. package/dist/plugins/package/registry.mjs +2 -1
  357. package/dist/plugins/package/registry.mjs.map +1 -1
  358. package/dist/plugins/package/service.mjs.map +1 -1
  359. package/dist/plugins/package/spans.mjs +14 -0
  360. package/dist/plugins/package/spans.mjs.map +1 -0
  361. package/dist/plugins/postgres/db-ensure.mjs +19 -12
  362. package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
  363. package/dist/plugins/postgres/errors.d.mts +5 -0
  364. package/dist/plugins/postgres/errors.mjs.map +1 -1
  365. package/dist/plugins/postgres/index.mjs +10 -17
  366. package/dist/plugins/postgres/index.mjs.map +1 -1
  367. package/dist/plugins/postgres/service.mjs +58 -24
  368. package/dist/plugins/postgres/service.mjs.map +1 -1
  369. package/dist/plugins/postgres/snapshot.mjs.map +1 -1
  370. package/dist/plugins/postgres/spans.mjs +11 -0
  371. package/dist/plugins/postgres/spans.mjs.map +1 -0
  372. package/dist/plugins/router-entrypoints.mjs +4 -4
  373. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  374. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
  375. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  376. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
  377. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  378. package/dist/plugins/seal/codegen.d.mts +2 -3
  379. package/dist/plugins/seal/codegen.mjs.map +1 -1
  380. package/dist/plugins/seal/config-render.mjs +35 -8
  381. package/dist/plugins/seal/config-render.mjs.map +1 -1
  382. package/dist/plugins/seal/deploy.mjs +31 -39
  383. package/dist/plugins/seal/deploy.mjs.map +1 -1
  384. package/dist/plugins/seal/errors.d.mts +1 -3
  385. package/dist/plugins/seal/errors.mjs +7 -1
  386. package/dist/plugins/seal/errors.mjs.map +1 -1
  387. package/dist/plugins/seal/index.d.mts +1 -6
  388. package/dist/plugins/seal/index.mjs +40 -14
  389. package/dist/plugins/seal/index.mjs.map +1 -1
  390. package/dist/plugins/seal/key-manager.d.mts +1 -9
  391. package/dist/plugins/seal/key-manager.mjs +2 -18
  392. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  393. package/dist/plugins/seal/key-server.mjs +37 -36
  394. package/dist/plugins/seal/key-server.mjs.map +1 -1
  395. package/dist/plugins/seal/keygen.mjs +16 -17
  396. package/dist/plugins/seal/keygen.mjs.map +1 -1
  397. package/dist/plugins/seal/mode/fork-known.mjs +36 -14
  398. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  399. package/dist/plugins/seal/mode/live.d.mts +6 -4
  400. package/dist/plugins/seal/mode/live.mjs +14 -21
  401. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  402. package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
  403. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  404. package/dist/plugins/seal/registry-publish.mjs +1 -0
  405. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  406. package/dist/plugins/seal/routable.mjs.map +1 -1
  407. package/dist/plugins/seal/service.mjs.map +1 -1
  408. package/dist/plugins/seal/spans.mjs +18 -0
  409. package/dist/plugins/seal/spans.mjs.map +1 -0
  410. package/dist/plugins/sui/auto-tick.mjs +17 -23
  411. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  412. package/dist/plugins/sui/chain-build-container.mjs +18 -0
  413. package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
  414. package/dist/plugins/sui/chain-probe.d.mts +5 -5
  415. package/dist/plugins/sui/chain-probe.mjs +28 -58
  416. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  417. package/dist/plugins/sui/codegen.mjs +26 -0
  418. package/dist/plugins/sui/codegen.mjs.map +1 -1
  419. package/dist/plugins/sui/errors.d.mts +2 -29
  420. package/dist/plugins/sui/errors.mjs +1 -3
  421. package/dist/plugins/sui/errors.mjs.map +1 -1
  422. package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
  423. package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
  424. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
  425. package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
  426. package/dist/plugins/sui/fork-orchestration.mjs +170 -2
  427. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  428. package/dist/plugins/sui/fork-transaction.d.mts +2 -0
  429. package/dist/plugins/sui/fork-transaction.mjs +92 -28
  430. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  431. package/dist/plugins/sui/index.d.mts +33 -70
  432. package/dist/plugins/sui/index.mjs +58 -35
  433. package/dist/plugins/sui/index.mjs.map +1 -1
  434. package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
  435. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
  436. package/dist/plugins/sui/mode/external.mjs +7 -13
  437. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  438. package/dist/plugins/sui/mode/fork.mjs +136 -59
  439. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  440. package/dist/plugins/sui/mode/live.mjs +10 -16
  441. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  442. package/dist/plugins/sui/mode/local.mjs +37 -36
  443. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  444. package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
  445. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  446. package/dist/plugins/sui/mode/shared.d.mts +1 -5
  447. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  448. package/dist/plugins/sui/mode/spec.d.mts +18 -0
  449. package/dist/plugins/sui/move-summary-runner.mjs +207 -0
  450. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
  451. package/dist/plugins/sui/network-resolver.d.mts +4 -3
  452. package/dist/plugins/sui/service.mjs.map +1 -1
  453. package/dist/plugins/sui/snapshot.mjs +3 -0
  454. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  455. package/dist/plugins/sui/spans.mjs +17 -0
  456. package/dist/plugins/sui/spans.mjs.map +1 -0
  457. package/dist/plugins/wallet/codegen.d.mts +0 -1
  458. package/dist/plugins/wallet/codegen.mjs +8 -9
  459. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  460. package/dist/plugins/wallet/index.d.mts +6 -8
  461. package/dist/plugins/wallet/index.mjs +46 -35
  462. package/dist/plugins/wallet/index.mjs.map +1 -1
  463. package/dist/plugins/wallet/origin-policy.mjs +12 -28
  464. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  465. package/dist/plugins/wallet/pairing.mjs +6 -4
  466. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  467. package/dist/plugins/wallet/protocol.d.mts +1 -0
  468. package/dist/plugins/wallet/protocol.mjs +5 -44
  469. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  470. package/dist/plugins/wallet/routable.mjs +2 -8
  471. package/dist/plugins/wallet/routable.mjs.map +1 -1
  472. package/dist/plugins/wallet/server.mjs +36 -44
  473. package/dist/plugins/wallet/server.mjs.map +1 -1
  474. package/dist/plugins/wallet/service.d.mts +1 -5
  475. package/dist/plugins/wallet/service.mjs +22 -18
  476. package/dist/plugins/wallet/service.mjs.map +1 -1
  477. package/dist/plugins/wallet/spans.mjs +22 -0
  478. package/dist/plugins/wallet/spans.mjs.map +1 -0
  479. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
  480. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  481. package/dist/plugins/walrus/codegen.d.mts +3 -3
  482. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  483. package/dist/plugins/walrus/deploy-paths.mjs +21 -5
  484. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  485. package/dist/plugins/walrus/deploy.mjs +67 -69
  486. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  487. package/dist/plugins/walrus/errors.mjs +1 -0
  488. package/dist/plugins/walrus/errors.mjs.map +1 -1
  489. package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
  490. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  491. package/dist/plugins/walrus/index.d.mts +2 -13
  492. package/dist/plugins/walrus/index.mjs +18 -23
  493. package/dist/plugins/walrus/index.mjs.map +1 -1
  494. package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
  495. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  496. package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
  497. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  498. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  499. package/dist/plugins/walrus/routable.mjs +7 -23
  500. package/dist/plugins/walrus/routable.mjs.map +1 -1
  501. package/dist/plugins/walrus/service.mjs.map +1 -1
  502. package/dist/plugins/walrus/spans.mjs +18 -0
  503. package/dist/plugins/walrus/spans.mjs.map +1 -0
  504. package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
  505. package/dist/plugins/walrus/storage-nodes.mjs +15 -8
  506. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  507. package/dist/plugins/walrus/wal-swap.mjs +58 -15
  508. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  509. package/dist/primitives/artifact-publisher.d.mts +1 -1
  510. package/dist/primitives/artifact-publisher.mjs +15 -0
  511. package/dist/primitives/artifact-publisher.mjs.map +1 -0
  512. package/dist/runtime/docker/client.mjs +17 -4
  513. package/dist/runtime/docker/client.mjs.map +1 -1
  514. package/dist/runtime/docker/container.mjs +219 -132
  515. package/dist/runtime/docker/container.mjs.map +1 -1
  516. package/dist/runtime/docker/errors.mjs +0 -6
  517. package/dist/runtime/docker/errors.mjs.map +1 -1
  518. package/dist/runtime/docker/exec.mjs +21 -18
  519. package/dist/runtime/docker/exec.mjs.map +1 -1
  520. package/dist/runtime/docker/image.mjs +36 -13
  521. package/dist/runtime/docker/image.mjs.map +1 -1
  522. package/dist/runtime/docker/index.mjs +14 -0
  523. package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
  524. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
  525. package/dist/runtime/docker/inventory.mjs +14 -11
  526. package/dist/runtime/docker/inventory.mjs.map +1 -1
  527. package/dist/runtime/docker/labels.mjs +38 -5
  528. package/dist/runtime/docker/labels.mjs.map +1 -1
  529. package/dist/runtime/docker/logs.d.mts +1 -1
  530. package/dist/runtime/docker/logs.mjs.map +1 -1
  531. package/dist/runtime/docker/network.mjs +83 -47
  532. package/dist/runtime/docker/network.mjs.map +1 -1
  533. package/dist/runtime/docker/render-run-args.mjs +82 -0
  534. package/dist/runtime/docker/render-run-args.mjs.map +1 -0
  535. package/dist/runtime/docker/service.d.mts +1 -1
  536. package/dist/runtime/docker/service.mjs +12 -7
  537. package/dist/runtime/docker/service.mjs.map +1 -1
  538. package/dist/runtime/docker/sweep.mjs +118 -43
  539. package/dist/runtime/docker/sweep.mjs.map +1 -1
  540. package/dist/runtime/docker/volume.mjs +2 -0
  541. package/dist/runtime/docker/volume.mjs.map +1 -1
  542. package/dist/runtime/docker/wrap.mjs +30 -1
  543. package/dist/runtime/docker/wrap.mjs.map +1 -1
  544. package/dist/substrate/cross-process.mjs +14 -8
  545. package/dist/substrate/cross-process.mjs.map +1 -1
  546. package/dist/substrate/event-time.mjs +33 -0
  547. package/dist/substrate/event-time.mjs.map +1 -0
  548. package/dist/substrate/events.d.mts +28 -8
  549. package/dist/substrate/identity.d.mts +2 -1
  550. package/dist/substrate/manifest.d.mts +68 -5
  551. package/dist/substrate/manifest.mjs +34 -5
  552. package/dist/substrate/manifest.mjs.map +1 -1
  553. package/dist/substrate/network.d.mts +3 -5
  554. package/dist/substrate/options.d.mts +0 -2
  555. package/dist/substrate/plugin.d.mts +13 -0
  556. package/dist/substrate/plugin.mjs +4 -2
  557. package/dist/substrate/plugin.mjs.map +1 -1
  558. package/dist/substrate/projection.d.mts +35 -3
  559. package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
  560. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
  561. package/dist/substrate/runtime/atomic-write.mjs +97 -32
  562. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  563. package/dist/substrate/runtime/cache/index.mjs +3 -0
  564. package/dist/substrate/runtime/cache/schema.mjs +2 -2
  565. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  566. package/dist/substrate/runtime/cache/service.mjs +9 -7
  567. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  568. package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
  569. package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
  570. package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
  571. package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
  572. package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
  573. package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
  574. package/dist/substrate/runtime/config-validation.d.mts +1 -13
  575. package/dist/substrate/runtime/config-validation.mjs +2 -91
  576. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  577. package/dist/substrate/runtime/container-runtime.d.mts +1 -0
  578. package/dist/substrate/runtime/container-runtime.mjs +2 -0
  579. package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
  580. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
  581. package/dist/substrate/runtime/control-plane/service.mjs +7 -0
  582. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
  583. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
  584. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  585. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
  586. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  587. package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
  588. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
  589. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  590. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
  591. package/dist/substrate/runtime/cross-process/index.mjs +11 -0
  592. package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
  593. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
  594. package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
  595. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  596. package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
  597. package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
  598. package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
  599. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
  600. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
  601. package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
  602. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  603. package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
  604. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
  605. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
  606. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
  607. package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
  608. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  609. package/dist/substrate/runtime/current-plugin.mjs +2 -2
  610. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  611. package/dist/substrate/runtime/errors.mjs +12 -6
  612. package/dist/substrate/runtime/errors.mjs.map +1 -1
  613. package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
  614. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
  615. package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
  616. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
  617. package/dist/substrate/runtime/host-gateway.mjs +20 -0
  618. package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
  619. package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
  620. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  621. package/dist/substrate/runtime/http-probe.d.mts +1 -1
  622. package/dist/substrate/runtime/index.mjs +14 -0
  623. package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
  624. package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
  625. package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
  626. package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
  627. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  628. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
  629. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  630. package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
  631. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
  632. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
  633. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  634. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
  635. package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
  636. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  637. package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
  638. package/dist/substrate/runtime/managed-container.d.mts +19 -1
  639. package/dist/substrate/runtime/managed-container.mjs +20 -1
  640. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  641. package/dist/substrate/runtime/manifest/index.mjs +3 -0
  642. package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
  643. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  644. package/dist/substrate/runtime/mode-errors.mjs +20 -0
  645. package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
  646. package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
  647. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  648. package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
  649. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
  650. package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
  651. package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
  652. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
  653. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  654. package/dist/substrate/runtime/observability/index.mjs +13 -0
  655. package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
  656. package/dist/substrate/runtime/observability/log-store.mjs +175 -0
  657. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
  658. package/dist/substrate/runtime/observability/logger.d.mts +2 -1
  659. package/dist/substrate/runtime/observability/logger.mjs +5 -9
  660. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  661. package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
  662. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
  663. package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
  664. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  665. package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
  666. package/dist/substrate/runtime/observability/redaction.mjs +8 -14
  667. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  668. package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
  669. package/dist/substrate/runtime/observability/span-store.mjs +110 -0
  670. package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
  671. package/dist/substrate/runtime/observability/spans.mjs +14 -14
  672. package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
  673. package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
  674. package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
  675. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
  676. package/dist/substrate/runtime/paths.d.mts +1 -1
  677. package/dist/substrate/runtime/paths.mjs +4 -3
  678. package/dist/substrate/runtime/paths.mjs.map +1 -1
  679. package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
  680. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
  681. package/dist/substrate/runtime/port-broker/index.mjs +3 -0
  682. package/dist/substrate/runtime/port-broker/service.mjs +170 -126
  683. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  684. package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
  685. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  686. package/dist/substrate/runtime/probes.d.mts +7 -5
  687. package/dist/substrate/runtime/probes.mjs +3 -1
  688. package/dist/substrate/runtime/probes.mjs.map +1 -1
  689. package/dist/substrate/runtime/projection/index.mjs +4 -0
  690. package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
  691. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  692. package/dist/substrate/runtime/projection/persisted.mjs +33 -15
  693. package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
  694. package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
  695. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  696. package/dist/substrate/runtime/projection/update.mjs +88 -24
  697. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  698. package/dist/substrate/runtime/random-suffix.mjs +11 -0
  699. package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
  700. package/dist/substrate/runtime/retry-policy.d.mts +59 -1
  701. package/dist/substrate/runtime/retry-policy.mjs +66 -1
  702. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  703. package/dist/substrate/runtime/routed-url.d.mts +1 -0
  704. package/dist/substrate/runtime/routed-url.mjs +79 -0
  705. package/dist/substrate/runtime/routed-url.mjs.map +1 -0
  706. package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
  707. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  708. package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
  709. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  710. package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
  711. package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
  712. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
  713. package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
  714. package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
  715. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
  716. package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
  717. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  718. package/dist/substrate/runtime/state-store/index.d.mts +1 -0
  719. package/dist/substrate/runtime/state-store/index.mjs +3 -0
  720. package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
  721. package/dist/substrate/runtime/state-store/schema.mjs +19 -14
  722. package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
  723. package/dist/substrate/runtime/state-store/service.d.mts +1 -0
  724. package/dist/substrate/runtime/state-store/service.mjs +145 -0
  725. package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
  726. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
  727. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
  728. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
  729. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
  730. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  731. package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
  732. package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
  733. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  734. package/dist/substrate/runtime/subnet-broker.mjs +60 -0
  735. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
  736. package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
  737. package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
  738. package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
  739. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
  740. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
  741. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
  742. package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
  743. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
  744. package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
  745. package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
  746. package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
  747. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
  748. package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
  749. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
  750. package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
  751. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
  752. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
  753. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
  754. package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
  755. package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
  756. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
  757. package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
  758. package/dist/substrate/runtime/supervisor/index.mjs +3 -0
  759. package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
  760. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
  761. package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
  762. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
  763. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
  764. package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
  765. package/dist/substrate/runtime/supervisor/state.mjs +22 -0
  766. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
  767. package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
  768. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
  769. package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
  770. package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
  771. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
  772. package/dist/substrate/runtime/typed-env.mjs +8 -0
  773. package/dist/substrate/runtime/typed-env.mjs.map +1 -0
  774. package/dist/substrate/state-store.d.mts +1 -0
  775. package/dist/substrate/versioned-doc-schema.mjs +17 -0
  776. package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
  777. package/dist/substrate/versioned-doc-sync.mjs +94 -0
  778. package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
  779. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  780. package/dist/surfaces/cli/commands/index.mjs +9 -0
  781. package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
  782. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
  783. package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
  784. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  785. package/dist/surfaces/cli/commands/prune.mjs +34 -17
  786. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  787. package/dist/surfaces/cli/commands/status.mjs +2 -2
  788. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  789. package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
  790. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  791. package/dist/surfaces/cli/commands/wipe.mjs +38 -4
  792. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  793. package/dist/surfaces/cli/errors.mjs +1 -1
  794. package/dist/surfaces/cli/errors.mjs.map +1 -1
  795. package/dist/surfaces/cli/flags.mjs +0 -1
  796. package/dist/surfaces/cli/flags.mjs.map +1 -1
  797. package/dist/surfaces/cli/index.mjs +98 -18
  798. package/dist/surfaces/cli/index.mjs.map +1 -1
  799. package/dist/surfaces/cli/output.mjs +1 -0
  800. package/dist/surfaces/cli/output.mjs.map +1 -1
  801. package/dist/surfaces/cli/sysexits.mjs +2 -1
  802. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  803. package/dist/surfaces/tui/app.mjs +25 -3
  804. package/dist/surfaces/tui/app.mjs.map +1 -1
  805. package/dist/surfaces/tui/display-derivation.mjs +23 -74
  806. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  807. package/dist/surfaces/tui/event-log.mjs +35 -23
  808. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  809. package/dist/surfaces/tui/input.mjs +5 -1
  810. package/dist/surfaces/tui/input.mjs.map +1 -1
  811. package/dist/surfaces/tui/plain-renderer.mjs +70 -34
  812. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  813. package/package.json +24 -4
  814. package/dist/contracts/liveness-classifier.d.mts +0 -19
  815. package/dist/contracts/network-resolver.d.mts +0 -15
  816. package/dist/contracts/network-resolver.mjs +0 -7
  817. package/dist/contracts/network-resolver.mjs.map +0 -1
  818. package/dist/orchestrators/codegen/extras.mjs +0 -16
  819. package/dist/orchestrators/codegen/extras.mjs.map +0 -1
  820. package/dist/plugins/deepbook/routable.mjs +0 -21
  821. package/dist/plugins/deepbook/routable.mjs.map +0 -1
  822. package/dist/plugins/faucet/service.d.mts +0 -20
  823. package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
  824. package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
  825. package/dist/plugins/sui/seed-objects.d.mts +0 -18
  826. package/dist/plugins/sui/seed-objects.mjs +0 -25
  827. package/dist/plugins/sui/seed-objects.mjs.map +0 -1
  828. package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
  829. package/dist/substrate/runtime/context-helpers.mjs +0 -32
  830. package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
  831. package/dist/substrate/runtime/run.mjs.map +0 -1
  832. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
  833. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
  834. package/dist/substrate/runtime/supervisor.d.mts +0 -1
  835. package/dist/substrate/runtime/supervisor.mjs +0 -831
  836. package/dist/substrate/runtime/supervisor.mjs.map +0 -1
  837. package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
  838. /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"global-setup.mjs","names":[],"sources":["../../../src/build-integrations/playwright/global-setup.ts"],"sourcesContent":["// Playwright `globalSetup` hook.\n//\n// Architecture (distilled/23-build-integrations.md § Playwright):\n//\n// What it needs: the same manifest as Vite (...) but with a\n// cold-start fallback (...) — Playwright config-load runs BEFORE\n// the supervisor spawns to write the manifest.\n//\n// How it hooks in: the spawned `pnpm dev` (default `command`) brings\n// up the supervisor, which writes the real manifest. Playwright\n// polls `webServer.url` until reachable.\n//\n// This module is the third hook in that chain (config-load → webServer\n// spawn → globalSetup). By the time it runs, the supervisor IS up and\n// the manifest has been written; globalSetup verifies invariants and\n// populates fixtures the in-spec tests rely on (e.g. preloads the\n// stack context so each test doesn't repeat the disk read; warms the\n// wallet adapter; resolves the test-account list).\n//\n// What it does NOT do:\n// - Boot the supervisor. (`webServer.command` does that.)\n// - Wait on `webServer.url`. (Playwright does that.)\n// - Write any state. (Read-only.)\n//\n// Returns a teardown function (the inverse hook Playwright supports\n// via `globalTeardown` indirection — we return the teardown so the\n// preset's `globalTeardown` can call it).\n\nimport {\n\treadStackContext,\n\ttype ResolveStackContextOptions,\n\ttype StackContext,\n} from './stack-context.ts';\n\n// -----------------------------------------------------------------------------\n// Public shape Playwright expects\n// -----------------------------------------------------------------------------\n\n/** Playwright's `globalSetup` signature is `() => Promise<void | (() =>\n * Promise<void>)>` — we model it explicitly so the preset compiles\n * without `@playwright/test`. */\nexport type PlaywrightGlobalSetup = () => Promise<void | (() => Promise<void>)>;\n\n// -----------------------------------------------------------------------------\n// Fixture payload\n// -----------------------------------------------------------------------------\n\n/**\n * The shape global-setup writes to disk for in-spec tests to read.\n * Tests do NOT re-walk-up to find the manifest at every assertion —\n * they read this prepared fixture, which is faster and avoids a\n * subtle cwd-mismatch class of failure when Playwright runs tests\n * from a worker process.\n *\n * The fixture is written to a Playwright-known path (resolved from\n * env Playwright populates) so worker processes pick it up. The\n * setup also stamps `DEVSTACK_MANIFEST_PATH` into the worker env so\n * `wallet-context` can reach the file without re-running discovery.\n */\nexport interface PlaywrightStackFixture {\n\treadonly endpoints: Readonly<Record<string, string>>;\n\treadonly walletEndpoint: string | null;\n\treadonly manifestPath: string;\n\treadonly stack: string;\n\treadonly app: string;\n}\n\n// -----------------------------------------------------------------------------\n// Configurable factory\n// -----------------------------------------------------------------------------\n\nexport interface DefineGlobalSetupOptions extends ResolveStackContextOptions {\n\t/**\n\t * Verify the manifest's `endpoints` has at least one entry. The\n\t * supervisor's manifest writer always emits at least the `app`\n\t * endpoint, so an empty `endpoints` lookup means the supervisor\n\t * crashed before reaching its eager snapshot-and-write — fail\n\t * fast here rather than letting tests time out.\n\t */\n\treadonly requireNonEmptyEndpoints?: boolean;\n\n\t/**\n\t * Verify the named endpoints exist in the manifest. Used to fail\n\t * fast when a test suite depends on a specific plugin (wallet,\n\t * sui-faucet) being present in the resolved stack.\n\t */\n\treadonly requireEndpoints?: ReadonlyArray<string>;\n\n\t/**\n\t * Pre-warm the stack context — read the manifest once and stash\n\t * the result on `globalThis` so tests don't repeat the disk read.\n\t * Default: `true`.\n\t */\n\treadonly preloadContext?: boolean;\n}\n\n/**\n * Build a Playwright `globalSetup` function. The returned function\n * matches the signature Playwright expects (a default export of a\n * module path; we return the function so the preset can wire it).\n */\nexport const buildGlobalSetup = (options: DefineGlobalSetupOptions = {}): PlaywrightGlobalSetup => {\n\treturn async () => {\n\t\tconst ctx = readStackContext(options);\n\n\t\tif (options.requireNonEmptyEndpoints === true) {\n\t\t\tif (ctx.endpointNames.length === 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`devstack manifest at ${ctx.manifestPath} has no endpoints. ` +\n\t\t\t\t\t\t`The supervisor likely failed before its eager snapshot ` +\n\t\t\t\t\t\t`write; check the dev server logs for plugin acquire errors.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst required = options.requireEndpoints ?? [];\n\t\tconst missing: string[] = [];\n\t\tfor (const key of required) {\n\t\t\tif (ctx.endpointMaybe(key) === null) missing.push(key);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`devstack manifest at ${ctx.manifestPath} is missing required ` +\n\t\t\t\t\t`endpoints: ${missing.join(', ')}. ` +\n\t\t\t\t\t`available endpoint names: ${ctx.endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t\t`raw manifest keys: ${ctx.manifestEndpointKeys.join(', ') || '(none)'}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (options.preloadContext ?? true) {\n\t\t\tstashStackContext(ctx);\n\t\t}\n\n\t\t// Return value: `void` (no teardown). Playwright accepts\n\t\t// `() => Promise<void>` here.\n\t};\n};\n\n/** Default export shape that mirrors what Playwright's\n * `defineConfig.globalSetup` resolves: a module whose default export\n * is the setup function. */\nexport default buildGlobalSetup();\n\n// -----------------------------------------------------------------------------\n// Global stash\n// -----------------------------------------------------------------------------\n\n/** The slot on `globalThis` where the prewarmed stack context lives.\n * In-spec helpers (`wallet-context.ts`) read from here when present\n * to avoid a second disk read. */\nexport const STACK_CONTEXT_SLOT = '__devstackPlaywrightStackContext__' as const;\n\ninterface GlobalSlot {\n\t[STACK_CONTEXT_SLOT]?: PlaywrightStackFixture;\n}\n\nconst stashStackContext = (ctx: StackContext): void => {\n\tconst fixture: PlaywrightStackFixture = {\n\t\tendpoints: Object.fromEntries(ctx.endpointNames.map((name) => [name, ctx.endpoint(name)])),\n\t\twalletEndpoint: ctx.endpointMaybe('wallet'),\n\t\tmanifestPath: ctx.manifestPath,\n\t\tstack: ctx.manifest.identity.stack,\n\t\tapp: ctx.manifest.identity.app,\n\t};\n\t(globalThis as unknown as GlobalSlot)[STACK_CONTEXT_SLOT] = fixture;\n};\n\n/** Read the slot. Returns `null` if global-setup didn't run (e.g. the\n * user opted out by passing `globalSetup: null`). */\nexport const readStashedFixture = (): PlaywrightStackFixture | null => {\n\tconst slot = (globalThis as unknown as GlobalSlot)[STACK_CONTEXT_SLOT];\n\treturn slot ?? null;\n};\n"],"mappings":";;;;;;;AAqGA,MAAa,oBAAoB,UAAoC,EAAE,KAA4B;AAClG,QAAO,YAAY;EAClB,MAAM,MAAM,iBAAiB,QAAQ;AAErC,MAAI,QAAQ,6BAA6B;OACpC,IAAI,cAAc,WAAW,EAChC,OAAM,IAAI,MACT,wBAAwB,IAAI,aAAa,uIAGzC;;EAIH,MAAM,WAAW,QAAQ,oBAAoB,EAAE;EAC/C,MAAM,UAAoB,EAAE;AAC5B,OAAK,MAAM,OAAO,SACjB,KAAI,IAAI,cAAc,IAAI,KAAK,KAAM,SAAQ,KAAK,IAAI;AAEvD,MAAI,QAAQ,SAAS,EACpB,OAAM,IAAI,MACT,wBAAwB,IAAI,aAAa,kCAC1B,QAAQ,KAAK,KAAK,CAAC,8BACJ,IAAI,cAAc,KAAK,KAAK,IAAI,SAAS,uBAChD,IAAI,qBAAqB,KAAK,KAAK,IAAI,SAAS,GACvE;AAGF,MAAI,QAAQ,kBAAkB,KAC7B,mBAAkB,IAAI;;;AAWV,kBAAkB;;;;AASjC,MAAa,qBAAqB;AAMlC,MAAM,qBAAqB,QAA4B;CACtD,MAAM,UAAkC;EACvC,WAAW,OAAO,YAAY,IAAI,cAAc,KAAK,SAAS,CAAC,MAAM,IAAI,SAAS,KAAK,CAAC,CAAC,CAAC;EAC1F,gBAAgB,IAAI,cAAc,SAAS;EAC3C,cAAc,IAAI;EAClB,OAAO,IAAI,SAAS,SAAS;EAC7B,KAAK,IAAI,SAAS,SAAS;EAC3B;AACA,YAAqC,sBAAsB;;;;AAK7D,MAAa,2BAA0D;AAEtE,QADc,WAAA,yCACC"}
1
+ {"version":3,"file":"global-setup.mjs","names":[],"sources":["../../../src/build-integrations/playwright/global-setup.ts"],"sourcesContent":["// Playwright `globalSetup` hook.\n//\n// Architecture (distilled/23-build-integrations.md § Playwright):\n//\n// What it needs: the same manifest as Vite (...) but with a\n// cold-start fallback (...) — Playwright config-load runs BEFORE\n// the supervisor spawns to write the manifest.\n//\n// How it hooks in: the spawned `pnpm dev` (default `command`) brings\n// up the supervisor, which writes the real manifest. Playwright\n// polls `webServer.url` until reachable.\n//\n// This module is the third hook in that chain (config-load → webServer\n// spawn → globalSetup). The public route can become reachable before\n// post-acquire codegen has finished, so globalSetup waits for the\n// supervisor's `codegen.emitted` event before specs load the app. That\n// keeps apps from importing stale generated package IDs.\n//\n// What it does NOT do:\n// - Boot the supervisor. (`webServer.command` does that.)\n// - Wait on `webServer.url`. (Playwright does that.)\n// - Write any state. (Read-only.)\n//\n// Returns a teardown function (the inverse hook Playwright supports\n// via `globalTeardown` indirection — we return the teardown so the\n// preset's `globalTeardown` can call it).\n\nimport { closeSync, openSync, readSync, statSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\n\nimport { Schema } from 'effect';\n\nimport { BUILT_IN_ENDPOINT_ALIASES } from '../runtime/conventional-routes.ts';\nimport { discoverSingleStackManifestPath } from '../runtime/discover.ts';\nimport { resolveDiscoveryEnv } from '../runtime/resolve-discovery-env.ts';\nimport { WALLET_ENDPOINT_KEY } from '../runtime/wallet-paths.ts';\nimport {\n\tPLAYWRIGHT_STACK_CONTEXT_SLOT_KEY,\n\ttype PlaywrightStackFixture as RuntimePlaywrightStackFixture,\n} from '../runtime/playwright-stack-context-slot.ts';\nimport {\n\tPLAYWRIGHT_ENV,\n\treadStackContext,\n\ttype ResolveStackContextOptions,\n\ttype StackContext,\n} from './stack-context.ts';\nimport { PlaywrightManifestDiscoveryError } from './errors.ts';\n\n// -----------------------------------------------------------------------------\n// Public shape Playwright expects\n// -----------------------------------------------------------------------------\n\n/** Playwright's `globalSetup` signature is `() => Promise<void | (() =>\n * Promise<void>)>` — we model it explicitly so the preset compiles\n * without `@playwright/test`. */\nexport type PlaywrightGlobalSetup = () => Promise<void | (() => Promise<void>)>;\n\n// -----------------------------------------------------------------------------\n// Fixture payload\n// -----------------------------------------------------------------------------\n\n/**\n * The shape global-setup writes for in-spec tests to read. Tests do\n * NOT re-walk-up to find the manifest at every assertion — they read\n * this prepared fixture from `globalThis`, which is faster and avoids\n * a subtle cwd-mismatch class of failure when Playwright runs tests\n * from a worker process.\n *\n * Re-export of the substrate-owned `runtime/playwright-stack-context-slot`\n * shape so both consumer surfaces agree on one type. The matching\n * typed `declare global` block lives next to the slot key so callers\n * can read/write `globalThis[KEY]` without a cast.\n */\nexport type PlaywrightStackFixture = RuntimePlaywrightStackFixture;\n\n// -----------------------------------------------------------------------------\n// Configurable factory\n// -----------------------------------------------------------------------------\n\nexport interface DefineGlobalSetupOptions extends ResolveStackContextOptions {\n\t/**\n\t * Wait for the supervisor's post-acquire codegen event before the\n\t * browser loads the app. Default: `true`.\n\t */\n\treadonly waitForCodegen?: boolean;\n\n\t/** Maximum wait for the manifest + codegen-ready event. */\n\treadonly readyTimeoutMs?: number;\n\n\t/** Poll interval while waiting for the manifest + codegen-ready event. */\n\treadonly readyPollIntervalMs?: number;\n\n\t/**\n\t * Verify the manifest's `endpoints` has at least one entry. The\n\t * supervisor's manifest writer always emits at least the `app`\n\t * endpoint, so an empty `endpoints` lookup means the supervisor\n\t * crashed before reaching its eager snapshot-and-write — fail\n\t * fast here rather than letting tests time out.\n\t */\n\treadonly requireNonEmptyEndpoints?: boolean;\n\n\t/**\n\t * Verify the named endpoints exist in the manifest. Used to fail\n\t * fast when a test suite depends on a specific plugin (wallet,\n\t * sui-faucet) being present in the resolved stack.\n\t */\n\treadonly requireEndpoints?: ReadonlyArray<string>;\n\n\t/**\n\t * Pre-warm the stack context — read the manifest once and stash\n\t * the result on `globalThis` so tests don't repeat the disk read.\n\t * Default: `true`.\n\t */\n\treadonly preloadContext?: boolean;\n}\n\nconst DEFAULT_READY_TIMEOUT_MS = 300_000;\nconst DEFAULT_READY_POLL_INTERVAL_MS = 100;\n\nconst sleep = (ms: number): Promise<void> =>\n\tnew Promise((resolveSleep) => setTimeout(resolveSleep, ms));\n\nconst stackOptionWasExplicit = (options: DefineGlobalSetupOptions): boolean => {\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\treturn (\n\t\toptions.stack !== undefined ||\n\t\toptions.manifestPath !== undefined ||\n\t\tenv[PLAYWRIGHT_ENV.STACK] !== undefined ||\n\t\tenv[PLAYWRIGHT_ENV.MANIFEST_PATH] !== undefined\n\t);\n};\n\nconst findSingleStackManifestPath = (options: DefineGlobalSetupOptions): string | null => {\n\tif (stackOptionWasExplicit(options)) return null;\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\t// Shared ladder (option > DEVSTACK_RUNTIME_ROOT > DEVSTACK_STATE_DIR\n\t// > '.devstack'). Previously read only DEVSTACK_STATE_DIR, dropping\n\t// DEVSTACK_RUNTIME_ROOT — aligned via `resolveDiscoveryEnv`. The\n\t// single-stack walk only needs the state-dir rung; stack is ignored.\n\tconst { stateDir } = resolveDiscoveryEnv(env, {\n\t\t...(options.stateDir !== undefined ? { stateDir: options.stateDir } : {}),\n\t});\n\treturn discoverSingleStackManifestPath({\n\t\t...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n\t\tstateDir,\n\t});\n};\n\nconst readContextForSetup = (options: DefineGlobalSetupOptions): StackContext => {\n\ttry {\n\t\treturn readStackContext(options);\n\t} catch (cause) {\n\t\tif (!(cause instanceof PlaywrightManifestDiscoveryError)) throw cause;\n\t\tconst inferredManifestPath = findSingleStackManifestPath(options);\n\t\tif (inferredManifestPath === null) throw cause;\n\t\treturn readStackContext({ ...options, manifestPath: inferredManifestPath });\n\t}\n};\n\n/**\n * Per-poll state for tail-following `events.ndjson`. We keep an open\n * file descriptor across polls and `readSync` only the bytes appended\n * since the previous tick. Re-opening every 100ms (the default poll\n * cadence) burned ~3000 syscalls per 5min wait; the open-once tail\n * collapses that to one open + one close at the bracket. Two cross-poll\n * counters track the latest `endpoint.registered name=app` and\n * `codegen.emitted` line numbers — codegen is fresh only when its\n * latest sighting is AFTER the latest app-endpoint registration (a\n * restart re-registers the endpoint, invalidating an earlier codegen).\n *\n * Lifecycle: `openCodegenWatch` allocates the fd; `advanceCodegenWatch`\n * reads forward; `closeCodegenWatch` releases. The caller MUST close\n * (the `waitForReadyStackContext` finally-block does this even on\n * timeout / exception paths).\n */\ninterface CodegenWatchState {\n\tfd: number | null;\n\toffset: number;\n\tlineIndex: number;\n\tcarry: string;\n\tlatestAppEndpointLine: number;\n\tlatestCodegenLine: number;\n\tlastFileSize: number;\n\tdecodeFailures: number;\n}\n\nconst createCodegenWatchState = (): CodegenWatchState => ({\n\tfd: null,\n\toffset: 0,\n\tlineIndex: 0,\n\tcarry: '',\n\tlatestAppEndpointLine: -1,\n\tlatestCodegenLine: -1,\n\tlastFileSize: 0,\n\tdecodeFailures: 0,\n});\n\nconst READ_CHUNK_BYTES = 64 * 1024;\n\n/**\n * Pinned-shape schema for the ndjson records we tail. The supervisor\n * emits a richer envelope (`protocol`/`seq`/`at` plus the full\n * `EngineEvent` union payload — see\n * `substrate/runtime/cross-process/command-channel/protocol.ts`\n * `EventRecordSchema`), but the watch only needs the discriminators\n * that route a record to `latestAppEndpointLine` / `latestCodegenLine`.\n *\n * The pin's job is to FAIL LOUDLY if one of those discriminators is\n * renamed upstream — a silent miss leaves the matchers permanently\n * unfired and deadlocks global-setup at the 5min `readyTimeout`. An\n * earlier version declared every field as `optional(Unknown)`, which\n * defeats that entirely: a `kind`→`recordKind` rename decoded to\n * `undefined` instead of throwing, so the watch silently stalled. We\n * therefore pin the stable discriminators as REQUIRED while keeping the\n * genuinely-variable axis (the engine `tag` value) permissive:\n *\n * - The engine variant requires `kind: 'engine'` (the literal value\n * the matchers test against, verified at `channel.ts` `publishEvent`)\n * and a required `event.tag` STRING. Renaming `kind`, its `'engine'`\n * value, the `event` key, or the `tag` key all fail decode — these\n * are the deadlock-class discriminators. The `tag` VALUE stays open,\n * so future `EngineEvent` tag additions need no change here.\n * - `event.endpoint` is optional (most engine tags carry no endpoint),\n * but WHERE present its `name` is REQUIRED. Renaming `name` on an\n * `endpoint.registered` record therefore fails decode rather than\n * silently leaving `latestAppEndpointLine` unset.\n * - `ack` / `error` envelopes carry no `event`; a dedicated variant\n * absorbs them so the supervisor's correlation replies don't flood\n * `decodeFailures`. They are never routed.\n *\n * Deliberately NOT permissive about an unknown `kind`: a brand-new\n * envelope kind fails decode. That is a rare, intentional protocol\n * change (and would be made alongside updating consumers), and failing\n * loudly here is the same drift signal the engine-value pin provides.\n */\nconst WatchedEngineRecordSchema = Schema.Struct({\n\tkind: Schema.Literal('engine'),\n\tevent: Schema.Struct({\n\t\ttag: Schema.String,\n\t\tendpoint: Schema.optional(\n\t\t\tSchema.Struct({\n\t\t\t\tname: Schema.String,\n\t\t\t}),\n\t\t),\n\t}),\n});\n\nconst WatchedReplyRecordSchema = Schema.Struct({\n\tkind: Schema.Literals(['ack', 'error']),\n});\n\nconst WatchedRecordSchema = Schema.Union([WatchedEngineRecordSchema, WatchedReplyRecordSchema]);\n\ntype WatchedRecord = Schema.Schema.Type<typeof WatchedRecordSchema>;\ntype WatchedEngineRecord = Schema.Schema.Type<typeof WatchedEngineRecordSchema>;\n\n/**\n * @internal Exported only so the through-surface test can assert the\n * drift-detection contract directly (a renamed discriminator must\n * THROW, not decode to `undefined`). Not part of the public API.\n */\nexport const decodeWatchedRecord = Schema.decodeUnknownSync(WatchedRecordSchema);\n\nconst isEngineRecord = (record: WatchedRecord): record is WatchedEngineRecord =>\n\trecord.kind === 'engine';\n\nconst isAppEndpointRegistration = (record: WatchedRecord): boolean =>\n\tisEngineRecord(record) &&\n\trecord.event.tag === 'endpoint.registered' &&\n\trecord.event.endpoint?.name === BUILT_IN_ENDPOINT_ALIASES.app;\n\nconst isCodegenEmitted = (record: WatchedRecord): boolean =>\n\tisEngineRecord(record) && record.event.tag === 'codegen.emitted';\n\nconst DEBUG_ENABLED = (): boolean => process.env.DEVSTACK_PLAYWRIGHT_DEBUG === '1';\n\nconst debugLog = (message: string): void => {\n\tif (!DEBUG_ENABLED()) return;\n\ttry {\n\t\tprocess.stderr.write(`[devstack/playwright] ${message}\\n`);\n\t} catch {\n\t\t// stderr EPIPE — swallow; the debug channel is best-effort.\n\t}\n};\n\nconst ingestNdjsonLine = (state: CodegenWatchState, line: string): void => {\n\tif (line.length === 0) return;\n\tstate.lineIndex += 1;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(line);\n\t} catch {\n\t\t// Partial / corrupt line — atomic-append from the supervisor can\n\t\t// land a half-flushed write between polls. Bump the counter so\n\t\t// repeated failures surface in debug mode (a steady stream means\n\t\t// the writer is malformed, not just race-y).\n\t\tstate.decodeFailures += 1;\n\t\tif (state.decodeFailures <= 3 || state.decodeFailures % 50 === 0) {\n\t\t\tdebugLog(\n\t\t\t\t`events.ndjson line ${state.lineIndex} failed JSON.parse (decodeFailures=${state.decodeFailures})`,\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tlet record: WatchedRecord;\n\ttry {\n\t\trecord = decodeWatchedRecord(parsed);\n\t} catch (cause) {\n\t\t// Schema drift: the supervisor emitted a record that doesn't\n\t\t// fit the discriminator shape we pin against. Log so a future\n\t\t// engine refactor that renames `kind` / `event.tag` /\n\t\t// `event.endpoint.name` surfaces immediately instead of\n\t\t// silently stalling the codegen wait at the readyTimeout.\n\t\tstate.decodeFailures += 1;\n\t\tif (state.decodeFailures <= 3 || state.decodeFailures % 50 === 0) {\n\t\t\tdebugLog(\n\t\t\t\t`events.ndjson line ${state.lineIndex} failed Schema.decode (decodeFailures=${state.decodeFailures}): ${\n\t\t\t\t\tcause instanceof Error ? cause.message : String(cause)\n\t\t\t\t}`,\n\t\t\t);\n\t\t}\n\t\treturn;\n\t}\n\tif (isAppEndpointRegistration(record)) {\n\t\tstate.latestAppEndpointLine = state.lineIndex;\n\t}\n\tif (isCodegenEmitted(record)) {\n\t\tstate.latestCodegenLine = state.lineIndex;\n\t}\n};\n\n/**\n * Advance the watch state by reading any bytes appended since the\n * previous poll. The fd is allocated lazily on the first poll (so a\n * file that doesn't yet exist isn't a hard error) and stays open across\n * polls until `closeCodegenWatch`. Returns `true` when the file has a\n * codegen-fresh state ready for caller continuation.\n *\n * Truncation/rotation: when `statSync(...).size < state.lastFileSize`\n * the file rotated. We close the old fd, reopen, and restart the\n * counters so the new tail's events aren't shadowed by stale\n * cross-poll state.\n */\nconst advanceCodegenWatch = (state: CodegenWatchState, eventsPath: string): boolean => {\n\tif (state.fd === null) {\n\t\ttry {\n\t\t\tstate.fd = openSync(eventsPath, 'r');\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\ttry {\n\t\tconst size = statSync(eventsPath).size;\n\t\tif (size < state.lastFileSize) {\n\t\t\t// File was truncated / rotated — drop the stale fd and reopen\n\t\t\t// so we read the new tail from byte zero.\n\t\t\ttry {\n\t\t\t\tcloseSync(state.fd);\n\t\t\t} catch {\n\t\t\t\t// Best-effort close; the inode is gone anyway.\n\t\t\t}\n\t\t\tstate.fd = null;\n\t\t\tstate.offset = 0;\n\t\t\tstate.lineIndex = 0;\n\t\t\tstate.carry = '';\n\t\t\tstate.latestAppEndpointLine = -1;\n\t\t\tstate.latestCodegenLine = -1;\n\t\t\tstate.lastFileSize = 0;\n\t\t\ttry {\n\t\t\t\tstate.fd = openSync(eventsPath, 'r');\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tstate.lastFileSize = size;\n\t\tconst buf = Buffer.allocUnsafe(READ_CHUNK_BYTES);\n\t\twhile (state.offset < size) {\n\t\t\tconst bytesRead = readSync(state.fd, buf, 0, READ_CHUNK_BYTES, state.offset);\n\t\t\tif (bytesRead <= 0) break;\n\t\t\tstate.offset += bytesRead;\n\t\t\tconst chunk = state.carry + buf.subarray(0, bytesRead).toString('utf8');\n\t\t\tconst segments = chunk.split(/\\r?\\n/);\n\t\t\tstate.carry = segments.pop() ?? '';\n\t\t\tfor (const segment of segments) {\n\t\t\t\tingestNdjsonLine(state, segment);\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// Treat read errors as \"no progress this poll\"; the fd stays\n\t\t// open so the next tick retries from `state.offset`.\n\t}\n\tif (state.latestCodegenLine < 0) return false;\n\tif (state.latestAppEndpointLine < 0) return true;\n\treturn state.latestCodegenLine > state.latestAppEndpointLine;\n};\n\nconst closeCodegenWatch = (state: CodegenWatchState): void => {\n\tif (state.fd === null) return;\n\ttry {\n\t\tcloseSync(state.fd);\n\t} catch {\n\t\t// Best-effort — we're done with the file regardless.\n\t}\n\tstate.fd = null;\n};\n\nconst waitForReadyStackContext = async (\n\toptions: DefineGlobalSetupOptions,\n): Promise<StackContext> => {\n\tconst timeoutMs = options.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS;\n\tconst intervalMs = options.readyPollIntervalMs ?? DEFAULT_READY_POLL_INTERVAL_MS;\n\tconst deadline = Date.now() + timeoutMs;\n\tlet lastError: unknown = null;\n\n\t// Phase 1: poll for the manifest itself. The supervisor writes it\n\t// eagerly during boot, but Playwright's `webServer.command` race\n\t// can land us here before the file exists. Once we've decoded a\n\t// manifest, we pin to its location for the remainder of the wait —\n\t// re-decoding on every tick (default 100ms over 5min) costs\n\t// thousands of JSON+Schema decodes for no information gain.\n\tlet ctx: StackContext | null = null;\n\twhile (Date.now() <= deadline) {\n\t\ttry {\n\t\t\tctx = readContextForSetup(options);\n\t\t\tbreak;\n\t\t} catch (cause) {\n\t\t\tlastError = cause;\n\t\t\tawait sleep(intervalMs);\n\t\t}\n\t}\n\tif (ctx === null) {\n\t\tthrow new Error(\n\t\t\t`devstack manifest did not appear within ${timeoutMs}ms` +\n\t\t\t\t(lastError instanceof Error ? `: ${lastError.message}` : ''),\n\t\t);\n\t}\n\n\t// Phase 2: tail `events.ndjson` for the codegen-fresh signal. Only\n\t// the events file changes during this phase — the manifest path is\n\t// fixed once Phase 1 succeeds. The watch holds an open fd across\n\t// polls; we close it on every exit path (success, timeout, throw).\n\tconst eventsPath = join(dirname(ctx.manifestPath), 'events.ndjson');\n\tconst watchState = createCodegenWatchState();\n\ttry {\n\t\twhile (Date.now() <= deadline) {\n\t\t\tif (advanceCodegenWatch(watchState, eventsPath)) return ctx;\n\t\t\tlastError = new Error(\n\t\t\t\t`devstack has not emitted codegen yet; waiting on events next to ${ctx.manifestPath}`,\n\t\t\t);\n\t\t\tawait sleep(intervalMs);\n\t\t}\n\t} finally {\n\t\tcloseCodegenWatch(watchState);\n\t}\n\n\tthrow new Error(\n\t\t`devstack did not reach post-acquire codegen within ${timeoutMs}ms` +\n\t\t\t(lastError instanceof Error ? `: ${lastError.message}` : ''),\n\t);\n};\n\n/**\n * Build a Playwright `globalSetup` function. The returned function\n * matches the signature Playwright expects (a default export of a\n * module path; we return the function so the preset can wire it).\n */\nexport const buildGlobalSetup = (options: DefineGlobalSetupOptions = {}): PlaywrightGlobalSetup => {\n\treturn async () => {\n\t\tconst ctx =\n\t\t\t(options.waitForCodegen ?? true)\n\t\t\t\t? await waitForReadyStackContext(options)\n\t\t\t\t: readContextForSetup(options);\n\n\t\tif (options.requireNonEmptyEndpoints === true) {\n\t\t\tif (ctx.endpointNames.length === 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`devstack manifest at ${ctx.manifestPath} has no endpoints. ` +\n\t\t\t\t\t\t`The supervisor likely failed before its eager snapshot ` +\n\t\t\t\t\t\t`write; check the dev server logs for plugin acquire errors.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst required = options.requireEndpoints ?? [];\n\t\tconst missing: string[] = [];\n\t\tfor (const key of required) {\n\t\t\tif (ctx.endpointMaybe(key) === null) missing.push(key);\n\t\t}\n\t\tif (missing.length > 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`devstack manifest at ${ctx.manifestPath} is missing required ` +\n\t\t\t\t\t`endpoints: ${missing.join(', ')}. ` +\n\t\t\t\t\t`available endpoint names: ${ctx.endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t\t`raw manifest keys: ${ctx.manifestEndpointKeys.join(', ') || '(none)'}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (options.preloadContext ?? true) {\n\t\t\tstashStackContext(ctx);\n\t\t}\n\n\t\t// Return value: `void` (no teardown). Playwright accepts\n\t\t// `() => Promise<void>` here.\n\t};\n};\n\n/** Default export shape that mirrors what Playwright's\n * `defineConfig.globalSetup` resolves: a module whose default export\n * is the setup function. */\nexport default buildGlobalSetup();\n\n// -----------------------------------------------------------------------------\n// Global stash\n// -----------------------------------------------------------------------------\n\n/** The slot on `globalThis` where the prewarmed stack context lives.\n * In-spec helpers (`wallet-context.ts`) read from here when present\n * to avoid a second disk read. Re-exported from the runtime slot\n * module so consumers can import either side. */\nexport const STACK_CONTEXT_SLOT = PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY;\n\n/** Monotonic counter for fixture rotations within a single Node process.\n * Survives across `stashStackContext` calls so a Playwright retry that\n * re-runs global-setup stamps a fresh `generation` even though the\n * module never reloads. */\nlet stashGeneration = 0;\n\nconst stashStackContext = (ctx: StackContext): void => {\n\t// Include alias keys in the stashed endpoints map so consumers\n\t// iterating `fixture.endpoints` see the same contract as callers\n\t// of `endpoint(alias)`. Without this, `fixture.endpoints['app']`\n\t// would miss while `ctx.endpoint('app')` resolves to `'dev'` —\n\t// the asymmetry surprises consumers reading the raw dict.\n\tconst endpoints: Record<string, string> = Object.fromEntries(\n\t\tctx.endpointNames.map((name) => [name, ctx.endpoint(name)]),\n\t);\n\tfor (const [alias, canonical] of Object.entries(BUILT_IN_ENDPOINT_ALIASES)) {\n\t\tif (alias in endpoints) continue;\n\t\tconst url = endpoints[canonical];\n\t\tif (url !== undefined) endpoints[alias] = url;\n\t}\n\tstashGeneration += 1;\n\tconst fixture: PlaywrightStackFixture = {\n\t\tendpoints,\n\t\twalletEndpoint: ctx.endpointMaybe(WALLET_ENDPOINT_KEY),\n\t\tmanifestPath: ctx.manifestPath,\n\t\tstack: ctx.manifest.identity.stack,\n\t\tapp: ctx.manifest.identity.app,\n\t\tgeneration: stashGeneration,\n\t};\n\t// Surface a one-line advisory when we overwrite an existing slot —\n\t// a second populate means global-setup ran twice (Playwright retry\n\t// with `reuseExistingServer:false`, or operator wiring both\n\t// `globalSetup` and an inline preset boot). The previous fixture\n\t// may be pointing at a stack that has since been torn down, so any\n\t// helper that cached the prior reference would silently read stale\n\t// state. The bumped `generation` lets cache-holders detect the\n\t// rotation and re-fetch.\n\tconst previous = globalThis[PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY];\n\tif (previous !== undefined) {\n\t\ttry {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`[devstack/playwright] global-setup re-ran (generation ${previous.generation} → ${fixture.generation}); ` +\n\t\t\t\t\t`downstream consumers should re-read globalThis[${PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY}].\\n`,\n\t\t\t);\n\t\t} catch {\n\t\t\t// stderr EPIPE — swallow; the warning is best-effort.\n\t\t}\n\t}\n\tglobalThis[PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY] = fixture;\n};\n\n/** Read the slot. Returns `null` if global-setup didn't run (e.g. the\n * user opted out by passing `globalSetup: null`). */\nexport const readStashedFixture = (): PlaywrightStackFixture | null =>\n\tglobalThis[PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY] ?? null;\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import { PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY } from "../runtime/playwright-stack-context-slot.mjs";
2
+ import { WALLET_ENDPOINT_KEY } from "../../contracts/wallet-protocol.mjs";
1
3
  import { PLAYWRIGHT_ENV, ResolveStackContextOptions, ResolvedEndpoint, StackContext, conventionalUrlFor, discoverManifestPath, makeStackContext, readManifestSync, readStackContext, resolveEndpointUrl } from "./stack-context.mjs";
2
- import { DevstackPlaywrightBaseConfigOptions, DevstackPlaywrightEndpointOptions, DevstackPlaywrightProjectsOptions, DevstackPlaywrightUseOptions, DevstackPlaywrightWebServerOptions, PlaywrightBaseConfigShape, PlaywrightProjectShape, PlaywrightUseConfigShape, PlaywrightWebServerConfigShape, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, resolveDevstackPlaywrightBaseURL } from "./config.mjs";
3
4
  import { DefineGlobalSetupOptions, PlaywrightGlobalSetup, PlaywrightStackFixture, STACK_CONTEXT_SLOT, buildGlobalSetup, readStashedFixture } from "./global-setup.mjs";
4
- import { DAPP_KIT_SLOT, DevAccount, PlaywrightPageLike, SignTxRequest, SignTxResponse, WALLET_ENDPOINT_KEY, WalletAdapter, WalletAdapterOptions, connectAs, createWalletAdapter, loadStackManifest, selectAccount } from "./wallet-context.mjs";
5
+ import { DevstackPlaywrightBaseConfigOptions, DevstackPlaywrightEndpointOptions, DevstackPlaywrightProjectsOptions, DevstackPlaywrightUseOptions, DevstackPlaywrightWebServerOptions, PlaywrightBaseConfigShape, PlaywrightProjectShape, PlaywrightUseConfigShape, PlaywrightWebServerConfigShape, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, resolveDevstackPlaywrightBaseURL } from "./config.mjs";
6
+ import { DAPP_KIT_SLOT, DevAccount, PlaywrightPageLike, SignTxRequest, SignTxResponse, WalletAdapter, WalletAdapterOptions, connectAs, createWalletAdapter, loadStackManifest, selectAccount } from "./wallet-context.mjs";
5
7
  import { PlaywrightEndpointNotFoundError, PlaywrightIntegrationError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, PlaywrightWalletAdapterError } from "./errors.mjs";
6
- export { DAPP_KIT_SLOT, type DefineGlobalSetupOptions, type DevAccount, type DevstackPlaywrightBaseConfigOptions, type DevstackPlaywrightEndpointOptions, type DevstackPlaywrightProjectsOptions, type DevstackPlaywrightUseOptions, type DevstackPlaywrightWebServerOptions, PLAYWRIGHT_ENV, type PlaywrightBaseConfigShape, PlaywrightEndpointNotFoundError, type PlaywrightGlobalSetup, type PlaywrightIntegrationError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, type PlaywrightPageLike, type PlaywrightProjectShape, type PlaywrightStackFixture, type PlaywrightUseConfigShape, PlaywrightWalletAdapterError, type PlaywrightWebServerConfigShape, type ResolveStackContextOptions, type ResolvedEndpoint, STACK_CONTEXT_SLOT, type SignTxRequest, type SignTxResponse, type StackContext, WALLET_ENDPOINT_KEY, type WalletAdapter, type WalletAdapterOptions, buildGlobalSetup, connectAs, conventionalUrlFor, createWalletAdapter, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, discoverManifestPath, loadStackManifest, makeStackContext, readManifestSync, readStackContext, readStashedFixture, resolveDevstackPlaywrightBaseURL, resolveEndpointUrl, selectAccount };
8
+ export { DAPP_KIT_SLOT, type DefineGlobalSetupOptions, type DevAccount, type DevstackPlaywrightBaseConfigOptions, type DevstackPlaywrightEndpointOptions, type DevstackPlaywrightProjectsOptions, type DevstackPlaywrightUseOptions, type DevstackPlaywrightWebServerOptions, PLAYWRIGHT_ENV, PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY, type PlaywrightBaseConfigShape, PlaywrightEndpointNotFoundError, type PlaywrightGlobalSetup, type PlaywrightIntegrationError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, type PlaywrightPageLike, type PlaywrightProjectShape, type PlaywrightStackFixture, type PlaywrightUseConfigShape, PlaywrightWalletAdapterError, type PlaywrightWebServerConfigShape, type ResolveStackContextOptions, type ResolvedEndpoint, STACK_CONTEXT_SLOT, type SignTxRequest, type SignTxResponse, type StackContext, WALLET_ENDPOINT_KEY, type WalletAdapter, type WalletAdapterOptions, buildGlobalSetup, connectAs, conventionalUrlFor, createWalletAdapter, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, discoverManifestPath, loadStackManifest, makeStackContext, readManifestSync, readStackContext, readStashedFixture, resolveDevstackPlaywrightBaseURL, resolveEndpointUrl, selectAccount };
@@ -1,6 +1,8 @@
1
+ import { WALLET_ENDPOINT_KEY } from "../../contracts/wallet-protocol.mjs";
2
+ import { PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY } from "../runtime/playwright-stack-context-slot.mjs";
1
3
  import { PlaywrightEndpointNotFoundError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, PlaywrightWalletAdapterError } from "./errors.mjs";
2
4
  import { PLAYWRIGHT_ENV, conventionalUrlFor, discoverManifestPath, makeStackContext, readManifestSync, readStackContext, resolveEndpointUrl } from "./stack-context.mjs";
3
5
  import { devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, resolveDevstackPlaywrightBaseURL } from "./config.mjs";
4
6
  import { STACK_CONTEXT_SLOT, buildGlobalSetup, readStashedFixture } from "./global-setup.mjs";
5
- import { DAPP_KIT_SLOT, WALLET_ENDPOINT_KEY, connectAs, createWalletAdapter, loadStackManifest, selectAccount } from "./wallet-context.mjs";
6
- export { DAPP_KIT_SLOT, PLAYWRIGHT_ENV, PlaywrightEndpointNotFoundError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, PlaywrightWalletAdapterError, STACK_CONTEXT_SLOT, WALLET_ENDPOINT_KEY, buildGlobalSetup, connectAs, conventionalUrlFor, createWalletAdapter, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, discoverManifestPath, loadStackManifest, makeStackContext, readManifestSync, readStackContext, readStashedFixture, resolveDevstackPlaywrightBaseURL, resolveEndpointUrl, selectAccount };
7
+ import { DAPP_KIT_SLOT, connectAs, createWalletAdapter, loadStackManifest, selectAccount } from "./wallet-context.mjs";
8
+ export { DAPP_KIT_SLOT, PLAYWRIGHT_ENV, PLAYWRIGHT_STACK_CONTEXT_SLOT_KEY, PlaywrightEndpointNotFoundError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError, PlaywrightWalletAdapterError, STACK_CONTEXT_SLOT, WALLET_ENDPOINT_KEY, buildGlobalSetup, connectAs, conventionalUrlFor, createWalletAdapter, devstackPlaywrightBaseConfig, devstackPlaywrightProjects, devstackPlaywrightUse, devstackPlaywrightWebServer, discoverManifestPath, loadStackManifest, makeStackContext, readManifestSync, readStackContext, readStashedFixture, resolveDevstackPlaywrightBaseURL, resolveEndpointUrl, selectAccount };
@@ -1,5 +1,4 @@
1
1
  import { EndpointEntry, ManifestEnvelope } from "../../substrate/manifest.mjs";
2
-
3
2
  //#region src/build-integrations/playwright/stack-context.d.ts
4
3
  /** Centralized env-var names this surface consults. Kept in sync with
5
4
  * the CLI's `ENV_VARS` table. */
@@ -1,8 +1,11 @@
1
+ import { resolveDiscoveryEnv } from "../runtime/resolve-discovery-env.mjs";
1
2
  import { ManifestDiscoveryError, ManifestShapeError } from "../runtime/errors.mjs";
2
3
  import { discoverManifestPath as discoverManifestPath$1 } from "../runtime/discover.mjs";
3
4
  import { EndpointRegistry } from "../runtime/endpoint-registry.mjs";
4
5
  import { manifestEnvelopeFromStackContext, readStackContext as readStackContext$1 } from "../runtime/read-stack-context.mjs";
5
- import { coldStartUrl, conventionalRoutesFromHints } from "../runtime/cold-start-url.mjs";
6
+ import { coldStartUrl } from "../runtime/cold-start-url.mjs";
7
+ import { builtInConventionalRoutes, resolveBuiltInEndpointAlias } from "../runtime/conventional-routes.mjs";
8
+ import "../runtime/index.mjs";
6
9
  import { PlaywrightEndpointNotFoundError, PlaywrightManifestDiscoveryError, PlaywrightManifestShapeError } from "./errors.mjs";
7
10
  //#region src/build-integrations/playwright/stack-context.ts
8
11
  /** Centralized env-var names this surface consults. Kept in sync with
@@ -14,17 +17,11 @@ const PLAYWRIGHT_ENV = {
14
17
  ROUTER_HOST_SUFFIX: "DEVSTACK_ROUTER_HOST_SUFFIX",
15
18
  ROUTER_PORT: "DEVSTACK_ROUTER_PORT"
16
19
  };
17
- const PLAYWRIGHT_ENDPOINT_ALIASES = {
18
- app: "dev",
19
- wallet: "wallet-app"
20
- };
21
- const PLAYWRIGHT_DEFAULT_ROUTER_PORTS = {
22
- app: 5175,
23
- dev: 5175,
24
- wallet: 5175,
25
- "wallet-app": 5175
26
- };
27
- const playwrightEndpointNameFor = (endpointNameOrAlias) => PLAYWRIGHT_ENDPOINT_ALIASES[endpointNameOrAlias] ?? endpointNameOrAlias;
20
+ /** Resolve a user-typed endpoint name or alias to the canonical
21
+ * endpoint name the manifest stores. Delegates to the canonical
22
+ * alias resolver in `runtime/conventional-routes.ts` so vitest and
23
+ * Playwright share one alias table. */
24
+ const playwrightEndpointNameFor = (endpointNameOrAlias) => resolveBuiltInEndpointAlias(endpointNameOrAlias);
28
25
  const endpointRegistryFromEnvelope = (envelope) => {
29
26
  const entries = [];
30
27
  for (const raw of Object.values(envelope.endpoints)) entries.push({
@@ -39,14 +36,16 @@ const endpointRegistryFromEnvelope = (envelope) => {
39
36
  };
40
37
  const buildRuntimeDiscoverOpts = (options) => {
41
38
  const env = options.env ?? process.env;
42
- const stack = options.stack ?? env[PLAYWRIGHT_ENV.STACK] ?? "main";
43
- const stateDir = options.stateDir ?? env[PLAYWRIGHT_ENV.STATE_DIR];
39
+ const { stack, stateDir } = resolveDiscoveryEnv(env, {
40
+ ...options.stack !== void 0 ? { stack: options.stack } : {},
41
+ ...options.stateDir !== void 0 ? { stateDir: options.stateDir } : {}
42
+ });
44
43
  return {
45
44
  env,
46
45
  stack,
46
+ stateDir,
47
47
  ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
48
- ...options.manifestPath !== void 0 ? { override: options.manifestPath } : {},
49
- ...stateDir !== void 0 && stateDir !== "" ? { stateDir } : {}
48
+ ...options.manifestPath !== void 0 ? { override: options.manifestPath } : {}
50
49
  };
51
50
  };
52
51
  /**
@@ -79,12 +78,10 @@ const readManifestSync = (manifestPath) => {
79
78
  recoveryHint: cause.phase === "version" ? "Re-run `devstack up` to write a manifest at the current version, or upgrade @mysten-incubation/devstack to a build-integration that understands the new envelope." : `Delete \`${manifestPath}\` and run \`devstack up\`. If the error persists, the build-integration is older than the supervisor.`,
80
79
  cause
81
80
  });
82
- if (cause instanceof ManifestDiscoveryError) throw new PlaywrightManifestShapeError({
83
- message: `failed to read manifest at ${manifestPath}`,
84
- manifestPath,
85
- phase: "parse",
86
- recoveryHint: "Confirm the file exists and is readable. Run `devstack up` to regenerate it if the supervisor was interrupted mid-write.",
87
- cause
81
+ if (cause instanceof ManifestDiscoveryError) throw new PlaywrightManifestDiscoveryError({
82
+ message: cause.message !== "" ? cause.message : `manifest at ${manifestPath} could not be read`,
83
+ searchedPaths: cause.path !== void 0 ? [cause.path] : [manifestPath],
84
+ recoveryHint: "Confirm the file exists and is readable. Run `devstack up` to regenerate it if the supervisor was interrupted mid-write."
88
85
  });
89
86
  throw cause;
90
87
  }
@@ -103,53 +100,17 @@ const conventionalUrlFor = (endpointKey, opts = {}) => {
103
100
  const stack = opts.stack ?? "main";
104
101
  const env = opts.env ?? process.env;
105
102
  const envPort = Number.parseInt(env[PLAYWRIGHT_ENV.ROUTER_PORT] ?? "", 10);
106
- const resolvedPort = opts.port ?? (Number.isFinite(envPort) && envPort > 0 ? envPort : void 0) ?? PLAYWRIGHT_DEFAULT_ROUTER_PORTS[endpointKey];
107
- if (resolvedPort === void 0 || !Number.isFinite(resolvedPort) || resolvedPort <= 0) return null;
108
- const routes = conventionalRoutesFromHints([
109
- {
110
- endpoint: "app",
111
- service: "dev"
112
- },
113
- {
114
- endpoint: "dev",
115
- service: "dev"
116
- },
117
- {
118
- endpoint: "sui-rpc",
119
- service: "sui-rpc"
120
- },
121
- {
122
- endpoint: "sui-faucet",
123
- service: "sui-faucet"
124
- },
125
- {
126
- endpoint: "walrus-aggregator",
127
- service: "walrus-aggregator"
128
- },
129
- {
130
- endpoint: "walrus-publisher",
131
- service: "walrus-publisher"
132
- },
133
- {
134
- endpoint: "seal",
135
- service: "seal"
136
- },
137
- {
138
- endpoint: "wallet",
139
- service: "api"
140
- },
141
- {
142
- endpoint: "wallet-app",
143
- service: "api"
144
- }
145
- ], resolvedPort);
103
+ const resolvedPort = opts.port ?? (Number.isFinite(envPort) && envPort > 0 ? envPort : void 0) ?? 5175;
104
+ if (!Number.isFinite(resolvedPort) || resolvedPort <= 0) return null;
105
+ const routes = builtInConventionalRoutes(resolvedPort);
146
106
  if (!routes.has(endpointKey)) return null;
147
107
  return coldStartUrl(endpointKey, {
148
108
  routes,
149
109
  stack,
150
110
  ...opts.app !== void 0 ? { app: opts.app } : {},
151
111
  ...opts.cwd !== void 0 ? { cwd: opts.cwd } : {},
152
- ...opts.hostSuffix !== void 0 ? { hostSuffix: opts.hostSuffix } : {}
112
+ ...opts.hostSuffix !== void 0 ? { hostSuffix: opts.hostSuffix } : {},
113
+ ...opts.env !== void 0 ? { env: opts.env } : {}
153
114
  });
154
115
  };
155
116
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"stack-context.mjs","names":["runtimeDiscoverManifestPath","readStackContextRuntime","port","runtimeColdStartUrl"],"sources":["../../../src/build-integrations/playwright/stack-context.ts"],"sourcesContent":["// Stack-context surface for the Playwright preset — thin wrapper\n// over `runtime/`'s sync read API.\n//\n// Playwright config-load is synchronous; it runs BEFORE the supervisor\n// spawns, so the preset MUST support a cold-start fallback that picks\n// a conventional URL when the manifest isn't on disk yet. The\n// decode + version-gate + walk-up live in `runtime/`; this surface\n// re-shapes the result into playwright-flavored typed errors and the\n// endpoint-name accessors in-spec helpers use.\n\nimport {\n\tdiscoverManifestPath as runtimeDiscoverManifestPath,\n\tcoldStartUrl as runtimeColdStartUrl,\n\tconventionalRoutesFromHints,\n\tEndpointRegistry,\n\tmanifestEnvelopeFromStackContext,\n\tManifestDiscoveryError,\n\tManifestShapeError,\n\treadStackContext as readStackContextRuntime,\n\ttype DiscoverManifestPathOptions,\n\ttype ResolvedEndpoint as RuntimeResolvedEndpoint,\n\ttype StackContext as RuntimeStackContext,\n} from '../runtime/index.ts';\nimport type { EndpointEntry, ManifestEnvelope } from '../../substrate/manifest.ts';\nimport {\n\tPlaywrightEndpointNotFoundError,\n\tPlaywrightManifestDiscoveryError,\n\tPlaywrightManifestShapeError,\n} from './errors.ts';\n\n/** Centralized env-var names this surface consults. Kept in sync with\n * the CLI's `ENV_VARS` table. */\nexport const PLAYWRIGHT_ENV = {\n\tSTATE_DIR: 'DEVSTACK_STATE_DIR',\n\tSTACK: 'DEVSTACK_STACK',\n\tMANIFEST_PATH: 'DEVSTACK_MANIFEST_PATH',\n\tROUTER_HOST_SUFFIX: 'DEVSTACK_ROUTER_HOST_SUFFIX',\n\tROUTER_PORT: 'DEVSTACK_ROUTER_PORT',\n} as const;\n\nexport interface ResolveStackContextOptions {\n\t/** Working directory to start the walk-up from. */\n\treadonly cwd?: string;\n\t/** Explicit manifest path. Wins over discovery + env. */\n\treadonly manifestPath?: string;\n\t/** Explicit `<stateDir>` root override. Combined with `stack` to\n\t * form `<root>/stacks/<stack>/manifest.json`. */\n\treadonly stateDir?: string;\n\t/** Stack name override. Defaults to env `DEVSTACK_STACK`. */\n\treadonly stack?: string;\n\t/** Env bag (defaults to `process.env`). Injectable for tests. */\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface StackContext {\n\treadonly manifest: ManifestEnvelope;\n\treadonly manifestPath: string;\n\treadonly endpointNames: ReadonlyArray<string>;\n\treadonly manifestEndpointKeys: ReadonlyArray<string>;\n\treadonly endpoint: (endpointNameOrAlias: string) => string;\n\treadonly endpointMaybe: (endpointNameOrAlias: string) => string | null;\n\treadonly endpointEntry: (endpointNameOrAlias: string) => EndpointEntry;\n}\n\nexport interface ResolvedEndpoint {\n\treadonly url: string;\n\treadonly source: 'manifest' | 'conventional';\n\treadonly endpointKey: string;\n\treadonly endpointName: string;\n}\n\nconst PLAYWRIGHT_ENDPOINT_ALIASES: Readonly<Record<string, string>> = {\n\tapp: 'dev',\n\twallet: 'wallet-app',\n};\n\nconst PLAYWRIGHT_DEFAULT_ROUTER_PORTS: Readonly<Record<string, number>> = {\n\tapp: 5175,\n\tdev: 5175,\n\twallet: 5175,\n\t'wallet-app': 5175,\n};\n\nexport const playwrightEndpointNameFor = (endpointNameOrAlias: string): string =>\n\tPLAYWRIGHT_ENDPOINT_ALIASES[endpointNameOrAlias] ?? endpointNameOrAlias;\n\nconst endpointRegistryFromEnvelope = (envelope: ManifestEnvelope): EndpointRegistry => {\n\tconst entries: RuntimeResolvedEndpoint[] = [];\n\tfor (const raw of Object.values(envelope.endpoints)) {\n\t\tentries.push({\n\t\t\tname: raw.name,\n\t\t\turl: raw.url,\n\t\t\tdisplayUrl: raw.displayUrl,\n\t\t\twireProtocol: raw.wireProtocol,\n\t\t\tpluginKey: raw.pluginKey as string,\n\t\t\tendpointKey: raw.endpointKey as string,\n\t\t});\n\t}\n\treturn new EndpointRegistry(entries);\n};\n\n// -----------------------------------------------------------------------------\n// Discovery\n// -----------------------------------------------------------------------------\n\nconst buildRuntimeDiscoverOpts = (\n\toptions: ResolveStackContextOptions,\n): DiscoverManifestPathOptions => {\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\tconst stack = options.stack ?? env[PLAYWRIGHT_ENV.STACK] ?? 'main';\n\tconst stateDir = options.stateDir ?? env[PLAYWRIGHT_ENV.STATE_DIR];\n\treturn {\n\t\tenv,\n\t\tstack,\n\t\t...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n\t\t...(options.manifestPath !== undefined ? { override: options.manifestPath } : {}),\n\t\t...(stateDir !== undefined && stateDir !== '' ? { stateDir } : {}),\n\t};\n};\n\n/**\n * Find the stack-scoped manifest by walking up from `cwd` looking for\n * `.devstack/stacks/<stack>/manifest.json`. Returns the absolute path\n * + the list of paths probed, or `null` on miss.\n */\nexport const discoverManifestPath = (\n\toptions: ResolveStackContextOptions = {},\n): { readonly path: string; readonly searched: ReadonlyArray<string> } | null => {\n\tconst path = runtimeDiscoverManifestPath(buildRuntimeDiscoverOpts(options));\n\tif (path === undefined) return null;\n\t// Runtime resolver doesn't surface intermediate probe paths today.\n\t// We expose the resolved path in the `searched` array so the\n\t// PlaywrightManifestDiscoveryError can still cite at least one\n\t// concrete path.\n\treturn { path, searched: [path] };\n};\n\n// -----------------------------------------------------------------------------\n// Synchronous read + decode\n// -----------------------------------------------------------------------------\n\n/**\n * Synchronously read + decode the manifest at `manifestPath`. Throws\n * `PlaywrightManifestShapeError` on JSON-parse or schema-decode\n * failure, or version mismatch. Used by callers that already know\n * the path (preset's webServer.url resolution + global-setup).\n */\nexport const readManifestSync = (manifestPath: string): ManifestEnvelope => {\n\ttry {\n\t\treturn manifestEnvelopeFromStackContext(readStackContextRuntime({ manifestPath }));\n\t} catch (cause) {\n\t\tif (cause instanceof ManifestShapeError) {\n\t\t\tthrow new PlaywrightManifestShapeError({\n\t\t\t\tmessage:\n\t\t\t\t\tcause.phase === 'version'\n\t\t\t\t\t\t? `manifest at ${manifestPath} version mismatch: ${cause.message}`\n\t\t\t\t\t\t: `manifest at ${manifestPath} does not match the envelope schema`,\n\t\t\t\tmanifestPath,\n\t\t\t\tphase: cause.phase === 'version' ? 'version-mismatch' : 'shape',\n\t\t\t\trecoveryHint:\n\t\t\t\t\tcause.phase === 'version'\n\t\t\t\t\t\t? `Re-run \\`devstack up\\` to write a manifest at the current version, ` +\n\t\t\t\t\t\t\t`or upgrade @mysten-incubation/devstack to a build-integration ` +\n\t\t\t\t\t\t\t`that understands the new envelope.`\n\t\t\t\t\t\t: `Delete \\`${manifestPath}\\` and run \\`devstack up\\`. If the error ` +\n\t\t\t\t\t\t\t`persists, the build-integration is older than the supervisor.`,\n\t\t\t\tcause,\n\t\t\t});\n\t\t}\n\t\tif (cause instanceof ManifestDiscoveryError) {\n\t\t\tthrow new PlaywrightManifestShapeError({\n\t\t\t\tmessage: `failed to read manifest at ${manifestPath}`,\n\t\t\t\tmanifestPath,\n\t\t\t\tphase: 'parse',\n\t\t\t\trecoveryHint:\n\t\t\t\t\t`Confirm the file exists and is readable. Run \\`devstack up\\` to ` +\n\t\t\t\t\t`regenerate it if the supervisor was interrupted mid-write.`,\n\t\t\t\tcause,\n\t\t\t});\n\t\t}\n\t\tthrow cause;\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Conventional URL fallback\n// -----------------------------------------------------------------------------\n\n/**\n * Cold-start URL fallback for endpoints with a conventional host\n * pattern. Playwright config-load runs BEFORE the supervisor writes\n * the manifest; the preset MUST be able to resolve a `baseURL`\n * without a manifest read.\n *\n * The route table shape matches `runtime/coldStartUrl`; Playwright\n * only supplies its conventional endpoint hints while the shared\n * runtime helper owns host formatting.\n */\nexport const conventionalUrlFor = (\n\tendpointKey: string,\n\topts: {\n\t\treadonly stack?: string;\n\t\treadonly hostSuffix?: string;\n\t\treadonly port?: number;\n\t\treadonly app?: string;\n\t\treadonly cwd?: string;\n\t\treadonly env?: Readonly<Record<string, string | undefined>>;\n\t} = {},\n): string | null => {\n\tconst stack = opts.stack ?? 'main';\n\tconst env = opts.env ?? (process.env as Record<string, string | undefined>);\n\tconst envPort = Number.parseInt(env[PLAYWRIGHT_ENV.ROUTER_PORT] ?? '', 10);\n\tconst resolvedPort =\n\t\topts.port ??\n\t\t(Number.isFinite(envPort) && envPort > 0 ? envPort : undefined) ??\n\t\tPLAYWRIGHT_DEFAULT_ROUTER_PORTS[endpointKey];\n\n\tif (resolvedPort === undefined || !Number.isFinite(resolvedPort) || resolvedPort <= 0) {\n\t\treturn null;\n\t}\n\tconst port = resolvedPort;\n\n\tconst routes = conventionalRoutesFromHints(\n\t\t[\n\t\t\t{ endpoint: 'app', service: 'dev' },\n\t\t\t{ endpoint: 'dev', service: 'dev' },\n\t\t\t{ endpoint: 'sui-rpc', service: 'sui-rpc' },\n\t\t\t{ endpoint: 'sui-faucet', service: 'sui-faucet' },\n\t\t\t{ endpoint: 'walrus-aggregator', service: 'walrus-aggregator' },\n\t\t\t{ endpoint: 'walrus-publisher', service: 'walrus-publisher' },\n\t\t\t{ endpoint: 'seal', service: 'seal' },\n\t\t\t{ endpoint: 'wallet', service: 'api' },\n\t\t\t{ endpoint: 'wallet-app', service: 'api' },\n\t\t],\n\t\tport,\n\t);\n\tif (!routes.has(endpointKey)) return null;\n\n\treturn runtimeColdStartUrl(endpointKey, {\n\t\troutes,\n\t\tstack,\n\t\t...(opts.app !== undefined ? { app: opts.app } : {}),\n\t\t...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),\n\t\t...(opts.hostSuffix !== undefined ? { hostSuffix: opts.hostSuffix } : {}),\n\t});\n};\n\n// -----------------------------------------------------------------------------\n// Public readers\n// -----------------------------------------------------------------------------\n\n/**\n * Synchronously resolve the full stack context. Throws on missing\n * manifest (no cold-start fallback here — caller wants the typed\n * envelope, not a guessed URL).\n */\nexport const readStackContext = (options: ResolveStackContextOptions = {}): StackContext => {\n\ttry {\n\t\tconst ctx = readStackContextRuntime(buildRuntimeDiscoverOpts(options));\n\t\treturn projectFromRuntime(ctx);\n\t} catch (err) {\n\t\tif (err instanceof ManifestDiscoveryError) {\n\t\t\tthrow new PlaywrightManifestDiscoveryError({\n\t\t\t\tmessage: 'no manifest found along walk-up path or env override',\n\t\t\t\tsearchedPaths: err.path !== undefined ? [err.path] : [],\n\t\t\t\trecoveryHint:\n\t\t\t\t\t`Run \\`devstack up\\` from your example app's directory to write ` +\n\t\t\t\t\t`the manifest, or set DEVSTACK_MANIFEST_PATH to an explicit path.`,\n\t\t\t});\n\t\t}\n\t\tif (err instanceof ManifestShapeError) {\n\t\t\tthrow new PlaywrightManifestShapeError({\n\t\t\t\tmessage: err.message,\n\t\t\t\tmanifestPath: err.path,\n\t\t\t\tphase: err.phase === 'version' ? 'version-mismatch' : err.phase,\n\t\t\t\trecoveryHint: `Delete \\`${err.path}\\` and run \\`devstack up\\` to regenerate.`,\n\t\t\t\tcause: err,\n\t\t\t});\n\t\t}\n\t\tthrow err;\n\t}\n};\n\nconst projectFromRuntime = (ctx: RuntimeStackContext): StackContext => {\n\tconst envelope = manifestEnvelopeFromStackContext(ctx);\n\treturn makeStackContext(envelope, ctx.manifestPath);\n};\n\n/** Project an in-memory envelope (test fixtures use this) into the\n * same accessor shape as the on-disk read. */\nexport const makeStackContext = (\n\tenvelope: ManifestEnvelope,\n\tmanifestPath: string,\n): StackContext => {\n\tconst endpoints = endpointRegistryFromEnvelope(envelope);\n\tconst manifestEndpointKeys = Object.keys(envelope.endpoints).sort();\n\tconst endpointNames = endpoints.names();\n\tconst notFound = (endpointKey: string, endpointName: string): PlaywrightEndpointNotFoundError =>\n\t\tnew PlaywrightEndpointNotFoundError({\n\t\t\tmessage:\n\t\t\t\t`no endpoint \\`${endpointKey}\\` (resolved endpoint name \\`${endpointName}\\`) ` +\n\t\t\t\t`in manifest at ${manifestPath}`,\n\t\t\tendpointKey,\n\t\t\tendpointName,\n\t\t\tavailable: endpointNames,\n\t\t\tmanifestKeys: manifestEndpointKeys,\n\t\t\trecoveryHint:\n\t\t\t\t`Available endpoint names: ${endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t`Raw manifest keys: ${manifestEndpointKeys.join(', ') || '(none)'}. ` +\n\t\t\t\t`Check the plugin emitting this endpoint is present in your stack, ` +\n\t\t\t\t`or check for a typo in the endpoint name.`,\n\t\t});\n\tconst findEndpoint = (endpointNameOrAlias: string): RuntimeResolvedEndpoint | undefined =>\n\t\tendpoints.byName(playwrightEndpointNameFor(endpointNameOrAlias));\n\tconst rawEntryFor = (resolved: RuntimeResolvedEndpoint): EndpointEntry => {\n\t\tconst byMapKey = envelope.endpoints[resolved.endpointKey];\n\t\tif (byMapKey !== undefined) return byMapKey;\n\t\tconst byEntryKey = Object.values(envelope.endpoints).find(\n\t\t\t(entry) => (entry.endpointKey as string) === resolved.endpointKey,\n\t\t);\n\t\tif (byEntryKey !== undefined) return byEntryKey;\n\t\treturn {\n\t\t\tname: resolved.name,\n\t\t\turl: resolved.url,\n\t\t\tdisplayUrl: resolved.displayUrl,\n\t\t\twireProtocol: resolved.wireProtocol,\n\t\t\tpluginKey: resolved.pluginKey as never,\n\t\t\tendpointKey: resolved.endpointKey as never,\n\t\t};\n\t};\n\n\treturn {\n\t\tmanifest: envelope,\n\t\tmanifestPath,\n\t\tendpointNames,\n\t\tmanifestEndpointKeys,\n\t\tendpoint: (endpointNameOrAlias: string): string => {\n\t\t\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\t\t\tconst entry = findEndpoint(endpointNameOrAlias);\n\t\t\tif (entry === undefined) {\n\t\t\t\tthrow notFound(endpointNameOrAlias, endpointName);\n\t\t\t}\n\t\t\treturn entry.url;\n\t\t},\n\t\tendpointMaybe: (endpointNameOrAlias: string): string | null =>\n\t\t\tfindEndpoint(endpointNameOrAlias)?.url ?? null,\n\t\tendpointEntry: (endpointNameOrAlias: string): EndpointEntry => {\n\t\t\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\t\t\tconst entry = findEndpoint(endpointNameOrAlias);\n\t\t\tif (entry === undefined) {\n\t\t\t\tthrow notFound(endpointNameOrAlias, endpointName);\n\t\t\t}\n\t\t\treturn rawEntryFor(entry);\n\t\t},\n\t};\n};\n\n/**\n * Resolve a URL for a single endpoint with cold-start fallback to the\n * conventional URL when the manifest is absent. Throws when both the\n * manifest and the conventional table miss.\n */\nexport const resolveEndpointUrl = (\n\tendpointNameOrAlias: string,\n\toptions: ResolveStackContextOptions & {\n\t\treadonly port?: number;\n\t\treadonly hostSuffix?: string;\n\t} = {},\n): ResolvedEndpoint => {\n\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\tlet ctx: StackContext | undefined;\n\ttry {\n\t\tctx = readStackContext(options);\n\t} catch (err) {\n\t\tif (!(err instanceof PlaywrightManifestDiscoveryError)) throw err;\n\t}\n\tif (ctx !== undefined) {\n\t\tconst entry = ctx.endpointEntry(endpointNameOrAlias);\n\t\treturn { url: entry.url, source: 'manifest', endpointKey: entry.endpointKey, endpointName };\n\t}\n\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\tconst stack = options.stack ?? env[PLAYWRIGHT_ENV.STACK] ?? 'main';\n\tconst fallback = conventionalUrlFor(endpointNameOrAlias, {\n\t\tstack,\n\t\t...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n\t\t...(options.hostSuffix !== undefined\n\t\t\t? { hostSuffix: options.hostSuffix }\n\t\t\t: env[PLAYWRIGHT_ENV.ROUTER_HOST_SUFFIX] !== undefined\n\t\t\t\t? { hostSuffix: env[PLAYWRIGHT_ENV.ROUTER_HOST_SUFFIX] }\n\t\t\t\t: {}),\n\t\t...(options.port !== undefined ? { port: options.port } : {}),\n\t\t...(options.env !== undefined ? { env: options.env } : {}),\n\t});\n\tif (fallback !== null) {\n\t\treturn {\n\t\t\turl: fallback,\n\t\t\tsource: 'conventional',\n\t\t\tendpointKey: endpointNameOrAlias,\n\t\t\tendpointName,\n\t\t};\n\t}\n\n\tthrow new PlaywrightManifestDiscoveryError({\n\t\tmessage:\n\t\t\t`no manifest found and no conventional fallback for endpoint ` +\n\t\t\t`\\`${endpointNameOrAlias}\\` (resolved endpoint name \\`${endpointName}\\`)`,\n\t\tsearchedPaths: [],\n\t\tendpointKey: endpointNameOrAlias,\n\t\trecoveryHint:\n\t\t\t`Run \\`devstack up\\` to materialize the manifest before invoking ` +\n\t\t\t`playwright, or pass an explicit \\`baseURL\\`.`,\n\t});\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"stack-context.mjs","names":["runtimeDiscoverManifestPath","readStackContextRuntime","runtimeColdStartUrl"],"sources":["../../../src/build-integrations/playwright/stack-context.ts"],"sourcesContent":["// Stack-context surface for the Playwright preset — thin wrapper\n// over `runtime/`'s sync read API.\n//\n// Playwright config-load is synchronous; it runs BEFORE the supervisor\n// spawns, so the preset MUST support a cold-start fallback that picks\n// a conventional URL when the manifest isn't on disk yet. The\n// decode + version-gate + walk-up live in `runtime/`; this surface\n// re-shapes the result into playwright-flavored typed errors and the\n// endpoint-name accessors in-spec helpers use.\n\nimport {\n\tDEFAULT_ROUTER_ENTRYPOINT_PORT,\n\tbuiltInConventionalRoutes,\n\tdiscoverManifestPath as runtimeDiscoverManifestPath,\n\tcoldStartUrl as runtimeColdStartUrl,\n\tEndpointRegistry,\n\tmanifestEnvelopeFromStackContext,\n\tManifestDiscoveryError,\n\tManifestShapeError,\n\treadStackContext as readStackContextRuntime,\n\tresolveBuiltInEndpointAlias,\n\tresolveDiscoveryEnv,\n\ttype DiscoverManifestPathOptions,\n\ttype EndpointEntry,\n\ttype ManifestEnvelope,\n\ttype ResolvedEndpoint as RuntimeResolvedEndpoint,\n\ttype StackContext as RuntimeStackContext,\n} from '../runtime/index.ts';\nimport {\n\tPlaywrightEndpointNotFoundError,\n\tPlaywrightManifestDiscoveryError,\n\tPlaywrightManifestShapeError,\n} from './errors.ts';\n\n/** Centralized env-var names this surface consults. Kept in sync with\n * the CLI's `ENV_VARS` table. */\nexport const PLAYWRIGHT_ENV = {\n\tSTATE_DIR: 'DEVSTACK_STATE_DIR',\n\tSTACK: 'DEVSTACK_STACK',\n\tMANIFEST_PATH: 'DEVSTACK_MANIFEST_PATH',\n\tROUTER_HOST_SUFFIX: 'DEVSTACK_ROUTER_HOST_SUFFIX',\n\tROUTER_PORT: 'DEVSTACK_ROUTER_PORT',\n} as const;\n\nexport interface ResolveStackContextOptions {\n\t/** Working directory to start the walk-up from. */\n\treadonly cwd?: string;\n\t/** Explicit manifest path. Wins over discovery + env. */\n\treadonly manifestPath?: string;\n\t/** Explicit `<stateDir>` root override. Combined with `stack` to\n\t * form `<root>/stacks/<stack>/manifest.json`. */\n\treadonly stateDir?: string;\n\t/** Stack name override. Defaults to env `DEVSTACK_STACK`. */\n\treadonly stack?: string;\n\t/** Env bag (defaults to `process.env`). Injectable for tests. */\n\treadonly env?: Readonly<Record<string, string | undefined>>;\n}\n\nexport interface StackContext {\n\treadonly manifest: ManifestEnvelope;\n\treadonly manifestPath: string;\n\treadonly endpointNames: ReadonlyArray<string>;\n\treadonly manifestEndpointKeys: ReadonlyArray<string>;\n\treadonly endpoint: (endpointNameOrAlias: string) => string;\n\treadonly endpointMaybe: (endpointNameOrAlias: string) => string | null;\n\treadonly endpointEntry: (endpointNameOrAlias: string) => EndpointEntry;\n}\n\nexport interface ResolvedEndpoint {\n\treadonly url: string;\n\treadonly source: 'manifest' | 'conventional';\n\treadonly endpointKey: string;\n\treadonly endpointName: string;\n}\n\n// Endpoint aliases + default port live in `runtime/conventional-routes.ts`\n// so vitest / Playwright / any future build integration share one table.\n// Playwright contributes nothing of its own here — every per-endpoint\n// fact is substrate-supplied.\n\n/** Resolve a user-typed endpoint name or alias to the canonical\n * endpoint name the manifest stores. Delegates to the canonical\n * alias resolver in `runtime/conventional-routes.ts` so vitest and\n * Playwright share one alias table. */\nexport const playwrightEndpointNameFor = (endpointNameOrAlias: string): string =>\n\tresolveBuiltInEndpointAlias(endpointNameOrAlias);\n\nconst endpointRegistryFromEnvelope = (envelope: ManifestEnvelope): EndpointRegistry => {\n\tconst entries: RuntimeResolvedEndpoint[] = [];\n\tfor (const raw of Object.values(envelope.endpoints)) {\n\t\tentries.push({\n\t\t\tname: raw.name,\n\t\t\turl: raw.url,\n\t\t\tdisplayUrl: raw.displayUrl,\n\t\t\twireProtocol: raw.wireProtocol,\n\t\t\tpluginKey: raw.pluginKey,\n\t\t\tendpointKey: raw.endpointKey,\n\t\t});\n\t}\n\treturn new EndpointRegistry(entries);\n};\n\n// -----------------------------------------------------------------------------\n// Discovery\n// -----------------------------------------------------------------------------\n\nconst buildRuntimeDiscoverOpts = (\n\toptions: ResolveStackContextOptions,\n): DiscoverManifestPathOptions => {\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\t// Shared ladder: option > DEVSTACK_RUNTIME_ROOT > DEVSTACK_STATE_DIR\n\t// > '.devstack'. This surface previously read only DEVSTACK_STATE_DIR\n\t// and silently ignored DEVSTACK_RUNTIME_ROOT — routing through\n\t// `resolveDiscoveryEnv` aligns it with the vitest + runtime surfaces.\n\tconst { stack, stateDir } = resolveDiscoveryEnv(env, {\n\t\t...(options.stack !== undefined ? { stack: options.stack } : {}),\n\t\t...(options.stateDir !== undefined ? { stateDir: options.stateDir } : {}),\n\t});\n\treturn {\n\t\tenv,\n\t\tstack,\n\t\tstateDir,\n\t\t...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n\t\t...(options.manifestPath !== undefined ? { override: options.manifestPath } : {}),\n\t};\n};\n\n/**\n * Find the stack-scoped manifest by walking up from `cwd` looking for\n * `.devstack/stacks/<stack>/manifest.json`. Returns the absolute path\n * + the list of paths probed, or `null` on miss.\n */\nexport const discoverManifestPath = (\n\toptions: ResolveStackContextOptions = {},\n): { readonly path: string; readonly searched: ReadonlyArray<string> } | null => {\n\tconst path = runtimeDiscoverManifestPath(buildRuntimeDiscoverOpts(options));\n\tif (path === undefined) return null;\n\t// Runtime resolver doesn't surface intermediate probe paths today.\n\t// We expose the resolved path in the `searched` array so the\n\t// PlaywrightManifestDiscoveryError can still cite at least one\n\t// concrete path.\n\treturn { path, searched: [path] };\n};\n\n// -----------------------------------------------------------------------------\n// Synchronous read + decode\n// -----------------------------------------------------------------------------\n\n/**\n * Synchronously read + decode the manifest at `manifestPath`. Throws\n * `PlaywrightManifestShapeError` on JSON-parse or schema-decode\n * failure, or version mismatch. Used by callers that already know\n * the path (preset's webServer.url resolution + global-setup).\n */\nexport const readManifestSync = (manifestPath: string): ManifestEnvelope => {\n\ttry {\n\t\treturn manifestEnvelopeFromStackContext(readStackContextRuntime({ manifestPath }));\n\t} catch (cause) {\n\t\tif (cause instanceof ManifestShapeError) {\n\t\t\tthrow new PlaywrightManifestShapeError({\n\t\t\t\tmessage:\n\t\t\t\t\tcause.phase === 'version'\n\t\t\t\t\t\t? `manifest at ${manifestPath} version mismatch: ${cause.message}`\n\t\t\t\t\t\t: `manifest at ${manifestPath} does not match the envelope schema`,\n\t\t\t\tmanifestPath,\n\t\t\t\tphase: cause.phase === 'version' ? 'version-mismatch' : 'shape',\n\t\t\t\trecoveryHint:\n\t\t\t\t\tcause.phase === 'version'\n\t\t\t\t\t\t? `Re-run \\`devstack up\\` to write a manifest at the current version, ` +\n\t\t\t\t\t\t\t`or upgrade @mysten-incubation/devstack to a build-integration ` +\n\t\t\t\t\t\t\t`that understands the new envelope.`\n\t\t\t\t\t\t: `Delete \\`${manifestPath}\\` and run \\`devstack up\\`. If the error ` +\n\t\t\t\t\t\t\t`persists, the build-integration is older than the supervisor.`,\n\t\t\t\tcause,\n\t\t\t});\n\t\t}\n\t\tif (cause instanceof ManifestDiscoveryError) {\n\t\t\t// A discovery error (missing file at a known path) is NOT a\n\t\t\t// shape error — surface the typed discovery tag so callers\n\t\t\t// can `catchTag` the two failure modes independently.\n\t\t\tthrow new PlaywrightManifestDiscoveryError({\n\t\t\t\tmessage:\n\t\t\t\t\tcause.message !== ''\n\t\t\t\t\t\t? cause.message\n\t\t\t\t\t\t: `manifest at ${manifestPath} could not be read`,\n\t\t\t\tsearchedPaths: cause.path !== undefined ? [cause.path] : [manifestPath],\n\t\t\t\trecoveryHint:\n\t\t\t\t\t`Confirm the file exists and is readable. Run \\`devstack up\\` to ` +\n\t\t\t\t\t`regenerate it if the supervisor was interrupted mid-write.`,\n\t\t\t});\n\t\t}\n\t\tthrow cause;\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Conventional URL fallback\n// -----------------------------------------------------------------------------\n\n/**\n * Cold-start URL fallback for endpoints with a conventional host\n * pattern. Playwright config-load runs BEFORE the supervisor writes\n * the manifest; the preset MUST be able to resolve a `baseURL`\n * without a manifest read.\n *\n * The route table shape matches `runtime/coldStartUrl`; Playwright\n * only supplies its conventional endpoint hints while the shared\n * runtime helper owns host formatting.\n */\nexport const conventionalUrlFor = (\n\tendpointKey: string,\n\topts: {\n\t\treadonly stack?: string;\n\t\treadonly hostSuffix?: string;\n\t\treadonly port?: number;\n\t\treadonly app?: string;\n\t\treadonly cwd?: string;\n\t\treadonly env?: Readonly<Record<string, string | undefined>>;\n\t} = {},\n): string | null => {\n\tconst stack = opts.stack ?? 'main';\n\tconst env = opts.env ?? (process.env as Record<string, string | undefined>);\n\tconst envPort = Number.parseInt(env[PLAYWRIGHT_ENV.ROUTER_PORT] ?? '', 10);\n\tconst resolvedPort =\n\t\topts.port ??\n\t\t(Number.isFinite(envPort) && envPort > 0 ? envPort : undefined) ??\n\t\tDEFAULT_ROUTER_ENTRYPOINT_PORT;\n\n\tif (!Number.isFinite(resolvedPort) || resolvedPort <= 0) {\n\t\treturn null;\n\t}\n\n\tconst routes = builtInConventionalRoutes(resolvedPort);\n\tif (!routes.has(endpointKey)) return null;\n\n\treturn runtimeColdStartUrl(endpointKey, {\n\t\troutes,\n\t\tstack,\n\t\t...(opts.app !== undefined ? { app: opts.app } : {}),\n\t\t...(opts.cwd !== undefined ? { cwd: opts.cwd } : {}),\n\t\t...(opts.hostSuffix !== undefined ? { hostSuffix: opts.hostSuffix } : {}),\n\t\t// Thread the caller env bag so `runtimeColdStartUrl` resolves\n\t\t// `DEVSTACK_STACK` / `DEVSTACK_APP` from the test-injected\n\t\t// fixture rather than silently falling back to `process.env`.\n\t\t...(opts.env !== undefined ? { env: opts.env } : {}),\n\t});\n};\n\n// -----------------------------------------------------------------------------\n// Public readers\n// -----------------------------------------------------------------------------\n\n/**\n * Synchronously resolve the full stack context. Throws on missing\n * manifest (no cold-start fallback here — caller wants the typed\n * envelope, not a guessed URL).\n */\nexport const readStackContext = (options: ResolveStackContextOptions = {}): StackContext => {\n\ttry {\n\t\tconst ctx = readStackContextRuntime(buildRuntimeDiscoverOpts(options));\n\t\treturn projectFromRuntime(ctx);\n\t} catch (err) {\n\t\tif (err instanceof ManifestDiscoveryError) {\n\t\t\tthrow new PlaywrightManifestDiscoveryError({\n\t\t\t\tmessage: 'no manifest found along walk-up path or env override',\n\t\t\t\tsearchedPaths: err.path !== undefined ? [err.path] : [],\n\t\t\t\trecoveryHint:\n\t\t\t\t\t`Run \\`devstack up\\` from your example app's directory to write ` +\n\t\t\t\t\t`the manifest, or set DEVSTACK_MANIFEST_PATH to an explicit path.`,\n\t\t\t});\n\t\t}\n\t\tif (err instanceof ManifestShapeError) {\n\t\t\tthrow new PlaywrightManifestShapeError({\n\t\t\t\tmessage: err.message,\n\t\t\t\tmanifestPath: err.path,\n\t\t\t\tphase: err.phase === 'version' ? 'version-mismatch' : err.phase,\n\t\t\t\trecoveryHint: `Delete \\`${err.path}\\` and run \\`devstack up\\` to regenerate.`,\n\t\t\t\tcause: err,\n\t\t\t});\n\t\t}\n\t\tthrow err;\n\t}\n};\n\nconst projectFromRuntime = (ctx: RuntimeStackContext): StackContext => {\n\tconst envelope = manifestEnvelopeFromStackContext(ctx);\n\treturn makeStackContext(envelope, ctx.manifestPath);\n};\n\n/** Project an in-memory envelope (test fixtures use this) into the\n * same accessor shape as the on-disk read. */\nexport const makeStackContext = (\n\tenvelope: ManifestEnvelope,\n\tmanifestPath: string,\n): StackContext => {\n\tconst endpoints = endpointRegistryFromEnvelope(envelope);\n\tconst manifestEndpointKeys = Object.keys(envelope.endpoints).sort();\n\tconst endpointNames = endpoints.names();\n\tconst notFound = (endpointKey: string, endpointName: string): PlaywrightEndpointNotFoundError =>\n\t\tnew PlaywrightEndpointNotFoundError({\n\t\t\tmessage:\n\t\t\t\t`no endpoint \\`${endpointKey}\\` (resolved endpoint name \\`${endpointName}\\`) ` +\n\t\t\t\t`in manifest at ${manifestPath}`,\n\t\t\tendpointKey,\n\t\t\tendpointName,\n\t\t\tavailable: endpointNames,\n\t\t\tmanifestKeys: manifestEndpointKeys,\n\t\t\trecoveryHint:\n\t\t\t\t`Available endpoint names: ${endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t`Raw manifest keys: ${manifestEndpointKeys.join(', ') || '(none)'}. ` +\n\t\t\t\t`Check the plugin emitting this endpoint is present in your stack, ` +\n\t\t\t\t`or check for a typo in the endpoint name.`,\n\t\t});\n\tconst findEndpoint = (endpointNameOrAlias: string): RuntimeResolvedEndpoint | undefined =>\n\t\tendpoints.byName(playwrightEndpointNameFor(endpointNameOrAlias));\n\tconst rawEntryFor = (resolved: RuntimeResolvedEndpoint): EndpointEntry => {\n\t\tconst byMapKey = envelope.endpoints[resolved.endpointKey];\n\t\tif (byMapKey !== undefined) return byMapKey;\n\t\tconst byEntryKey = Object.values(envelope.endpoints).find(\n\t\t\t(entry) => entry.endpointKey === resolved.endpointKey,\n\t\t);\n\t\tif (byEntryKey !== undefined) return byEntryKey;\n\t\treturn {\n\t\t\tname: resolved.name,\n\t\t\turl: resolved.url,\n\t\t\tdisplayUrl: resolved.displayUrl,\n\t\t\twireProtocol: resolved.wireProtocol,\n\t\t\tpluginKey: resolved.pluginKey,\n\t\t\tendpointKey: resolved.endpointKey,\n\t\t};\n\t};\n\n\treturn {\n\t\tmanifest: envelope,\n\t\tmanifestPath,\n\t\tendpointNames,\n\t\tmanifestEndpointKeys,\n\t\tendpoint: (endpointNameOrAlias: string): string => {\n\t\t\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\t\t\tconst entry = findEndpoint(endpointNameOrAlias);\n\t\t\tif (entry === undefined) {\n\t\t\t\tthrow notFound(endpointNameOrAlias, endpointName);\n\t\t\t}\n\t\t\treturn entry.url;\n\t\t},\n\t\tendpointMaybe: (endpointNameOrAlias: string): string | null =>\n\t\t\tfindEndpoint(endpointNameOrAlias)?.url ?? null,\n\t\tendpointEntry: (endpointNameOrAlias: string): EndpointEntry => {\n\t\t\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\t\t\tconst entry = findEndpoint(endpointNameOrAlias);\n\t\t\tif (entry === undefined) {\n\t\t\t\tthrow notFound(endpointNameOrAlias, endpointName);\n\t\t\t}\n\t\t\treturn rawEntryFor(entry);\n\t\t},\n\t};\n};\n\n/**\n * Resolve a URL for a single endpoint with cold-start fallback to the\n * conventional URL when the manifest is absent. Throws when both the\n * manifest and the conventional table miss.\n */\nexport const resolveEndpointUrl = (\n\tendpointNameOrAlias: string,\n\toptions: ResolveStackContextOptions & {\n\t\treadonly port?: number;\n\t\treadonly hostSuffix?: string;\n\t} = {},\n): ResolvedEndpoint => {\n\tconst endpointName = playwrightEndpointNameFor(endpointNameOrAlias);\n\tlet ctx: StackContext | undefined;\n\ttry {\n\t\tctx = readStackContext(options);\n\t} catch (err) {\n\t\tif (!(err instanceof PlaywrightManifestDiscoveryError)) throw err;\n\t}\n\tif (ctx !== undefined) {\n\t\tconst entry = ctx.endpointEntry(endpointNameOrAlias);\n\t\treturn { url: entry.url, source: 'manifest', endpointKey: entry.endpointKey, endpointName };\n\t}\n\n\tconst env = options.env ?? (process.env as Record<string, string | undefined>);\n\tconst stack = options.stack ?? env[PLAYWRIGHT_ENV.STACK] ?? 'main';\n\tconst fallback = conventionalUrlFor(endpointNameOrAlias, {\n\t\tstack,\n\t\t...(options.cwd !== undefined ? { cwd: options.cwd } : {}),\n\t\t...(options.hostSuffix !== undefined\n\t\t\t? { hostSuffix: options.hostSuffix }\n\t\t\t: env[PLAYWRIGHT_ENV.ROUTER_HOST_SUFFIX] !== undefined\n\t\t\t\t? { hostSuffix: env[PLAYWRIGHT_ENV.ROUTER_HOST_SUFFIX] }\n\t\t\t\t: {}),\n\t\t...(options.port !== undefined ? { port: options.port } : {}),\n\t\t...(options.env !== undefined ? { env: options.env } : {}),\n\t});\n\tif (fallback !== null) {\n\t\treturn {\n\t\t\turl: fallback,\n\t\t\tsource: 'conventional',\n\t\t\tendpointKey: endpointNameOrAlias,\n\t\t\tendpointName,\n\t\t};\n\t}\n\n\tthrow new PlaywrightManifestDiscoveryError({\n\t\tmessage:\n\t\t\t`no manifest found and no conventional fallback for endpoint ` +\n\t\t\t`\\`${endpointNameOrAlias}\\` (resolved endpoint name \\`${endpointName}\\`)`,\n\t\tsearchedPaths: [],\n\t\tendpointKey: endpointNameOrAlias,\n\t\trecoveryHint:\n\t\t\t`Run \\`devstack up\\` to materialize the manifest before invoking ` +\n\t\t\t`playwright, or pass an explicit \\`baseURL\\`.`,\n\t});\n};\n"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { WALLET_ENDPOINT_KEY } from "../../contracts/wallet-protocol.mjs";
1
2
  import { ResolveStackContextOptions, StackContext } from "./stack-context.mjs";
2
3
 
3
4
  //#region src/build-integrations/playwright/wallet-context.d.ts
@@ -5,11 +6,6 @@ import { ResolveStackContextOptions, StackContext } from "./stack-context.mjs";
5
6
  interface PlaywrightPageLike {
6
7
  readonly evaluate: <T>(fn: (arg: unknown) => T, arg?: unknown) => Promise<T>;
7
8
  }
8
- /** Public alias for the dev-wallet endpoint. The manifest stores raw
9
- * keys as `${pluginKey}:${endpointName}` and the actual endpoint name
10
- * is `wallet-app`; `readStackContext(...).endpointMaybe('wallet')`
11
- * maps this alias through the Playwright boundary. */
12
- declare const WALLET_ENDPOINT_KEY: "wallet";
13
9
  interface WalletAdapterOptions extends ResolveStackContextOptions {
14
10
  /** Override the resolved wallet URL. Useful for tests targeting a
15
11
  * remote / non-default stack. */
@@ -26,12 +22,13 @@ interface WalletAdapter {
26
22
  readonly walletUrl: string;
27
23
  /** List dev-wallet account names + addresses. */
28
24
  readonly listAccounts: () => Promise<ReadonlyArray<DevAccount>>;
29
- /** Switch the active dev-wallet account by name. Posts to the
30
- * wallet's `switch-account` endpoint. */
31
- readonly switchAccount: (accountName: string) => Promise<void>;
32
25
  /** Sign + execute a serialized transaction as `accountName`.
33
26
  * `txBytes` is the canonical Sui tx bytes (base64). Returns the
34
- * wallet's response body (typed `unknown` — caller decodes). */
27
+ * wallet's response body (typed `unknown` — caller decodes).
28
+ *
29
+ * NOTE on account switching: the HTTP wallet server has no
30
+ * `/accounts/switch` endpoint — active-account selection is owned
31
+ * by the dapp-kit slot. Use `selectAccount` / `connectAs` below. */
35
32
  readonly signTransaction: (input: SignTxRequest) => Promise<SignTxResponse>;
36
33
  /** Raw POST escape hatch. Used by the helpers above and by tests
37
34
  * that need a wallet-endpoint not in the typed surface. */
@@ -83,5 +80,5 @@ declare const selectAccount: (page: PlaywrightPageLike, accountName: string) =>
83
80
  /** Test-side accessor for the full manifest (already decoded). */
84
81
  declare const loadStackManifest: (options?: ResolveStackContextOptions) => StackContext;
85
82
  //#endregion
86
- export { DAPP_KIT_SLOT, DevAccount, PlaywrightPageLike, SignTxRequest, SignTxResponse, WALLET_ENDPOINT_KEY, WalletAdapter, WalletAdapterOptions, connectAs, createWalletAdapter, loadStackManifest, selectAccount };
83
+ export { DAPP_KIT_SLOT, DevAccount, PlaywrightPageLike, SignTxRequest, SignTxResponse, WalletAdapter, WalletAdapterOptions, connectAs, createWalletAdapter, loadStackManifest, selectAccount };
87
84
  //# sourceMappingURL=wallet-context.d.mts.map
@@ -1,13 +1,10 @@
1
+ import { WALLET_ENDPOINT_KEY, WalletHttpPath } from "../../contracts/wallet-protocol.mjs";
2
+ import "../runtime/wallet-paths.mjs";
1
3
  import { PlaywrightWalletAdapterError } from "./errors.mjs";
2
4
  import { readStackContext } from "./stack-context.mjs";
3
5
  import { readStashedFixture } from "./global-setup.mjs";
4
6
  import { DAPP_KIT_SLOT_KEY } from "../runtime/dapp-kit-slot.mjs";
5
7
  //#region src/build-integrations/playwright/wallet-context.ts
6
- /** Public alias for the dev-wallet endpoint. The manifest stores raw
7
- * keys as `${pluginKey}:${endpointName}` and the actual endpoint name
8
- * is `wallet-app`; `readStackContext(...).endpointMaybe('wallet')`
9
- * maps this alias through the Playwright boundary. */
10
- const WALLET_ENDPOINT_KEY = "wallet";
11
8
  /**
12
9
  * Resolve the dev-wallet URL. Precedence:
13
10
  * 1. `options.walletUrl` (explicit override).
@@ -44,7 +41,7 @@ const resolveWalletUrl = (options) => {
44
41
  const createWalletAdapter = (options = {}) => {
45
42
  const walletUrl = resolveWalletUrl(options).replace(/\/$/, "");
46
43
  const fetchImpl = options.fetch ?? globalThis.fetch;
47
- const timeoutMs = options.timeoutMs ?? 5e3;
44
+ const timeoutMs = options.timeoutMs ?? 3e4;
48
45
  const request = async (path, body) => {
49
46
  const url = `${walletUrl}${path.startsWith("/") ? path : `/${path}`}`;
50
47
  const controller = new AbortController();
@@ -77,11 +74,8 @@ const createWalletAdapter = (options = {}) => {
77
74
  };
78
75
  return {
79
76
  walletUrl,
80
- listAccounts: () => request("/accounts"),
81
- switchAccount: async (accountName) => {
82
- await request("/accounts/switch", { accountName });
83
- },
84
- signTransaction: (input) => request("/sign-transaction", {
77
+ listAccounts: () => request(WalletHttpPath.ACCOUNTS),
78
+ signTransaction: (input) => request(WalletHttpPath.SIGN_TRANSACTION, {
85
79
  accountName: input.accountName,
86
80
  txBytesBase64: input.txBytesBase64,
87
81
  label: input.label
@@ -137,12 +131,13 @@ const selectAccount = async (page, accountName) => {
137
131
  }, accountName);
138
132
  if (!result.ok) throw new PlaywrightWalletAdapterError({
139
133
  message: `selectAccount("${accountName}") failed: ${result.reason ?? "unknown"}. Confirm \`globalThis.${DAPP_KIT_SLOT}\` is populated by the app's dapp-kit module at boot.`,
140
- operation: "switch-account"
134
+ operation: "switch-account",
135
+ cause: result.reason
141
136
  });
142
137
  };
143
138
  /** Test-side accessor for the full manifest (already decoded). */
144
139
  const loadStackManifest = (options = {}) => readStackContext(options);
145
140
  //#endregion
146
- export { DAPP_KIT_SLOT, WALLET_ENDPOINT_KEY, connectAs, createWalletAdapter, loadStackManifest, selectAccount };
141
+ export { DAPP_KIT_SLOT, connectAs, createWalletAdapter, loadStackManifest, selectAccount };
147
142
 
148
143
  //# sourceMappingURL=wallet-context.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"wallet-context.mjs","names":[],"sources":["../../../src/build-integrations/playwright/wallet-context.ts"],"sourcesContent":["// Wallet-context test helpers.\n//\n// Architecture (distilled/23-build-integrations.md § Playwright /\n// \"What it produces\"):\n//\n// In-spec helpers (`connectAs`, `selectAccount`) and artifact\n// loaders (`loadStackManifest`, `loadStackKeypair`).\n//\n// And (per the user task brief): tests sign txs via the wallet's HTTP\n// API rather than driving the browser's wallet-UI flow. That is the\n// load-bearing wallet-context contract: a tiny typed HTTP client over\n// the dev wallet's endpoint exposed in the manifest.\n//\n// Discipline:\n// - This module performs NO browser interaction. The `page` arg in\n// `connectAs` is the Playwright `Page` (kept structural — we do\n// not import `@playwright/test`), but the helpers here only use\n// it to expose the dev-wallet selection / account-switch flow\n// through `evaluate`. The actual key handling stays server-side\n// in the wallet plugin.\n// - HTTP calls go through `fetch`. We do NOT pull in `@mysten/sui`\n// here — txs are constructed by tests, serialized, and POSTed\n// to the wallet for signing. The wallet plugin is the\n// authoritative key holder.\n// - Account-switch via the global slot (`globalThis.__devstackDAppKit__`)\n// for dapp-kit-driven in-browser context; HTTP wallet helpers\n// are the spec-level lower-friction path.\n\nimport {\n\treadStackContext,\n\ttype ResolveStackContextOptions,\n\ttype StackContext,\n} from './stack-context.ts';\nimport { readStashedFixture } from './global-setup.ts';\nimport { PlaywrightWalletAdapterError } from './errors.ts';\nimport { DAPP_KIT_SLOT_KEY, type DAppKitSlot } from '../runtime/dapp-kit-slot.ts';\n\n// -----------------------------------------------------------------------------\n// Structural Playwright `Page` shape — we keep `@playwright/test` an\n// optional peer.\n// -----------------------------------------------------------------------------\n\n/** Subset of `Page` we use. */\nexport interface PlaywrightPageLike {\n\treadonly evaluate: <T>(fn: (arg: unknown) => T, arg?: unknown) => Promise<T>;\n}\n\n// -----------------------------------------------------------------------------\n// Wallet adapter — HTTP client targeting the wallet plugin's endpoint\n// -----------------------------------------------------------------------------\n\n/** Public alias for the dev-wallet endpoint. The manifest stores raw\n * keys as `${pluginKey}:${endpointName}` and the actual endpoint name\n * is `wallet-app`; `readStackContext(...).endpointMaybe('wallet')`\n * maps this alias through the Playwright boundary. */\nexport const WALLET_ENDPOINT_KEY = 'wallet' as const;\n\nexport interface WalletAdapterOptions extends ResolveStackContextOptions {\n\t/** Override the resolved wallet URL. Useful for tests targeting a\n\t * remote / non-default stack. */\n\treadonly walletUrl?: string;\n\t/** Custom `fetch` for tests. Defaults to `globalThis.fetch`. */\n\treadonly fetch?: typeof fetch;\n\t/** Per-request timeout in ms. Default: 5_000. */\n\treadonly timeoutMs?: number;\n}\n\n/** Public shape of the wallet adapter — typed by-key methods plus the\n * raw `request` escape hatch. */\nexport interface WalletAdapter {\n\t/** Resolved base URL of the wallet plugin. */\n\treadonly walletUrl: string;\n\n\t/** List dev-wallet account names + addresses. */\n\treadonly listAccounts: () => Promise<ReadonlyArray<DevAccount>>;\n\n\t/** Switch the active dev-wallet account by name. Posts to the\n\t * wallet's `switch-account` endpoint. */\n\treadonly switchAccount: (accountName: string) => Promise<void>;\n\n\t/** Sign + execute a serialized transaction as `accountName`.\n\t * `txBytes` is the canonical Sui tx bytes (base64). Returns the\n\t * wallet's response body (typed `unknown` — caller decodes). */\n\treadonly signTransaction: (input: SignTxRequest) => Promise<SignTxResponse>;\n\n\t/** Raw POST escape hatch. Used by the helpers above and by tests\n\t * that need a wallet-endpoint not in the typed surface. */\n\treadonly request: <T>(path: string, body?: Record<string, unknown>) => Promise<T>;\n}\n\nexport interface DevAccount {\n\treadonly name: string;\n\treadonly address: string;\n}\n\nexport interface SignTxRequest {\n\treadonly accountName: string;\n\t/** Canonical Sui tx bytes, base64-encoded. */\n\treadonly txBytesBase64: string;\n\t/** Optional caller-supplied label for correlated trace output. */\n\treadonly label?: string;\n}\n\nexport interface SignTxResponse {\n\treadonly digest: string;\n\treadonly signature: string;\n\t/** Raw response payload (wallet-plugin-versioned shape). */\n\treadonly raw: unknown;\n}\n\n// -----------------------------------------------------------------------------\n// Resolver: locate the wallet URL via fixture > manifest > error\n// -----------------------------------------------------------------------------\n\n/**\n * Resolve the dev-wallet URL. Precedence:\n * 1. `options.walletUrl` (explicit override).\n * 2. The fixture stashed by `globalSetup` on `globalThis`.\n * 3. A fresh manifest read.\n *\n * Throws `PlaywrightWalletAdapterError` when every path misses. */\nconst resolveWalletUrl = (options: WalletAdapterOptions): string => {\n\tif (options.walletUrl !== undefined) return options.walletUrl;\n\n\tconst fixture = readStashedFixture();\n\tif (fixture !== null && fixture.walletEndpoint !== null) {\n\t\treturn fixture.walletEndpoint;\n\t}\n\n\tlet ctx: StackContext;\n\ttry {\n\t\tctx = readStackContext(options);\n\t} catch (cause) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`unable to resolve dev-wallet URL — no globalSetup fixture and ` + `manifest read failed`,\n\t\t\toperation: 'fetch',\n\t\t\tcause,\n\t\t});\n\t}\n\tconst walletUrl = ctx.endpointMaybe(WALLET_ENDPOINT_KEY);\n\tif (walletUrl === null) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`manifest has no \\`${WALLET_ENDPOINT_KEY}\\` endpoint (alias for ` +\n\t\t\t\t`\\`wallet-app\\`) — is the dev-wallet plugin present in your stack? ` +\n\t\t\t\t`Available endpoint names: ${ctx.endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t`Raw manifest keys: ${ctx.manifestEndpointKeys.join(', ') || '(none)'}.`,\n\t\t\toperation: 'fetch',\n\t\t});\n\t}\n\treturn walletUrl;\n};\n\n// -----------------------------------------------------------------------------\n// Factory\n// -----------------------------------------------------------------------------\n\n/**\n * Build a wallet adapter. Most tests call this once per `test`\n * fixture; the resolution is sync (a hash-lookup on the\n * fixture / manifest) so this is cheap.\n */\nexport const createWalletAdapter = (options: WalletAdapterOptions = {}): WalletAdapter => {\n\tconst walletUrl = resolveWalletUrl(options).replace(/\\/$/, '');\n\tconst fetchImpl = options.fetch ?? globalThis.fetch;\n\tconst timeoutMs = options.timeoutMs ?? 5_000;\n\n\tconst request = async <T>(path: string, body?: Record<string, unknown>): Promise<T> => {\n\t\tconst url = `${walletUrl}${path.startsWith('/') ? path : `/${path}`}`;\n\t\tconst controller = new AbortController();\n\t\tconst handle = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst res = await fetchImpl(url, {\n\t\t\t\tmethod: body === undefined ? 'GET' : 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: body === undefined ? undefined : JSON.stringify(body),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tif (!res.ok) {\n\t\t\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\t\t\tmessage: `wallet request ${path} failed: HTTP ${res.status}`,\n\t\t\t\t\toperation: 'fetch',\n\t\t\t\t\turl,\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn (await res.json()) as T;\n\t\t} catch (cause) {\n\t\t\tif (cause instanceof PlaywrightWalletAdapterError) throw cause;\n\t\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\t\tmessage: `wallet request ${path} threw`,\n\t\t\t\toperation: 'fetch',\n\t\t\t\turl,\n\t\t\t\tcause,\n\t\t\t});\n\t\t} finally {\n\t\t\tclearTimeout(handle);\n\t\t}\n\t};\n\n\treturn {\n\t\twalletUrl,\n\t\tlistAccounts: () => request<ReadonlyArray<DevAccount>>('/accounts'),\n\t\tswitchAccount: async (accountName: string) => {\n\t\t\tawait request<{ readonly ok: true }>('/accounts/switch', { accountName });\n\t\t},\n\t\tsignTransaction: (input: SignTxRequest) =>\n\t\t\trequest<SignTxResponse>('/sign-transaction', {\n\t\t\t\taccountName: input.accountName,\n\t\t\t\ttxBytesBase64: input.txBytesBase64,\n\t\t\t\tlabel: input.label,\n\t\t\t}),\n\t\trequest,\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// In-spec helpers — `connectAs` and `selectAccount`\n// -----------------------------------------------------------------------------\n\n/** Slot name owned by the app's `dapp-kit.ts`. The build integration\n * reads it; the app populates it. Re-exported from `runtime/`'s\n * canonical contract — kept here as a name alias for the\n * in-spec-helpers' import path. */\nexport const DAPP_KIT_SLOT = DAPP_KIT_SLOT_KEY;\n\n/**\n * Connect/switch the app's active dev-wallet account through the dapp-kit\n * slot the app populates at boot.\n *\n * This intentionally avoids driving the wallet UI. The app-side slot\n * implementation still goes through dapp-kit + wallet-standard, so pairing,\n * origin, and account discovery failures surface as real browser failures.\n */\nexport const connectAs = async (page: PlaywrightPageLike, accountName: string): Promise<void> => {\n\ttry {\n\t\tawait selectAccount(page, accountName);\n\t} catch (cause) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage: `connectAs(\"${accountName}\") failed`,\n\t\t\toperation: 'switch-account',\n\t\t\tcause,\n\t\t});\n\t}\n};\n\n/**\n * Switch the dev-wallet's active account by routing through the\n * dapp-kit global slot the app populates at module init. Strictly\n * faster + less flaky than clicking the wallet's UI.\n */\nexport const selectAccount = async (\n\tpage: PlaywrightPageLike,\n\taccountName: string,\n): Promise<void> => {\n\t// `evaluate`'s closure is serialized into the browser; the slot\n\t// shape (`DAppKitSlot`) lives in `runtime/dapp-kit-slot.ts` — the\n\t// in-browser closure can't import it, but the global-augmentation\n\t// `globalThis.__devstackDAppKit__` is the typed contract both sides\n\t// rely on.\n\tconst result = await page.evaluate(async (name): Promise<{ ok: boolean; reason?: string }> => {\n\t\tconst slot = (globalThis as { __devstackDAppKit__?: DAppKitSlot }).__devstackDAppKit__;\n\t\tif (slot === undefined || slot.selectAccount === undefined) {\n\t\t\treturn { ok: false, reason: 'slot-not-populated' };\n\t\t}\n\t\ttry {\n\t\t\tawait slot.selectAccount(name as string);\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}, accountName);\n\tif (!result.ok) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`selectAccount(\"${accountName}\") failed: ${result.reason ?? 'unknown'}. ` +\n\t\t\t\t`Confirm \\`globalThis.${DAPP_KIT_SLOT}\\` is populated by the app's ` +\n\t\t\t\t`dapp-kit module at boot.`,\n\t\t\toperation: 'switch-account',\n\t\t});\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Artifact loaders\n// -----------------------------------------------------------------------------\n\n/** Test-side accessor for the full manifest (already decoded). */\nexport const loadStackManifest = (options: ResolveStackContextOptions = {}): StackContext =>\n\treadStackContext(options);\n"],"mappings":"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"}
1
+ {"version":3,"file":"wallet-context.mjs","names":[],"sources":["../../../src/build-integrations/playwright/wallet-context.ts"],"sourcesContent":["// Wallet-context test helpers.\n//\n// Architecture (distilled/23-build-integrations.md § Playwright /\n// \"What it produces\"):\n//\n// In-spec helpers (`connectAs`, `selectAccount`) and the\n// `loadStackManifest` artifact loader. (`loadStackKeypair` is not\n// implemented — keys never leave the wallet plugin; tests sign via\n// the wallet's HTTP API.)\n//\n// And (per the user task brief): tests sign txs via the wallet's HTTP\n// API rather than driving the browser's wallet-UI flow. That is the\n// load-bearing wallet-context contract: a tiny typed HTTP client over\n// the dev wallet's endpoint exposed in the manifest.\n//\n// Discipline:\n// - This module performs NO browser interaction. The `page` arg in\n// `connectAs` is the Playwright `Page` (kept structural — we do\n// not import `@playwright/test`), but the helpers here only use\n// it to expose the dev-wallet selection / account-switch flow\n// through `evaluate`. The actual key handling stays server-side\n// in the wallet plugin.\n// - HTTP calls go through `fetch`. We do NOT pull in `@mysten/sui`\n// here — txs are constructed by tests, serialized, and POSTed\n// to the wallet for signing. The wallet plugin is the\n// authoritative key holder.\n// - Account-switch via the global slot (`globalThis.__devstackDAppKit__`)\n// for dapp-kit-driven in-browser context; HTTP wallet helpers\n// are the spec-level lower-friction path.\n\nimport {\n\treadStackContext,\n\ttype ResolveStackContextOptions,\n\ttype StackContext,\n} from './stack-context.ts';\nimport { readStashedFixture } from './global-setup.ts';\nimport { PlaywrightWalletAdapterError } from './errors.ts';\nimport { DAPP_KIT_SLOT_KEY, type DAppKitSlot } from '../runtime/dapp-kit-slot.ts';\n// The wallet plugin owns the wire-protocol path constants AND the\n// canonical endpoint name. Both are surfaced through the L5 runtime\n// bridge so this adapter never reaches into L2 plugin code directly\n// (ARCHITECTURE.md § Layer table — L5 reads only the runtime bridge).\nimport { WalletHttpPath, WALLET_ENDPOINT_KEY } from '../runtime/wallet-paths.ts';\n\n// -----------------------------------------------------------------------------\n// Structural Playwright `Page` shape — we keep `@playwright/test` an\n// optional peer.\n// -----------------------------------------------------------------------------\n\n/** Subset of `Page` we use. */\nexport interface PlaywrightPageLike {\n\treadonly evaluate: <T>(fn: (arg: unknown) => T, arg?: unknown) => Promise<T>;\n}\n\n// -----------------------------------------------------------------------------\n// Wallet adapter — HTTP client targeting the wallet plugin's endpoint\n// -----------------------------------------------------------------------------\n\n// `WALLET_ENDPOINT_KEY` is the short form Playwright/vitest helpers look\n// up — the manifest stores the canonical endpoint name\n// (`WALLET_ENDPOINT_NAME` — `'wallet-app'`) but the substrate's alias\n// resolver folds the key to the canonical name. Re-exported from the L5\n// runtime bridge so the spelling + canonical pairing stay aligned with\n// the wallet plugin.\nexport { WALLET_ENDPOINT_KEY };\n\nexport interface WalletAdapterOptions extends ResolveStackContextOptions {\n\t/** Override the resolved wallet URL. Useful for tests targeting a\n\t * remote / non-default stack. */\n\treadonly walletUrl?: string;\n\t/** Custom `fetch` for tests. Defaults to `globalThis.fetch`. */\n\treadonly fetch?: typeof fetch;\n\t/** Per-request timeout in ms. Default: 5_000. */\n\treadonly timeoutMs?: number;\n}\n\n/** Public shape of the wallet adapter — typed by-key methods plus the\n * raw `request` escape hatch. */\nexport interface WalletAdapter {\n\t/** Resolved base URL of the wallet plugin. */\n\treadonly walletUrl: string;\n\n\t/** List dev-wallet account names + addresses. */\n\treadonly listAccounts: () => Promise<ReadonlyArray<DevAccount>>;\n\n\t/** Sign + execute a serialized transaction as `accountName`.\n\t * `txBytes` is the canonical Sui tx bytes (base64). Returns the\n\t * wallet's response body (typed `unknown` — caller decodes).\n\t *\n\t * NOTE on account switching: the HTTP wallet server has no\n\t * `/accounts/switch` endpoint — active-account selection is owned\n\t * by the dapp-kit slot. Use `selectAccount` / `connectAs` below. */\n\treadonly signTransaction: (input: SignTxRequest) => Promise<SignTxResponse>;\n\n\t/** Raw POST escape hatch. Used by the helpers above and by tests\n\t * that need a wallet-endpoint not in the typed surface. */\n\treadonly request: <T>(path: string, body?: Record<string, unknown>) => Promise<T>;\n}\n\nexport interface DevAccount {\n\treadonly name: string;\n\treadonly address: string;\n}\n\nexport interface SignTxRequest {\n\treadonly accountName: string;\n\t/** Canonical Sui tx bytes, base64-encoded. */\n\treadonly txBytesBase64: string;\n\t/** Optional caller-supplied label for correlated trace output. */\n\treadonly label?: string;\n}\n\nexport interface SignTxResponse {\n\treadonly digest: string;\n\treadonly signature: string;\n\t/** Raw response payload (wallet-plugin-versioned shape). */\n\treadonly raw: unknown;\n}\n\n// -----------------------------------------------------------------------------\n// Resolver: locate the wallet URL via fixture > manifest > error\n// -----------------------------------------------------------------------------\n\n/**\n * Resolve the dev-wallet URL. Precedence:\n * 1. `options.walletUrl` (explicit override).\n * 2. The fixture stashed by `globalSetup` on `globalThis`.\n * 3. A fresh manifest read.\n *\n * Throws `PlaywrightWalletAdapterError` when every path misses. */\nconst resolveWalletUrl = (options: WalletAdapterOptions): string => {\n\tif (options.walletUrl !== undefined) return options.walletUrl;\n\n\tconst fixture = readStashedFixture();\n\tif (fixture !== null && fixture.walletEndpoint !== null) {\n\t\treturn fixture.walletEndpoint;\n\t}\n\n\tlet ctx: StackContext;\n\ttry {\n\t\tctx = readStackContext(options);\n\t} catch (cause) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`unable to resolve dev-wallet URL — no globalSetup fixture and ` + `manifest read failed`,\n\t\t\toperation: 'fetch',\n\t\t\tcause,\n\t\t});\n\t}\n\tconst walletUrl = ctx.endpointMaybe(WALLET_ENDPOINT_KEY);\n\tif (walletUrl === null) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`manifest has no \\`${WALLET_ENDPOINT_KEY}\\` endpoint (alias for ` +\n\t\t\t\t`\\`wallet-app\\`) — is the dev-wallet plugin present in your stack? ` +\n\t\t\t\t`Available endpoint names: ${ctx.endpointNames.join(', ') || '(none)'}. ` +\n\t\t\t\t`Raw manifest keys: ${ctx.manifestEndpointKeys.join(', ') || '(none)'}.`,\n\t\t\toperation: 'fetch',\n\t\t});\n\t}\n\treturn walletUrl;\n};\n\n// -----------------------------------------------------------------------------\n// Factory\n// -----------------------------------------------------------------------------\n\n/**\n * Build a wallet adapter. Most tests call this once per `test`\n * fixture; the resolution is sync (a hash-lookup on the\n * fixture / manifest) so this is cheap.\n */\nexport const createWalletAdapter = (options: WalletAdapterOptions = {}): WalletAdapter => {\n\tconst walletUrl = resolveWalletUrl(options).replace(/\\/$/, '');\n\tconst fetchImpl = options.fetch ?? globalThis.fetch;\n\t// 30s default — Playwright's webServer cold-start (vite + first\n\t// devstack bring-up) routinely exceeds 5s under CI parallelism; the\n\t// shorter default surfaces as a spurious AbortError before the\n\t// wallet plugin has finished publishing its HTTP route. Callers can\n\t// still tighten via `options.timeoutMs` for hot-path assertions.\n\tconst timeoutMs = options.timeoutMs ?? 30_000;\n\n\tconst request = async <T>(path: string, body?: Record<string, unknown>): Promise<T> => {\n\t\tconst url = `${walletUrl}${path.startsWith('/') ? path : `/${path}`}`;\n\t\tconst controller = new AbortController();\n\t\tconst handle = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst res = await fetchImpl(url, {\n\t\t\t\tmethod: body === undefined ? 'GET' : 'POST',\n\t\t\t\theaders: { 'content-type': 'application/json' },\n\t\t\t\tbody: body === undefined ? undefined : JSON.stringify(body),\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tif (!res.ok) {\n\t\t\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\t\t\tmessage: `wallet request ${path} failed: HTTP ${res.status}`,\n\t\t\t\t\toperation: 'fetch',\n\t\t\t\t\turl,\n\t\t\t\t\tstatus: res.status,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn (await res.json()) as T;\n\t\t} catch (cause) {\n\t\t\tif (cause instanceof PlaywrightWalletAdapterError) throw cause;\n\t\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\t\tmessage: `wallet request ${path} threw`,\n\t\t\t\toperation: 'fetch',\n\t\t\t\turl,\n\t\t\t\tcause,\n\t\t\t});\n\t\t} finally {\n\t\t\tclearTimeout(handle);\n\t\t}\n\t};\n\n\treturn {\n\t\twalletUrl,\n\t\t// Paths come from the wallet plugin's canonical wire-protocol\n\t\t// module. Hard-coded literals here would silently 404 the moment\n\t\t// `WalletHttpPath` is reorganised, with no compile-time signal.\n\t\tlistAccounts: () => request<ReadonlyArray<DevAccount>>(WalletHttpPath.ACCOUNTS),\n\t\tsignTransaction: (input: SignTxRequest) =>\n\t\t\trequest<SignTxResponse>(WalletHttpPath.SIGN_TRANSACTION, {\n\t\t\t\taccountName: input.accountName,\n\t\t\t\ttxBytesBase64: input.txBytesBase64,\n\t\t\t\tlabel: input.label,\n\t\t\t}),\n\t\trequest,\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// In-spec helpers — `connectAs` and `selectAccount`\n// -----------------------------------------------------------------------------\n\n/** Slot name owned by the app's `dapp-kit.ts`. The build integration\n * reads it; the app populates it. Re-exported from `runtime/`'s\n * canonical contract — kept here as a name alias for the\n * in-spec-helpers' import path. */\nexport const DAPP_KIT_SLOT = DAPP_KIT_SLOT_KEY;\n\n/**\n * Connect/switch the app's active dev-wallet account through the dapp-kit\n * slot the app populates at boot.\n *\n * This intentionally avoids driving the wallet UI. The app-side slot\n * implementation still goes through dapp-kit + wallet-standard, so pairing,\n * origin, and account discovery failures surface as real browser failures.\n */\nexport const connectAs = async (page: PlaywrightPageLike, accountName: string): Promise<void> => {\n\ttry {\n\t\tawait selectAccount(page, accountName);\n\t} catch (cause) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage: `connectAs(\"${accountName}\") failed`,\n\t\t\toperation: 'switch-account',\n\t\t\tcause,\n\t\t});\n\t}\n};\n\n/**\n * Switch the dev-wallet's active account by routing through the\n * dapp-kit global slot the app populates at module init. Strictly\n * faster + less flaky than clicking the wallet's UI.\n */\nexport const selectAccount = async (\n\tpage: PlaywrightPageLike,\n\taccountName: string,\n): Promise<void> => {\n\t// `evaluate`'s closure is serialized into the browser; the slot\n\t// shape (`DAppKitSlot`) lives in `runtime/dapp-kit-slot.ts` — the\n\t// in-browser closure can't import it, but the global-augmentation\n\t// `globalThis.__devstackDAppKit__` is the typed contract both sides\n\t// rely on.\n\tconst result = await page.evaluate(async (name): Promise<{ ok: boolean; reason?: string }> => {\n\t\tconst slot = (globalThis as { __devstackDAppKit__?: DAppKitSlot }).__devstackDAppKit__;\n\t\tif (slot === undefined || slot.selectAccount === undefined) {\n\t\t\treturn { ok: false, reason: 'slot-not-populated' };\n\t\t}\n\t\ttry {\n\t\t\tawait slot.selectAccount(name as string);\n\t\t\treturn { ok: true };\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: err instanceof Error ? err.message : String(err),\n\t\t\t};\n\t\t}\n\t}, accountName);\n\tif (!result.ok) {\n\t\tthrow new PlaywrightWalletAdapterError({\n\t\t\tmessage:\n\t\t\t\t`selectAccount(\"${accountName}\") failed: ${result.reason ?? 'unknown'}. ` +\n\t\t\t\t`Confirm \\`globalThis.${DAPP_KIT_SLOT}\\` is populated by the app's ` +\n\t\t\t\t`dapp-kit module at boot.`,\n\t\t\toperation: 'switch-account',\n\t\t\t// `cause` survives the `page.evaluate` boundary as a string —\n\t\t\t// the browser-side `Error` instance is lost across the bridge,\n\t\t\t// but the message is the load-bearing diagnostic. Preserving\n\t\t\t// it on the typed error keeps the underlying detail attached\n\t\t\t// when consumers inspect `cause` rather than `message`.\n\t\t\tcause: result.reason,\n\t\t});\n\t}\n};\n\n// -----------------------------------------------------------------------------\n// Artifact loaders\n// -----------------------------------------------------------------------------\n\n/** Test-side accessor for the full manifest (already decoded). */\nexport const loadStackManifest = (options: ResolveStackContextOptions = {}): StackContext =>\n\treadStackContext(options);\n"],"mappings":"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"}
@@ -31,6 +31,11 @@ interface ColdStartUrlOptions {
31
31
  readonly cwd?: string;
32
32
  /** Host suffix owned by the router. Default: `.localhost`. */
33
33
  readonly hostSuffix?: string;
34
+ /** Env bag consulted before falling back to `process.env`. Lets
35
+ * callers (build integrations under test) inject a hermetic env
36
+ * so `DEVSTACK_STACK` / `DEVSTACK_APP` are read from the bag
37
+ * rather than leaking through the ambient environment. */
38
+ readonly env?: Readonly<Record<string, string | undefined>>;
34
39
  }
35
40
  interface ConventionalRouteHostInput {
36
41
  readonly service: string;
@@ -34,15 +34,16 @@ const coldStartUrl = (endpoint, opts) => {
34
34
  });
35
35
  }
36
36
  const cwd = opts.cwd ?? process.cwd();
37
- const stack = resolveBuildIntegrationStack(opts.stack);
38
- const app = opts.app ?? readAppName(cwd) ?? basename(cwd);
37
+ const env = opts.env ?? process.env;
38
+ const stack = resolveBuildIntegrationStack(opts.stack, env);
39
+ const app = opts.app ?? env.DEVSTACK_APP ?? readAppName(cwd) ?? basename(cwd);
39
40
  return conventionalRouteUrl({
40
41
  route,
41
42
  service: route.service,
42
43
  app,
43
44
  stack,
44
45
  ...opts.hostSuffix !== void 0 ? { hostSuffix: opts.hostSuffix } : {},
45
- scheme: route.wireProtocol === "h2c" ? "http" : "http"
46
+ scheme: "http"
46
47
  });
47
48
  };
48
49
  /** `undefined`-on-miss variant. */