@mysten-incubation/devstack 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (838) hide show
  1. package/README.md +7 -3
  2. package/dashboard-ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  3. package/dashboard-ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  4. package/dashboard-ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  5. package/dashboard-ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  6. package/dashboard-ui/assets/geist-mono-cyrillic-ext-wght-normal-I4S5GZfc.woff2 +0 -0
  7. package/dashboard-ui/assets/geist-mono-cyrillic-wght-normal-BmXc_FBt.woff2 +0 -0
  8. package/dashboard-ui/assets/geist-mono-latin-ext-wght-normal-DrnZ1wKl.woff2 +0 -0
  9. package/dashboard-ui/assets/geist-mono-latin-wght-normal-B_7UjwxQ.woff2 +0 -0
  10. package/dashboard-ui/assets/geist-mono-symbols2-wght-normal-GZpp1pK2.woff2 +0 -0
  11. package/dashboard-ui/assets/geist-mono-vietnamese-wght-normal-D8KDMBhC.woff2 +0 -0
  12. package/dashboard-ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  13. package/dashboard-ui/assets/index-Bmi1UtAg.js +1356 -0
  14. package/dashboard-ui/assets/index-D5EShVt4.js +3 -0
  15. package/dashboard-ui/assets/index-Deml9drg.css +1 -0
  16. package/dashboard-ui/index.html +13 -0
  17. package/dist/api/define-capabilities.d.mts +14 -3
  18. package/dist/api/define-capabilities.mjs +18 -1
  19. package/dist/api/define-capabilities.mjs.map +1 -1
  20. package/dist/api/define-devstack.d.mts +1 -1
  21. package/dist/api/define-devstack.mjs +6 -26
  22. package/dist/api/define-devstack.mjs.map +1 -1
  23. package/dist/api/define-plugin.d.mts +1 -0
  24. package/dist/api/define-plugin.mjs +2 -0
  25. package/dist/api/inference-network.d.mts +132 -0
  26. package/dist/api/inference-network.mjs +105 -16
  27. package/dist/api/inference-network.mjs.map +1 -1
  28. package/dist/api/plugin-errors.d.mts +7 -0
  29. package/dist/api/run-stack.d.mts +20 -9
  30. package/dist/api/run-stack.mjs +56 -29
  31. package/dist/api/run-stack.mjs.map +1 -1
  32. package/dist/build-integrations/playwright/config.d.mts +6 -4
  33. package/dist/build-integrations/playwright/config.mjs +5 -3
  34. package/dist/build-integrations/playwright/config.mjs.map +1 -1
  35. package/dist/build-integrations/playwright/errors.d.mts +1 -1
  36. package/dist/build-integrations/playwright/global-setup.d.mts +43 -17
  37. package/dist/build-integrations/playwright/global-setup.mjs +250 -13
  38. package/dist/build-integrations/playwright/global-setup.mjs.map +1 -1
  39. package/dist/build-integrations/playwright/index.d.mts +5 -3
  40. package/dist/build-integrations/playwright/index.mjs +4 -2
  41. package/dist/build-integrations/playwright/stack-context.d.mts +0 -1
  42. package/dist/build-integrations/playwright/stack-context.mjs +24 -63
  43. package/dist/build-integrations/playwright/stack-context.mjs.map +1 -1
  44. package/dist/build-integrations/playwright/wallet-context.d.mts +7 -10
  45. package/dist/build-integrations/playwright/wallet-context.mjs +8 -13
  46. package/dist/build-integrations/playwright/wallet-context.mjs.map +1 -1
  47. package/dist/build-integrations/runtime/cold-start-url.d.mts +5 -0
  48. package/dist/build-integrations/runtime/cold-start-url.mjs +4 -3
  49. package/dist/build-integrations/runtime/cold-start-url.mjs.map +1 -1
  50. package/dist/build-integrations/runtime/conventional-routes.d.mts +51 -0
  51. package/dist/build-integrations/runtime/conventional-routes.mjs +92 -0
  52. package/dist/build-integrations/runtime/conventional-routes.mjs.map +1 -0
  53. package/dist/build-integrations/runtime/discover.d.mts +38 -30
  54. package/dist/build-integrations/runtime/discover.mjs +73 -70
  55. package/dist/build-integrations/runtime/discover.mjs.map +1 -1
  56. package/dist/build-integrations/runtime/endpoint-registry.d.mts +3 -1
  57. package/dist/build-integrations/runtime/endpoint-registry.mjs +3 -1
  58. package/dist/build-integrations/runtime/endpoint-registry.mjs.map +1 -1
  59. package/dist/build-integrations/runtime/index.d.mts +7 -2
  60. package/dist/build-integrations/runtime/index.mjs +9 -2
  61. package/dist/build-integrations/runtime/manifest-types.d.mts +2 -0
  62. package/dist/build-integrations/runtime/manifest-types.mjs +3 -0
  63. package/dist/build-integrations/runtime/playwright-stack-context-slot.d.mts +29 -0
  64. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs +10 -0
  65. package/dist/build-integrations/runtime/playwright-stack-context-slot.mjs.map +1 -0
  66. package/dist/build-integrations/runtime/read-stack-context.d.mts +1 -1
  67. package/dist/build-integrations/runtime/read-stack-context.mjs +10 -4
  68. package/dist/build-integrations/runtime/read-stack-context.mjs.map +1 -1
  69. package/dist/build-integrations/runtime/resolve-discovery-env.d.mts +48 -0
  70. package/dist/build-integrations/runtime/resolve-discovery-env.mjs +42 -0
  71. package/dist/build-integrations/runtime/resolve-discovery-env.mjs.map +1 -0
  72. package/dist/build-integrations/runtime/stack-context.d.mts +1 -1
  73. package/dist/build-integrations/runtime/wallet-paths.mjs +2 -0
  74. package/dist/build-integrations/vite/index.d.mts +51 -0
  75. package/dist/build-integrations/vite/index.mjs +73 -0
  76. package/dist/build-integrations/vite/index.mjs.map +1 -0
  77. package/dist/build-integrations/vitest/env.d.mts +4 -3
  78. package/dist/build-integrations/vitest/env.mjs +6 -4
  79. package/dist/build-integrations/vitest/env.mjs.map +1 -1
  80. package/dist/build-integrations/vitest/errors.d.mts +25 -4
  81. package/dist/build-integrations/vitest/errors.mjs +15 -2
  82. package/dist/build-integrations/vitest/errors.mjs.map +1 -1
  83. package/dist/build-integrations/vitest/index.d.mts +2 -2
  84. package/dist/build-integrations/vitest/index.mjs +3 -3
  85. package/dist/build-integrations/vitest/setup.d.mts +4 -2
  86. package/dist/build-integrations/vitest/setup.mjs +2 -2
  87. package/dist/build-integrations/vitest/setup.mjs.map +1 -1
  88. package/dist/build-integrations/vitest/stack-context.d.mts +0 -1
  89. package/dist/build-integrations/vitest/stack-context.mjs +33 -13
  90. package/dist/build-integrations/vitest/stack-context.mjs.map +1 -1
  91. package/dist/cli/bail.mjs +23 -0
  92. package/dist/cli/bail.mjs.map +1 -0
  93. package/dist/{surfaces/cli/commands → cli}/doctor-probes.mjs +26 -16
  94. package/dist/cli/doctor-probes.mjs.map +1 -0
  95. package/dist/cli/main.d.mts +15 -1
  96. package/dist/cli/main.mjs +166 -482
  97. package/dist/cli/main.mjs.map +1 -1
  98. package/dist/cli/prune-direct.mjs +31 -201
  99. package/dist/cli/prune-direct.mjs.map +1 -1
  100. package/dist/cli/snapshot-reader.mjs +14 -11
  101. package/dist/cli/snapshot-reader.mjs.map +1 -1
  102. package/dist/cli/up-lifecycle.mjs +4 -1
  103. package/dist/cli/up-lifecycle.mjs.map +1 -1
  104. package/dist/cli/wirings/apply.mjs +95 -0
  105. package/dist/cli/wirings/apply.mjs.map +1 -0
  106. package/dist/cli/wirings/build-verb-layers.mjs +42 -0
  107. package/dist/cli/wirings/build-verb-layers.mjs.map +1 -0
  108. package/dist/cli/wirings/config-loader.mjs +69 -0
  109. package/dist/cli/wirings/config-loader.mjs.map +1 -0
  110. package/dist/cli/wirings/engine-command.mjs +30 -0
  111. package/dist/cli/wirings/engine-command.mjs.map +1 -0
  112. package/dist/cli/wirings/identity.mjs +72 -0
  113. package/dist/cli/wirings/identity.mjs.map +1 -0
  114. package/dist/cli/wirings/provide-file-system.mjs +7 -0
  115. package/dist/cli/wirings/provide-file-system.mjs.map +1 -0
  116. package/dist/cli/wirings/snapshot.mjs +177 -0
  117. package/dist/cli/wirings/snapshot.mjs.map +1 -0
  118. package/dist/cli/wirings/up.mjs +287 -0
  119. package/dist/cli/wirings/up.mjs.map +1 -0
  120. package/dist/cli/wirings/wipe.mjs +40 -0
  121. package/dist/cli/wirings/wipe.mjs.map +1 -0
  122. package/dist/contracts/capability-decl.d.mts +0 -2
  123. package/dist/contracts/codegenable.d.mts +43 -0
  124. package/dist/contracts/container-runtime.d.mts +26 -1
  125. package/dist/contracts/faucet-strategy.d.mts +25 -0
  126. package/dist/contracts/funding-strategy.d.mts +42 -0
  127. package/dist/contracts/plugin-expander.mjs +60 -0
  128. package/dist/contracts/plugin-expander.mjs.map +1 -0
  129. package/dist/contracts/projection.d.mts +5 -3
  130. package/dist/contracts/renderer.d.mts +23 -0
  131. package/dist/contracts/routable.d.mts +14 -1
  132. package/dist/contracts/snapshotable.d.mts +25 -3
  133. package/dist/contracts/wallet-protocol.d.mts +52 -0
  134. package/dist/contracts/wallet-protocol.mjs +52 -0
  135. package/dist/contracts/wallet-protocol.mjs.map +1 -0
  136. package/dist/index.d.mts +26 -25
  137. package/dist/index.mjs +20 -13
  138. package/dist/{runtime → orchestrators}/built-in-plugin-layers.mjs +10 -5
  139. package/dist/orchestrators/built-in-plugin-layers.mjs.map +1 -0
  140. package/dist/orchestrators/codegen/bindings.d.mts +1 -2
  141. package/dist/orchestrators/codegen/bindings.mjs +52 -186
  142. package/dist/orchestrators/codegen/bindings.mjs.map +1 -1
  143. package/dist/orchestrators/codegen/emit.mjs +19 -1
  144. package/dist/orchestrators/codegen/emit.mjs.map +1 -1
  145. package/dist/orchestrators/codegen/errors.mjs +8 -3
  146. package/dist/orchestrators/codegen/errors.mjs.map +1 -1
  147. package/dist/orchestrators/codegen/format.mjs +47 -39
  148. package/dist/orchestrators/codegen/format.mjs.map +1 -1
  149. package/dist/orchestrators/codegen/gitignore.mjs +3 -1
  150. package/dist/orchestrators/codegen/gitignore.mjs.map +1 -1
  151. package/dist/orchestrators/codegen/output-location.mjs +40 -0
  152. package/dist/orchestrators/codegen/output-location.mjs.map +1 -0
  153. package/dist/orchestrators/codegen/paths.d.mts +1 -1
  154. package/dist/orchestrators/codegen/paths.mjs +40 -14
  155. package/dist/orchestrators/codegen/paths.mjs.map +1 -1
  156. package/dist/orchestrators/codegen/permissions.mjs +3 -1
  157. package/dist/orchestrators/codegen/permissions.mjs.map +1 -1
  158. package/dist/orchestrators/codegen/service.mjs +157 -105
  159. package/dist/orchestrators/codegen/service.mjs.map +1 -1
  160. package/dist/orchestrators/lifecycle-prune/errors.mjs +31 -0
  161. package/dist/orchestrators/lifecycle-prune/errors.mjs.map +1 -0
  162. package/dist/orchestrators/lifecycle-prune/index.mjs +350 -0
  163. package/dist/orchestrators/lifecycle-prune/index.mjs.map +1 -0
  164. package/dist/orchestrators/router/cleanup.mjs +26 -27
  165. package/dist/orchestrators/router/cleanup.mjs.map +1 -1
  166. package/dist/orchestrators/router/entrypoints.mjs +2 -2
  167. package/dist/orchestrators/router/entrypoints.mjs.map +1 -1
  168. package/dist/orchestrators/router/file-provider.mjs +14 -5
  169. package/dist/orchestrators/router/file-provider.mjs.map +1 -1
  170. package/dist/orchestrators/router/hostname.mjs +19 -55
  171. package/dist/orchestrators/router/hostname.mjs.map +1 -1
  172. package/dist/orchestrators/router/index.mjs +11 -0
  173. package/dist/orchestrators/router/profile.mjs +2 -2
  174. package/dist/orchestrators/router/sentinels.mjs +26 -0
  175. package/dist/orchestrators/router/sentinels.mjs.map +1 -0
  176. package/dist/orchestrators/router/service.mjs +40 -37
  177. package/dist/orchestrators/router/service.mjs.map +1 -1
  178. package/dist/orchestrators/router/traefik-container.mjs +27 -16
  179. package/dist/orchestrators/router/traefik-container.mjs.map +1 -1
  180. package/dist/{substrate/runtime → orchestrators}/run.mjs +26 -21
  181. package/dist/orchestrators/run.mjs.map +1 -0
  182. package/dist/orchestrators/runtime-composition.d.mts +1 -1
  183. package/dist/orchestrators/runtime-composition.mjs +123 -39
  184. package/dist/orchestrators/runtime-composition.mjs.map +1 -1
  185. package/dist/orchestrators/snapshot/capture-command.d.mts +1 -0
  186. package/dist/orchestrators/snapshot/capture-command.mjs +25 -0
  187. package/dist/orchestrators/snapshot/capture-command.mjs.map +1 -0
  188. package/dist/orchestrators/snapshot/capture.mjs +42 -28
  189. package/dist/orchestrators/snapshot/capture.mjs.map +1 -1
  190. package/dist/orchestrators/snapshot/descriptor.mjs +35 -10
  191. package/dist/orchestrators/snapshot/descriptor.mjs.map +1 -1
  192. package/dist/orchestrators/snapshot/identity-guard.mjs +1 -1
  193. package/dist/orchestrators/snapshot/index.mjs +13 -0
  194. package/dist/orchestrators/snapshot/integrity.d.mts +1 -1
  195. package/dist/orchestrators/snapshot/integrity.mjs +73 -17
  196. package/dist/orchestrators/snapshot/integrity.mjs.map +1 -1
  197. package/dist/orchestrators/snapshot/pending-marker.d.mts +1 -0
  198. package/dist/orchestrators/snapshot/pending-marker.mjs +99 -0
  199. package/dist/orchestrators/snapshot/pending-marker.mjs.map +1 -0
  200. package/dist/orchestrators/snapshot/phase-error.mjs +23 -0
  201. package/dist/orchestrators/snapshot/phase-error.mjs.map +1 -0
  202. package/dist/orchestrators/snapshot/prune.mjs +20 -55
  203. package/dist/orchestrators/snapshot/prune.mjs.map +1 -1
  204. package/dist/orchestrators/snapshot/recover-pending.d.mts +1 -0
  205. package/dist/orchestrators/snapshot/recover-pending.mjs +223 -0
  206. package/dist/orchestrators/snapshot/recover-pending.mjs.map +1 -0
  207. package/dist/orchestrators/snapshot/restore.mjs +118 -84
  208. package/dist/orchestrators/snapshot/restore.mjs.map +1 -1
  209. package/dist/orchestrators/snapshot/service.mjs +53 -56
  210. package/dist/orchestrators/snapshot/service.mjs.map +1 -1
  211. package/dist/orchestrators/snapshot/state-document.d.mts +1 -0
  212. package/dist/orchestrators/snapshot/state-document.mjs +47 -7
  213. package/dist/orchestrators/snapshot/state-document.mjs.map +1 -1
  214. package/dist/orchestrators/snapshot/wipe.mjs +67 -10
  215. package/dist/orchestrators/snapshot/wipe.mjs.map +1 -1
  216. package/dist/plugins/account/codegen.mjs +9 -8
  217. package/dist/plugins/account/codegen.mjs.map +1 -1
  218. package/dist/plugins/account/errors.d.mts +33 -6
  219. package/dist/plugins/account/errors.mjs.map +1 -1
  220. package/dist/plugins/account/funding.d.mts +29 -19
  221. package/dist/plugins/account/funding.mjs +84 -66
  222. package/dist/plugins/account/funding.mjs.map +1 -1
  223. package/dist/plugins/account/index.d.mts +2 -4
  224. package/dist/plugins/account/index.mjs +64 -31
  225. package/dist/plugins/account/index.mjs.map +1 -1
  226. package/dist/plugins/account/keypair.mjs +6 -9
  227. package/dist/plugins/account/keypair.mjs.map +1 -1
  228. package/dist/plugins/account/lease.mjs +1 -0
  229. package/dist/plugins/account/lease.mjs.map +1 -1
  230. package/dist/plugins/account/registry.d.mts +14 -1
  231. package/dist/plugins/account/registry.mjs +18 -18
  232. package/dist/plugins/account/registry.mjs.map +1 -1
  233. package/dist/plugins/account/service.d.mts +23 -4
  234. package/dist/plugins/account/service.mjs +83 -45
  235. package/dist/plugins/account/service.mjs.map +1 -1
  236. package/dist/plugins/account/snapshot.mjs +2 -5
  237. package/dist/plugins/account/snapshot.mjs.map +1 -1
  238. package/dist/plugins/account/spans.mjs +16 -0
  239. package/dist/plugins/account/spans.mjs.map +1 -0
  240. package/dist/plugins/account/variants/keystore.mjs +6 -8
  241. package/dist/plugins/account/variants/keystore.mjs.map +1 -1
  242. package/dist/plugins/action/build-context.d.mts +3 -2
  243. package/dist/plugins/action/errors.d.mts +16 -12
  244. package/dist/plugins/action/errors.mjs.map +1 -1
  245. package/dist/plugins/action/execute.mjs +65 -103
  246. package/dist/plugins/action/execute.mjs.map +1 -1
  247. package/dist/plugins/action/index.d.mts +0 -2
  248. package/dist/plugins/action/index.mjs +17 -13
  249. package/dist/plugins/action/index.mjs.map +1 -1
  250. package/dist/plugins/action/service.mjs +38 -35
  251. package/dist/plugins/action/service.mjs.map +1 -1
  252. package/dist/plugins/action/spans.mjs +11 -0
  253. package/dist/plugins/action/spans.mjs.map +1 -0
  254. package/dist/plugins/coin/codegen.mjs +9 -8
  255. package/dist/plugins/coin/codegen.mjs.map +1 -1
  256. package/dist/plugins/coin/discovery.mjs +8 -4
  257. package/dist/plugins/coin/discovery.mjs.map +1 -1
  258. package/dist/plugins/coin/index.d.mts +11 -29
  259. package/dist/plugins/coin/index.mjs +56 -27
  260. package/dist/plugins/coin/index.mjs.map +1 -1
  261. package/dist/plugins/coin/metadata.mjs +8 -15
  262. package/dist/plugins/coin/metadata.mjs.map +1 -1
  263. package/dist/plugins/coin/mint.d.mts +30 -11
  264. package/dist/plugins/coin/mint.mjs +78 -74
  265. package/dist/plugins/coin/mint.mjs.map +1 -1
  266. package/dist/plugins/coin/registry.mjs +4 -7
  267. package/dist/plugins/coin/registry.mjs.map +1 -1
  268. package/dist/plugins/coin/service.d.mts +39 -1
  269. package/dist/plugins/coin/service.mjs +11 -4
  270. package/dist/plugins/coin/service.mjs.map +1 -1
  271. package/dist/plugins/coin/spans.mjs +20 -0
  272. package/dist/plugins/coin/spans.mjs.map +1 -0
  273. package/dist/plugins/dashboard/domain.mjs +402 -0
  274. package/dist/plugins/dashboard/domain.mjs.map +1 -0
  275. package/dist/plugins/dashboard/index.d.mts +29 -0
  276. package/dist/plugins/dashboard/index.mjs +91 -0
  277. package/dist/plugins/dashboard/index.mjs.map +1 -0
  278. package/dist/plugins/dashboard/origin-policy.mjs +36 -0
  279. package/dist/plugins/dashboard/origin-policy.mjs.map +1 -0
  280. package/dist/plugins/dashboard/routable.mjs +27 -0
  281. package/dist/plugins/dashboard/routable.mjs.map +1 -0
  282. package/dist/plugins/dashboard/schema/builder.mjs +21 -0
  283. package/dist/plugins/dashboard/schema/builder.mjs.map +1 -0
  284. package/dist/plugins/dashboard/schema/enums.mjs +72 -0
  285. package/dist/plugins/dashboard/schema/enums.mjs.map +1 -0
  286. package/dist/plugins/dashboard/schema/root.mjs +351 -0
  287. package/dist/plugins/dashboard/schema/root.mjs.map +1 -0
  288. package/dist/plugins/dashboard/schema/types.mjs +508 -0
  289. package/dist/plugins/dashboard/schema/types.mjs.map +1 -0
  290. package/dist/plugins/dashboard/schema.mjs +11 -0
  291. package/dist/plugins/dashboard/schema.mjs.map +1 -0
  292. package/dist/plugins/dashboard/server.mjs +166 -0
  293. package/dist/plugins/dashboard/server.mjs.map +1 -0
  294. package/dist/plugins/deepbook/deploy.mjs +53 -115
  295. package/dist/plugins/deepbook/deploy.mjs.map +1 -1
  296. package/dist/plugins/deepbook/errors.mjs +1 -0
  297. package/dist/plugins/deepbook/errors.mjs.map +1 -1
  298. package/dist/plugins/deepbook/faucet-strategy.mjs +47 -34
  299. package/dist/plugins/deepbook/faucet-strategy.mjs.map +1 -1
  300. package/dist/plugins/deepbook/hash.mjs +9 -0
  301. package/dist/plugins/deepbook/hash.mjs.map +1 -0
  302. package/dist/plugins/deepbook/index.d.mts +1 -10
  303. package/dist/plugins/deepbook/index.mjs +25 -22
  304. package/dist/plugins/deepbook/index.mjs.map +1 -1
  305. package/dist/plugins/deepbook/pyth/index.mjs +26 -55
  306. package/dist/plugins/deepbook/pyth/index.mjs.map +1 -1
  307. package/dist/plugins/deepbook/snapshot.mjs +17 -29
  308. package/dist/plugins/deepbook/snapshot.mjs.map +1 -1
  309. package/dist/plugins/deepbook/spans.mjs +18 -0
  310. package/dist/plugins/deepbook/spans.mjs.map +1 -0
  311. package/dist/plugins/deepbook/type-strings.mjs +65 -0
  312. package/dist/plugins/deepbook/type-strings.mjs.map +1 -0
  313. package/dist/plugins/deepbook/types.d.mts +2 -3
  314. package/dist/plugins/deepbook/types.mjs.map +1 -1
  315. package/dist/plugins/faucet/dispatcher.d.mts +21 -2
  316. package/dist/plugins/faucet/dispatcher.mjs +1 -2
  317. package/dist/plugins/faucet/dispatcher.mjs.map +1 -1
  318. package/dist/plugins/faucet/errors.d.mts +11 -24
  319. package/dist/plugins/faucet/errors.mjs.map +1 -1
  320. package/dist/plugins/faucet/http.mjs +33 -14
  321. package/dist/plugins/faucet/http.mjs.map +1 -1
  322. package/dist/plugins/faucet/index.d.mts +15 -5
  323. package/dist/plugins/faucet/index.mjs +3 -0
  324. package/dist/plugins/faucet/index.mjs.map +1 -1
  325. package/dist/plugins/faucet/spans.mjs +12 -0
  326. package/dist/plugins/faucet/spans.mjs.map +1 -0
  327. package/dist/plugins/host-service/errors.d.mts +1 -1
  328. package/dist/plugins/host-service/index.mjs +34 -8
  329. package/dist/plugins/host-service/index.mjs.map +1 -1
  330. package/dist/plugins/host-service/routable.mjs +2 -1
  331. package/dist/plugins/host-service/routable.mjs.map +1 -1
  332. package/dist/plugins/host-service/service.d.mts +21 -0
  333. package/dist/plugins/host-service/service.mjs +136 -81
  334. package/dist/plugins/host-service/service.mjs.map +1 -1
  335. package/dist/plugins/internal/acquire-on-chain-artifact.mjs +23 -0
  336. package/dist/plugins/internal/acquire-on-chain-artifact.mjs.map +1 -0
  337. package/dist/plugins/internal/codegen-helpers.mjs +18 -0
  338. package/dist/plugins/internal/codegen-helpers.mjs.map +1 -0
  339. package/dist/plugins/internal/funding-failure-error.mjs +32 -0
  340. package/dist/plugins/internal/funding-failure-error.mjs.map +1 -0
  341. package/dist/plugins/package/build.mjs +1 -1
  342. package/dist/plugins/package/build.mjs.map +1 -1
  343. package/dist/plugins/package/codegen.mjs +26 -0
  344. package/dist/plugins/package/codegen.mjs.map +1 -1
  345. package/dist/plugins/package/errors.d.mts +16 -6
  346. package/dist/plugins/package/errors.mjs.map +1 -1
  347. package/dist/plugins/package/index.d.mts +0 -4
  348. package/dist/plugins/package/index.mjs +27 -21
  349. package/dist/plugins/package/index.mjs.map +1 -1
  350. package/dist/plugins/package/mode-known.mjs +26 -12
  351. package/dist/plugins/package/mode-known.mjs.map +1 -1
  352. package/dist/plugins/package/mode-local.mjs +47 -41
  353. package/dist/plugins/package/mode-local.mjs.map +1 -1
  354. package/dist/plugins/package/publish-executor.mjs +55 -114
  355. package/dist/plugins/package/publish-executor.mjs.map +1 -1
  356. package/dist/plugins/package/registry.mjs +2 -1
  357. package/dist/plugins/package/registry.mjs.map +1 -1
  358. package/dist/plugins/package/service.mjs.map +1 -1
  359. package/dist/plugins/package/spans.mjs +14 -0
  360. package/dist/plugins/package/spans.mjs.map +1 -0
  361. package/dist/plugins/postgres/db-ensure.mjs +19 -12
  362. package/dist/plugins/postgres/db-ensure.mjs.map +1 -1
  363. package/dist/plugins/postgres/errors.d.mts +5 -0
  364. package/dist/plugins/postgres/errors.mjs.map +1 -1
  365. package/dist/plugins/postgres/index.mjs +10 -17
  366. package/dist/plugins/postgres/index.mjs.map +1 -1
  367. package/dist/plugins/postgres/service.mjs +58 -24
  368. package/dist/plugins/postgres/service.mjs.map +1 -1
  369. package/dist/plugins/postgres/snapshot.mjs.map +1 -1
  370. package/dist/plugins/postgres/spans.mjs +11 -0
  371. package/dist/plugins/postgres/spans.mjs.map +1 -0
  372. package/dist/plugins/router-entrypoints.mjs +4 -4
  373. package/dist/plugins/router-entrypoints.mjs.map +1 -1
  374. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs +15 -13
  375. package/dist/plugins/seal/bootstrap-assets/cargo-image.mjs.map +1 -1
  376. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs +15 -19
  377. package/dist/plugins/seal/bootstrap-assets/source-fetch.mjs.map +1 -1
  378. package/dist/plugins/seal/codegen.d.mts +2 -3
  379. package/dist/plugins/seal/codegen.mjs.map +1 -1
  380. package/dist/plugins/seal/config-render.mjs +35 -8
  381. package/dist/plugins/seal/config-render.mjs.map +1 -1
  382. package/dist/plugins/seal/deploy.mjs +31 -39
  383. package/dist/plugins/seal/deploy.mjs.map +1 -1
  384. package/dist/plugins/seal/errors.d.mts +1 -3
  385. package/dist/plugins/seal/errors.mjs +7 -1
  386. package/dist/plugins/seal/errors.mjs.map +1 -1
  387. package/dist/plugins/seal/index.d.mts +1 -6
  388. package/dist/plugins/seal/index.mjs +40 -14
  389. package/dist/plugins/seal/index.mjs.map +1 -1
  390. package/dist/plugins/seal/key-manager.d.mts +1 -9
  391. package/dist/plugins/seal/key-manager.mjs +2 -18
  392. package/dist/plugins/seal/key-manager.mjs.map +1 -1
  393. package/dist/plugins/seal/key-server.mjs +37 -36
  394. package/dist/plugins/seal/key-server.mjs.map +1 -1
  395. package/dist/plugins/seal/keygen.mjs +16 -17
  396. package/dist/plugins/seal/keygen.mjs.map +1 -1
  397. package/dist/plugins/seal/mode/fork-known.mjs +36 -14
  398. package/dist/plugins/seal/mode/fork-known.mjs.map +1 -1
  399. package/dist/plugins/seal/mode/live.d.mts +6 -4
  400. package/dist/plugins/seal/mode/live.mjs +14 -21
  401. package/dist/plugins/seal/mode/live.mjs.map +1 -1
  402. package/dist/plugins/seal/mode/local-keygen.mjs +57 -21
  403. package/dist/plugins/seal/mode/local-keygen.mjs.map +1 -1
  404. package/dist/plugins/seal/registry-publish.mjs +1 -0
  405. package/dist/plugins/seal/registry-publish.mjs.map +1 -1
  406. package/dist/plugins/seal/routable.mjs.map +1 -1
  407. package/dist/plugins/seal/service.mjs.map +1 -1
  408. package/dist/plugins/seal/spans.mjs +18 -0
  409. package/dist/plugins/seal/spans.mjs.map +1 -0
  410. package/dist/plugins/sui/auto-tick.mjs +17 -23
  411. package/dist/plugins/sui/auto-tick.mjs.map +1 -1
  412. package/dist/plugins/sui/chain-build-container.mjs +18 -0
  413. package/dist/plugins/sui/chain-build-container.mjs.map +1 -0
  414. package/dist/plugins/sui/chain-probe.d.mts +5 -5
  415. package/dist/plugins/sui/chain-probe.mjs +28 -58
  416. package/dist/plugins/sui/chain-probe.mjs.map +1 -1
  417. package/dist/plugins/sui/codegen.mjs +26 -0
  418. package/dist/plugins/sui/codegen.mjs.map +1 -1
  419. package/dist/plugins/sui/errors.d.mts +2 -29
  420. package/dist/plugins/sui/errors.mjs +1 -3
  421. package/dist/plugins/sui/errors.mjs.map +1 -1
  422. package/dist/plugins/sui/fork-faucet-strategy.d.mts +1 -0
  423. package/dist/plugins/sui/fork-faucet-strategy.mjs +55 -0
  424. package/dist/plugins/sui/fork-faucet-strategy.mjs.map +1 -0
  425. package/dist/plugins/sui/fork-orchestration.d.mts +1 -0
  426. package/dist/plugins/sui/fork-orchestration.mjs +170 -2
  427. package/dist/plugins/sui/fork-orchestration.mjs.map +1 -1
  428. package/dist/plugins/sui/fork-transaction.d.mts +2 -0
  429. package/dist/plugins/sui/fork-transaction.mjs +92 -28
  430. package/dist/plugins/sui/fork-transaction.mjs.map +1 -1
  431. package/dist/plugins/sui/index.d.mts +33 -70
  432. package/dist/plugins/sui/index.mjs +58 -35
  433. package/dist/plugins/sui/index.mjs.map +1 -1
  434. package/dist/plugins/{faucet/strategies/sui-local.mjs → sui/local-faucet-strategy.mjs} +10 -7
  435. package/dist/plugins/sui/local-faucet-strategy.mjs.map +1 -0
  436. package/dist/plugins/sui/mode/external.mjs +7 -13
  437. package/dist/plugins/sui/mode/external.mjs.map +1 -1
  438. package/dist/plugins/sui/mode/fork.mjs +136 -59
  439. package/dist/plugins/sui/mode/fork.mjs.map +1 -1
  440. package/dist/plugins/sui/mode/live.mjs +10 -16
  441. package/dist/plugins/sui/mode/live.mjs.map +1 -1
  442. package/dist/plugins/sui/mode/local.mjs +37 -36
  443. package/dist/plugins/sui/mode/local.mjs.map +1 -1
  444. package/dist/plugins/sui/mode/shared-boot.mjs +38 -115
  445. package/dist/plugins/sui/mode/shared-boot.mjs.map +1 -1
  446. package/dist/plugins/sui/mode/shared.d.mts +1 -5
  447. package/dist/plugins/sui/mode/shared.mjs.map +1 -1
  448. package/dist/plugins/sui/mode/spec.d.mts +18 -0
  449. package/dist/plugins/sui/move-summary-runner.mjs +207 -0
  450. package/dist/plugins/sui/move-summary-runner.mjs.map +1 -0
  451. package/dist/plugins/sui/network-resolver.d.mts +4 -3
  452. package/dist/plugins/sui/service.mjs.map +1 -1
  453. package/dist/plugins/sui/snapshot.mjs +3 -0
  454. package/dist/plugins/sui/snapshot.mjs.map +1 -1
  455. package/dist/plugins/sui/spans.mjs +17 -0
  456. package/dist/plugins/sui/spans.mjs.map +1 -0
  457. package/dist/plugins/wallet/codegen.d.mts +0 -1
  458. package/dist/plugins/wallet/codegen.mjs +8 -9
  459. package/dist/plugins/wallet/codegen.mjs.map +1 -1
  460. package/dist/plugins/wallet/index.d.mts +6 -8
  461. package/dist/plugins/wallet/index.mjs +46 -35
  462. package/dist/plugins/wallet/index.mjs.map +1 -1
  463. package/dist/plugins/wallet/origin-policy.mjs +12 -28
  464. package/dist/plugins/wallet/origin-policy.mjs.map +1 -1
  465. package/dist/plugins/wallet/pairing.mjs +6 -4
  466. package/dist/plugins/wallet/pairing.mjs.map +1 -1
  467. package/dist/plugins/wallet/protocol.d.mts +1 -0
  468. package/dist/plugins/wallet/protocol.mjs +5 -44
  469. package/dist/plugins/wallet/protocol.mjs.map +1 -1
  470. package/dist/plugins/wallet/routable.mjs +2 -8
  471. package/dist/plugins/wallet/routable.mjs.map +1 -1
  472. package/dist/plugins/wallet/server.mjs +36 -44
  473. package/dist/plugins/wallet/server.mjs.map +1 -1
  474. package/dist/plugins/wallet/service.d.mts +1 -5
  475. package/dist/plugins/wallet/service.mjs +22 -18
  476. package/dist/plugins/wallet/service.mjs.map +1 -1
  477. package/dist/plugins/wallet/spans.mjs +22 -0
  478. package/dist/plugins/wallet/spans.mjs.map +1 -0
  479. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs +33 -8
  480. package/dist/plugins/walrus/bootstrap-assets/cargo-image.mjs.map +1 -1
  481. package/dist/plugins/walrus/codegen.d.mts +3 -3
  482. package/dist/plugins/walrus/codegen.mjs.map +1 -1
  483. package/dist/plugins/walrus/deploy-paths.mjs +21 -5
  484. package/dist/plugins/walrus/deploy-paths.mjs.map +1 -1
  485. package/dist/plugins/walrus/deploy.mjs +67 -69
  486. package/dist/plugins/walrus/deploy.mjs.map +1 -1
  487. package/dist/plugins/walrus/errors.mjs +1 -0
  488. package/dist/plugins/walrus/errors.mjs.map +1 -1
  489. package/dist/plugins/walrus/faucet-strategy.mjs +12 -7
  490. package/dist/plugins/walrus/faucet-strategy.mjs.map +1 -1
  491. package/dist/plugins/walrus/index.d.mts +2 -13
  492. package/dist/plugins/walrus/index.mjs +18 -23
  493. package/dist/plugins/walrus/index.mjs.map +1 -1
  494. package/dist/plugins/walrus/mode/known-deploy.mjs +7 -5
  495. package/dist/plugins/walrus/mode/known-deploy.mjs.map +1 -1
  496. package/dist/plugins/walrus/mode/local-cluster.mjs +26 -7
  497. package/dist/plugins/walrus/mode/local-cluster.mjs.map +1 -1
  498. package/dist/plugins/walrus/registry-publish.mjs.map +1 -1
  499. package/dist/plugins/walrus/routable.mjs +7 -23
  500. package/dist/plugins/walrus/routable.mjs.map +1 -1
  501. package/dist/plugins/walrus/service.mjs.map +1 -1
  502. package/dist/plugins/walrus/spans.mjs +18 -0
  503. package/dist/plugins/walrus/spans.mjs.map +1 -0
  504. package/dist/plugins/walrus/storage-nodes.d.mts +6 -2
  505. package/dist/plugins/walrus/storage-nodes.mjs +15 -8
  506. package/dist/plugins/walrus/storage-nodes.mjs.map +1 -1
  507. package/dist/plugins/walrus/wal-swap.mjs +58 -15
  508. package/dist/plugins/walrus/wal-swap.mjs.map +1 -1
  509. package/dist/primitives/artifact-publisher.d.mts +1 -1
  510. package/dist/primitives/artifact-publisher.mjs +15 -0
  511. package/dist/primitives/artifact-publisher.mjs.map +1 -0
  512. package/dist/runtime/docker/client.mjs +17 -4
  513. package/dist/runtime/docker/client.mjs.map +1 -1
  514. package/dist/runtime/docker/container.mjs +219 -132
  515. package/dist/runtime/docker/container.mjs.map +1 -1
  516. package/dist/runtime/docker/errors.mjs +0 -6
  517. package/dist/runtime/docker/errors.mjs.map +1 -1
  518. package/dist/runtime/docker/exec.mjs +21 -18
  519. package/dist/runtime/docker/exec.mjs.map +1 -1
  520. package/dist/runtime/docker/image.mjs +36 -13
  521. package/dist/runtime/docker/image.mjs.map +1 -1
  522. package/dist/runtime/docker/index.mjs +14 -0
  523. package/dist/runtime/docker/inspect-and-decode.mjs +51 -0
  524. package/dist/runtime/docker/inspect-and-decode.mjs.map +1 -0
  525. package/dist/runtime/docker/inventory.mjs +14 -11
  526. package/dist/runtime/docker/inventory.mjs.map +1 -1
  527. package/dist/runtime/docker/labels.mjs +38 -5
  528. package/dist/runtime/docker/labels.mjs.map +1 -1
  529. package/dist/runtime/docker/logs.d.mts +1 -1
  530. package/dist/runtime/docker/logs.mjs.map +1 -1
  531. package/dist/runtime/docker/network.mjs +83 -47
  532. package/dist/runtime/docker/network.mjs.map +1 -1
  533. package/dist/runtime/docker/render-run-args.mjs +82 -0
  534. package/dist/runtime/docker/render-run-args.mjs.map +1 -0
  535. package/dist/runtime/docker/service.d.mts +1 -1
  536. package/dist/runtime/docker/service.mjs +12 -7
  537. package/dist/runtime/docker/service.mjs.map +1 -1
  538. package/dist/runtime/docker/sweep.mjs +118 -43
  539. package/dist/runtime/docker/sweep.mjs.map +1 -1
  540. package/dist/runtime/docker/volume.mjs +2 -0
  541. package/dist/runtime/docker/volume.mjs.map +1 -1
  542. package/dist/runtime/docker/wrap.mjs +30 -1
  543. package/dist/runtime/docker/wrap.mjs.map +1 -1
  544. package/dist/substrate/cross-process.mjs +14 -8
  545. package/dist/substrate/cross-process.mjs.map +1 -1
  546. package/dist/substrate/event-time.mjs +33 -0
  547. package/dist/substrate/event-time.mjs.map +1 -0
  548. package/dist/substrate/events.d.mts +28 -8
  549. package/dist/substrate/identity.d.mts +2 -1
  550. package/dist/substrate/manifest.d.mts +68 -5
  551. package/dist/substrate/manifest.mjs +34 -5
  552. package/dist/substrate/manifest.mjs.map +1 -1
  553. package/dist/substrate/network.d.mts +3 -5
  554. package/dist/substrate/options.d.mts +0 -2
  555. package/dist/substrate/plugin.d.mts +13 -0
  556. package/dist/substrate/plugin.mjs +4 -2
  557. package/dist/substrate/plugin.mjs.map +1 -1
  558. package/dist/substrate/projection.d.mts +35 -3
  559. package/dist/substrate/runtime/artifact-publisher/index.mjs +19 -9
  560. package/dist/substrate/runtime/artifact-publisher/index.mjs.map +1 -1
  561. package/dist/substrate/runtime/atomic-write.mjs +97 -32
  562. package/dist/substrate/runtime/atomic-write.mjs.map +1 -1
  563. package/dist/substrate/runtime/cache/index.mjs +3 -0
  564. package/dist/substrate/runtime/cache/schema.mjs +2 -2
  565. package/dist/substrate/runtime/cache/schema.mjs.map +1 -1
  566. package/dist/substrate/runtime/cache/service.mjs +9 -7
  567. package/dist/substrate/runtime/cache/service.mjs.map +1 -1
  568. package/dist/substrate/runtime/capability-sinks/index.d.mts +1 -1
  569. package/dist/substrate/runtime/capability-sinks/index.mjs +3 -0
  570. package/dist/substrate/runtime/capability-sinks/layer.mjs +1 -1
  571. package/dist/substrate/runtime/capability-sinks/service.d.mts +61 -2
  572. package/dist/substrate/runtime/capability-sinks/service.mjs +21 -26
  573. package/dist/substrate/runtime/capability-sinks/service.mjs.map +1 -1
  574. package/dist/substrate/runtime/config-validation.d.mts +1 -13
  575. package/dist/substrate/runtime/config-validation.mjs +2 -91
  576. package/dist/substrate/runtime/config-validation.mjs.map +1 -1
  577. package/dist/substrate/runtime/container-runtime.d.mts +1 -0
  578. package/dist/substrate/runtime/container-runtime.mjs +2 -0
  579. package/dist/substrate/runtime/control-plane/domain.mjs +101 -0
  580. package/dist/substrate/runtime/control-plane/domain.mjs.map +1 -0
  581. package/dist/substrate/runtime/control-plane/service.mjs +7 -0
  582. package/dist/substrate/runtime/control-plane/service.mjs.map +1 -0
  583. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs +46 -19
  584. package/dist/substrate/runtime/cross-process/command-channel/channel.mjs.map +1 -1
  585. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs +30 -12
  586. package/dist/substrate/runtime/cross-process/command-channel/file-channel.mjs.map +1 -1
  587. package/dist/substrate/runtime/cross-process/command-channel/index.mjs +5 -0
  588. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs +11 -2
  589. package/dist/substrate/runtime/cross-process/command-channel/protocol.mjs.map +1 -1
  590. package/dist/substrate/runtime/cross-process/command-channel/runtime-control-lock.mjs +1 -1
  591. package/dist/substrate/runtime/cross-process/index.mjs +11 -0
  592. package/dist/substrate/runtime/cross-process/live-clock.mjs +34 -0
  593. package/dist/substrate/runtime/cross-process/live-clock.mjs.map +1 -0
  594. package/dist/substrate/runtime/cross-process/liveness.mjs +52 -10
  595. package/dist/substrate/runtime/cross-process/liveness.mjs.map +1 -1
  596. package/dist/substrate/runtime/cross-process/lock.d.mts +1 -0
  597. package/dist/substrate/runtime/cross-process/lock.mjs +23 -0
  598. package/dist/substrate/runtime/cross-process/lock.mjs.map +1 -0
  599. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs +64 -0
  600. package/dist/substrate/runtime/cross-process/reclaim-stale-file.mjs.map +1 -0
  601. package/dist/substrate/runtime/cross-process/roster.mjs +97 -83
  602. package/dist/substrate/runtime/cross-process/roster.mjs.map +1 -1
  603. package/dist/substrate/runtime/cross-process/self-pid.mjs +8 -0
  604. package/dist/substrate/runtime/cross-process/self-pid.mjs.map +1 -0
  605. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs +24 -28
  606. package/dist/substrate/runtime/cross-process/snapshot-reservation.mjs.map +1 -1
  607. package/dist/substrate/runtime/cross-process/stack-lock.mjs +41 -20
  608. package/dist/substrate/runtime/cross-process/stack-lock.mjs.map +1 -1
  609. package/dist/substrate/runtime/current-plugin.mjs +2 -2
  610. package/dist/substrate/runtime/current-plugin.mjs.map +1 -1
  611. package/dist/substrate/runtime/errors.mjs +12 -6
  612. package/dist/substrate/runtime/errors.mjs.map +1 -1
  613. package/dist/substrate/runtime/format-unknown-error.mjs +30 -0
  614. package/dist/substrate/runtime/format-unknown-error.mjs.map +1 -0
  615. package/dist/substrate/runtime/host-bind-mount-owner.mjs +10 -0
  616. package/dist/substrate/runtime/host-bind-mount-owner.mjs.map +1 -0
  617. package/dist/substrate/runtime/host-gateway.mjs +20 -0
  618. package/dist/substrate/runtime/host-gateway.mjs.map +1 -0
  619. package/dist/substrate/runtime/host-tree-tar/index.mjs +61 -50
  620. package/dist/substrate/runtime/host-tree-tar/index.mjs.map +1 -1
  621. package/dist/substrate/runtime/http-probe.d.mts +1 -1
  622. package/dist/substrate/runtime/index.mjs +14 -0
  623. package/dist/substrate/runtime/lease-broker/index.d.mts +1 -1
  624. package/dist/substrate/runtime/lease-broker/index.mjs +2 -0
  625. package/dist/substrate/runtime/lease-broker/service.d.mts +1 -64
  626. package/dist/substrate/runtime/lease-broker/service.mjs +1 -1
  627. package/dist/substrate/runtime/lease-broker/service.mjs.map +1 -1
  628. package/dist/substrate/runtime/lifecycle/dep-graph.mjs +22 -3
  629. package/dist/substrate/runtime/lifecycle/dep-graph.mjs.map +1 -1
  630. package/dist/substrate/runtime/lifecycle/index.mjs +9 -0
  631. package/dist/substrate/runtime/lifecycle/lifecycle-fact.mjs.map +1 -1
  632. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs +20 -3
  633. package/dist/substrate/runtime/lifecycle/plugin-registry.mjs.map +1 -1
  634. package/dist/substrate/runtime/lifecycle/selective-restart.mjs +1 -1
  635. package/dist/substrate/runtime/lifecycle/signals.mjs +5 -5
  636. package/dist/substrate/runtime/lifecycle/signals.mjs.map +1 -1
  637. package/dist/substrate/runtime/lifecycle/state-machine.mjs +1 -1
  638. package/dist/substrate/runtime/managed-container.d.mts +19 -1
  639. package/dist/substrate/runtime/managed-container.mjs +20 -1
  640. package/dist/substrate/runtime/managed-container.mjs.map +1 -1
  641. package/dist/substrate/runtime/manifest/index.mjs +3 -0
  642. package/dist/substrate/runtime/manifest/manifest.mjs +15 -11
  643. package/dist/substrate/runtime/manifest/manifest.mjs.map +1 -1
  644. package/dist/substrate/runtime/mode-errors.mjs +20 -0
  645. package/dist/substrate/runtime/mode-errors.mjs.map +1 -0
  646. package/dist/substrate/runtime/observability/cascade-formatter.mjs +9 -13
  647. package/dist/substrate/runtime/observability/cascade-formatter.mjs.map +1 -1
  648. package/dist/substrate/runtime/observability/formatter-registry.mjs +19 -36
  649. package/dist/substrate/runtime/observability/formatter-registry.mjs.map +1 -1
  650. package/dist/substrate/runtime/observability/ignore-with-log.d.mts +1 -0
  651. package/dist/substrate/runtime/observability/ignore-with-log.mjs +17 -0
  652. package/dist/substrate/runtime/observability/ignore-with-log.mjs.map +1 -0
  653. package/dist/substrate/runtime/observability/index.d.mts +1 -1
  654. package/dist/substrate/runtime/observability/index.mjs +13 -0
  655. package/dist/substrate/runtime/observability/log-store.d.mts +1 -0
  656. package/dist/substrate/runtime/observability/log-store.mjs +175 -0
  657. package/dist/substrate/runtime/observability/log-store.mjs.map +1 -0
  658. package/dist/substrate/runtime/observability/logger.d.mts +2 -1
  659. package/dist/substrate/runtime/observability/logger.mjs +5 -9
  660. package/dist/substrate/runtime/observability/logger.mjs.map +1 -1
  661. package/dist/substrate/runtime/observability/output-truncate.mjs +35 -0
  662. package/dist/substrate/runtime/observability/output-truncate.mjs.map +1 -0
  663. package/dist/substrate/runtime/observability/pretty-error.mjs +9 -12
  664. package/dist/substrate/runtime/observability/pretty-error.mjs.map +1 -1
  665. package/dist/substrate/runtime/observability/redaction.d.mts +2 -13
  666. package/dist/substrate/runtime/observability/redaction.mjs +8 -14
  667. package/dist/substrate/runtime/observability/redaction.mjs.map +1 -1
  668. package/dist/substrate/runtime/observability/span-store.d.mts +1 -0
  669. package/dist/substrate/runtime/observability/span-store.mjs +110 -0
  670. package/dist/substrate/runtime/observability/span-store.mjs.map +1 -0
  671. package/dist/substrate/runtime/observability/spans.mjs +14 -14
  672. package/dist/substrate/runtime/observability/spans.mjs.map +1 -1
  673. package/dist/substrate/runtime/observability/subprocess-capture.mjs +1 -1
  674. package/dist/substrate/runtime/passthrough-or-wrap.mjs +33 -0
  675. package/dist/substrate/runtime/passthrough-or-wrap.mjs.map +1 -0
  676. package/dist/substrate/runtime/paths.d.mts +1 -1
  677. package/dist/substrate/runtime/paths.mjs +4 -3
  678. package/dist/substrate/runtime/paths.mjs.map +1 -1
  679. package/dist/substrate/runtime/phase-preserving-produce.mjs +40 -0
  680. package/dist/substrate/runtime/phase-preserving-produce.mjs.map +1 -0
  681. package/dist/substrate/runtime/port-broker/index.mjs +3 -0
  682. package/dist/substrate/runtime/port-broker/service.mjs +170 -126
  683. package/dist/substrate/runtime/port-broker/service.mjs.map +1 -1
  684. package/dist/substrate/runtime/post-acquire-tasks.mjs +1 -1
  685. package/dist/substrate/runtime/post-acquire-tasks.mjs.map +1 -1
  686. package/dist/substrate/runtime/probes.d.mts +7 -5
  687. package/dist/substrate/runtime/probes.mjs +3 -1
  688. package/dist/substrate/runtime/probes.mjs.map +1 -1
  689. package/dist/substrate/runtime/projection/index.mjs +4 -0
  690. package/dist/substrate/runtime/projection/operational-endpoints.mjs +1 -2
  691. package/dist/substrate/runtime/projection/operational-endpoints.mjs.map +1 -1
  692. package/dist/substrate/runtime/projection/persisted.mjs +33 -15
  693. package/dist/substrate/runtime/projection/persisted.mjs.map +1 -1
  694. package/dist/substrate/runtime/projection/state-ref.mjs +26 -2
  695. package/dist/substrate/runtime/projection/state-ref.mjs.map +1 -1
  696. package/dist/substrate/runtime/projection/update.mjs +88 -24
  697. package/dist/substrate/runtime/projection/update.mjs.map +1 -1
  698. package/dist/substrate/runtime/random-suffix.mjs +11 -0
  699. package/dist/substrate/runtime/random-suffix.mjs.map +1 -0
  700. package/dist/substrate/runtime/retry-policy.d.mts +59 -1
  701. package/dist/substrate/runtime/retry-policy.mjs +66 -1
  702. package/dist/substrate/runtime/retry-policy.mjs.map +1 -1
  703. package/dist/substrate/runtime/routed-url.d.mts +1 -0
  704. package/dist/substrate/runtime/routed-url.mjs +79 -0
  705. package/dist/substrate/runtime/routed-url.mjs.map +1 -0
  706. package/dist/substrate/runtime/runtime-decode.d.mts +1 -1
  707. package/dist/substrate/runtime/runtime-decode.mjs.map +1 -1
  708. package/dist/substrate/runtime/scoped-http-server.mjs +2 -3
  709. package/dist/substrate/runtime/scoped-http-server.mjs.map +1 -1
  710. package/dist/substrate/runtime/scoped-multimap/index.mjs +2 -0
  711. package/dist/substrate/runtime/scoped-multimap/service.mjs +52 -0
  712. package/dist/substrate/runtime/scoped-multimap/service.mjs.map +1 -0
  713. package/dist/substrate/runtime/scoped-ref-map/index.mjs +2 -0
  714. package/dist/substrate/runtime/scoped-ref-map/service.mjs +2 -2
  715. package/dist/substrate/runtime/scoped-ref-map/service.mjs.map +1 -1
  716. package/dist/substrate/runtime/stage-and-swap/index.mjs +72 -4
  717. package/dist/substrate/runtime/stage-and-swap/index.mjs.map +1 -1
  718. package/dist/substrate/runtime/state-store/index.d.mts +1 -0
  719. package/dist/substrate/runtime/state-store/index.mjs +3 -0
  720. package/dist/substrate/runtime/state-store/schema.d.mts +1 -0
  721. package/dist/substrate/runtime/state-store/schema.mjs +19 -14
  722. package/dist/substrate/runtime/state-store/schema.mjs.map +1 -1
  723. package/dist/substrate/runtime/state-store/service.d.mts +1 -0
  724. package/dist/substrate/runtime/state-store/service.mjs +145 -0
  725. package/dist/substrate/runtime/state-store/service.mjs.map +1 -0
  726. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.d.mts +1 -0
  727. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs +33 -0
  728. package/dist/substrate/runtime/strategy-registry/chain-keyed-strategy-for.mjs.map +1 -0
  729. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs +1 -1
  730. package/dist/substrate/runtime/strategy-registry/chain-probe-for.mjs.map +1 -1
  731. package/dist/substrate/runtime/strategy-registry/index.mjs +4 -0
  732. package/dist/substrate/runtime/strategy-registry/service.mjs +19 -33
  733. package/dist/substrate/runtime/strategy-registry/service.mjs.map +1 -1
  734. package/dist/substrate/runtime/subnet-broker.mjs +60 -0
  735. package/dist/substrate/runtime/subnet-broker.mjs.map +1 -0
  736. package/dist/substrate/runtime/sui-execute/index.d.mts +21 -1
  737. package/dist/substrate/runtime/sui-execute/index.mjs +84 -20
  738. package/dist/substrate/runtime/sui-execute/index.mjs.map +1 -1
  739. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.d.mts +1 -0
  740. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs +32 -0
  741. package/dist/substrate/runtime/sui-execute/sign-and-dispatch.mjs.map +1 -0
  742. package/dist/substrate/runtime/sui-ledger/object-ref.mjs +32 -0
  743. package/dist/substrate/runtime/sui-ledger/object-ref.mjs.map +1 -0
  744. package/dist/substrate/runtime/sui-move-build/index.mjs +93 -19
  745. package/dist/substrate/runtime/sui-move-build/index.mjs.map +1 -1
  746. package/dist/substrate/runtime/supervisor/acquire-node.mjs +181 -0
  747. package/dist/substrate/runtime/supervisor/acquire-node.mjs.map +1 -0
  748. package/dist/substrate/runtime/supervisor/background-tasks.mjs +144 -0
  749. package/dist/substrate/runtime/supervisor/background-tasks.mjs.map +1 -0
  750. package/dist/substrate/runtime/supervisor/command-loop.mjs +68 -0
  751. package/dist/substrate/runtime/supervisor/command-loop.mjs.map +1 -0
  752. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs +151 -0
  753. package/dist/substrate/runtime/supervisor/dispatch-contributions.mjs.map +1 -0
  754. package/dist/substrate/runtime/supervisor/errors.d.mts +1 -0
  755. package/dist/substrate/runtime/supervisor/errors.mjs +9 -0
  756. package/dist/substrate/runtime/supervisor/errors.mjs.map +1 -0
  757. package/dist/substrate/runtime/supervisor/index.d.mts +1 -0
  758. package/dist/substrate/runtime/supervisor/index.mjs +3 -0
  759. package/dist/substrate/runtime/supervisor/shutdown.mjs +51 -0
  760. package/dist/substrate/runtime/supervisor/shutdown.mjs.map +1 -0
  761. package/dist/substrate/runtime/supervisor/start-supervisor.d.mts +1 -0
  762. package/dist/substrate/runtime/supervisor/start-supervisor.mjs +250 -0
  763. package/dist/substrate/runtime/supervisor/start-supervisor.mjs.map +1 -0
  764. package/dist/substrate/runtime/supervisor/state.d.mts +1 -0
  765. package/dist/substrate/runtime/supervisor/state.mjs +22 -0
  766. package/dist/substrate/runtime/supervisor/state.mjs.map +1 -0
  767. package/dist/substrate/runtime/supervisor/teardown.mjs +57 -0
  768. package/dist/substrate/runtime/supervisor/teardown.mjs.map +1 -0
  769. package/dist/substrate/runtime/supervisor/types.d.mts +1 -0
  770. package/dist/substrate/runtime/supervisor/wiring.mjs +133 -0
  771. package/dist/substrate/runtime/supervisor/wiring.mjs.map +1 -0
  772. package/dist/substrate/runtime/typed-env.mjs +8 -0
  773. package/dist/substrate/runtime/typed-env.mjs.map +1 -0
  774. package/dist/substrate/state-store.d.mts +1 -0
  775. package/dist/substrate/versioned-doc-schema.mjs +17 -0
  776. package/dist/substrate/versioned-doc-schema.mjs.map +1 -0
  777. package/dist/substrate/versioned-doc-sync.mjs +94 -0
  778. package/dist/substrate/versioned-doc-sync.mjs.map +1 -0
  779. package/dist/surfaces/cli/command-tree.mjs.map +1 -1
  780. package/dist/surfaces/cli/commands/index.mjs +9 -0
  781. package/dist/surfaces/cli/commands/prune-picker-entry.mjs +13 -0
  782. package/dist/surfaces/cli/commands/prune-picker-entry.mjs.map +1 -0
  783. package/dist/surfaces/cli/commands/prune-picker.mjs +3 -2
  784. package/dist/surfaces/cli/commands/prune-picker.mjs.map +1 -1
  785. package/dist/surfaces/cli/commands/prune.mjs +34 -17
  786. package/dist/surfaces/cli/commands/prune.mjs.map +1 -1
  787. package/dist/surfaces/cli/commands/status.mjs +2 -2
  788. package/dist/surfaces/cli/commands/status.mjs.map +1 -1
  789. package/dist/surfaces/cli/commands/supervisor-presence.mjs +5 -3
  790. package/dist/surfaces/cli/commands/supervisor-presence.mjs.map +1 -1
  791. package/dist/surfaces/cli/commands/wipe.mjs +38 -4
  792. package/dist/surfaces/cli/commands/wipe.mjs.map +1 -1
  793. package/dist/surfaces/cli/errors.mjs +1 -1
  794. package/dist/surfaces/cli/errors.mjs.map +1 -1
  795. package/dist/surfaces/cli/flags.mjs +0 -1
  796. package/dist/surfaces/cli/flags.mjs.map +1 -1
  797. package/dist/surfaces/cli/index.mjs +98 -18
  798. package/dist/surfaces/cli/index.mjs.map +1 -1
  799. package/dist/surfaces/cli/output.mjs +1 -0
  800. package/dist/surfaces/cli/output.mjs.map +1 -1
  801. package/dist/surfaces/cli/sysexits.mjs +2 -1
  802. package/dist/surfaces/cli/sysexits.mjs.map +1 -1
  803. package/dist/surfaces/tui/app.mjs +25 -3
  804. package/dist/surfaces/tui/app.mjs.map +1 -1
  805. package/dist/surfaces/tui/display-derivation.mjs +23 -74
  806. package/dist/surfaces/tui/display-derivation.mjs.map +1 -1
  807. package/dist/surfaces/tui/event-log.mjs +35 -23
  808. package/dist/surfaces/tui/event-log.mjs.map +1 -1
  809. package/dist/surfaces/tui/input.mjs +5 -1
  810. package/dist/surfaces/tui/input.mjs.map +1 -1
  811. package/dist/surfaces/tui/plain-renderer.mjs +70 -34
  812. package/dist/surfaces/tui/plain-renderer.mjs.map +1 -1
  813. package/package.json +24 -4
  814. package/dist/contracts/liveness-classifier.d.mts +0 -19
  815. package/dist/contracts/network-resolver.d.mts +0 -15
  816. package/dist/contracts/network-resolver.mjs +0 -7
  817. package/dist/contracts/network-resolver.mjs.map +0 -1
  818. package/dist/orchestrators/codegen/extras.mjs +0 -16
  819. package/dist/orchestrators/codegen/extras.mjs.map +0 -1
  820. package/dist/plugins/deepbook/routable.mjs +0 -21
  821. package/dist/plugins/deepbook/routable.mjs.map +0 -1
  822. package/dist/plugins/faucet/service.d.mts +0 -20
  823. package/dist/plugins/faucet/strategies/sui-local.d.mts +0 -23
  824. package/dist/plugins/faucet/strategies/sui-local.mjs.map +0 -1
  825. package/dist/plugins/sui/seed-objects.d.mts +0 -18
  826. package/dist/plugins/sui/seed-objects.mjs +0 -25
  827. package/dist/plugins/sui/seed-objects.mjs.map +0 -1
  828. package/dist/runtime/built-in-plugin-layers.mjs.map +0 -1
  829. package/dist/substrate/runtime/context-helpers.mjs +0 -32
  830. package/dist/substrate/runtime/context-helpers.mjs.map +0 -1
  831. package/dist/substrate/runtime/run.mjs.map +0 -1
  832. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs +0 -30
  833. package/dist/substrate/runtime/strategy-registry/faucet-capability-for.mjs.map +0 -1
  834. package/dist/substrate/runtime/supervisor.d.mts +0 -1
  835. package/dist/substrate/runtime/supervisor.mjs +0 -831
  836. package/dist/substrate/runtime/supervisor.mjs.map +0 -1
  837. package/dist/surfaces/cli/commands/doctor-probes.mjs.map +0 -1
  838. /package/dist/{substrate/runtime/strategy-registry/faucet-capability-for.d.mts → plugins/faucet/http.d.mts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"main.mjs","names":["resolvePath","m"],"sources":["../../src/cli/main.ts"],"sourcesContent":["// devstack CLI bin entry — argv → dispatch → exit.\n//\n// This file is the executable entry the `bin: { devstack: ... }`\n// package.json field points at. Build output: `dist/cli/main.mjs`.\n//\n// Architecture invariant (surfaces/cli/index.ts header):\n// \"`up` must hand its long-running effect to the outer Node runtime\n// directly, not nest a runtime — otherwise SIGINT cannot reach\n// scope finalizers and container teardown leaks.\"\n//\n// Shape:\n// 1. The Stricli-backed dispatcher validates argv and builds command-\n// scoped flags.\n// 2. Attached `up` constructs substrate Layers directly so signals\n// reach scope finalizers.\n// 3. `apply` is live-aware: publish to an attached supervisor when\n// one owns the selected stack; otherwise run the one-shot path.\n// 4. Offline/direct commands read or mutate the selected stack root\n// without publishing peer commands to a live supervisor.\n\nimport { existsSync, realpathSync } from 'node:fs';\nimport { dirname, isAbsolute, resolve as resolvePath } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport {\n\tCause,\n\tEffect,\n\tExit,\n\tFileSystem,\n\tLayer,\n\tLogger,\n\tQueue,\n\tScope,\n\tStream,\n\tSubscriptionRef,\n} from 'effect';\n\nimport { appName, chainId, stackName } from '../substrate/brand.ts';\nimport type { Identity } from '../substrate/identity.ts';\nimport type { EngineCommand, EngineEvent } from '../substrate/events.ts';\nimport type { SubscribableState } from '../substrate/projection.ts';\nimport { StackPathsService } from '../substrate/runtime/paths.ts';\nimport {\n\tmakeProjectionRef,\n\tpersistProjectionChanges,\n\treadProjectionSnapshot,\n\tclaim,\n\tcommandChannelPaths,\n\theartbeatFiber,\n\tmakeCommandChannelPublisher,\n\tmakeCommandChannelSubscriber,\n\trelease,\n\ttype SupervisedStack,\n\ttype SupervisorCommandHandler,\n\ttype SupervisorHandle,\n\twriteProjectionSnapshot,\n} from '../substrate/runtime/index.ts';\nimport { buildSubstrateLayers, superviseStackEffect } from '../substrate/runtime/run.ts';\n\nimport {\n\tdispatch,\n\ttype CliDeps,\n\tCliConfigInvalidError,\n\tCliConfigNotFoundError,\n\tCliSupervisorLiveError,\n} from '../surfaces/cli/index.ts';\nimport { defaultProbes, probeSupervisorPresence } from '../surfaces/cli/commands/index.ts';\nimport { nodeConfirmPrompt } from '../surfaces/cli/commands/confirm-node.ts';\nimport type { LoadedConfig } from '../surfaces/cli/commands/config-loader.ts';\nimport {\n\tSnapshotOrchestratorService,\n\ttype RestoreParticipant,\n\ttype SnapshotMetadata,\n} from '../orchestrators/snapshot/index.ts';\nimport {\n\tbuildProductionOrchestratorSinks,\n\tbuildProductionPostAcquireHook,\n\tlayerProductionOrchestrators,\n} from '../orchestrators/runtime-composition.ts';\nimport {\n\textendBuiltInPluginContext,\n\tlayerBuiltInPluginRuntime,\n} from '../runtime/built-in-plugin-layers.ts';\nimport type { StatusReader } from '../surfaces/cli/commands/status.ts';\nimport type { GlobalFlags } from '../surfaces/cli/flags.ts';\nimport { ExitCode } from '../surfaces/cli/sysexits.ts';\nimport { makeTuiSurface } from '../surfaces/tui/index.ts';\nimport { makeSnapshotReader } from './snapshot-reader.ts';\nimport { makeQueueCommandPublisher, resolveUpRendererMode } from './up-lifecycle.ts';\nimport { resolveAppName, resolveStackName } from '../api/inference-network.ts';\nimport { readStackEngine, type Stack } from '../api/define-devstack.ts';\nimport { makeDirectPruneDeps } from './prune-direct.ts';\nimport { removeRouterDispatchFilesForStack } from '../orchestrators/router/cleanup.ts';\n\n// -----------------------------------------------------------------------------\n// Config loader (default-export = Stack)\n// -----------------------------------------------------------------------------\n\nconst DEFAULT_CONFIG_PATH = './devstack.config.ts';\nconst LIVE_APPLY_ACK_TIMEOUT_MILLIS = 10 * 60 * 1000;\n\nconst stackRootFor = (runtimeRoot: string, stack: string): string =>\n\tresolvePath(runtimeRoot, 'stacks', stack);\n\nconst rosterPathsFor = (stackRoot: string) => ({\n\tstackLockFile: resolvePath(stackRoot, 'stack.lock'),\n\trosterFile: resolvePath(stackRoot, 'roster.json'),\n});\n\nconst ENGINE_COMMAND_TAGS = new Set<EngineCommand['tag']>([\n\t'stack.start',\n\t'stack.stop',\n\t'stack.restart',\n\t'apply.requested',\n\t'codegen.requested',\n\t'snapshot.capture',\n\t'snapshot.restore',\n\t'snapshot.list',\n\t'snapshot.delete',\n\t'wipe.requested',\n\t'prune.requested',\n\t'advance-clock.requested',\n\t'shutdown.requested',\n\t'shutdown.hardKillRequested',\n\t'selective-restart.requested',\n]);\n\nconst hasString = (value: Record<string, unknown>, key: string): boolean =>\n\ttypeof value[key] === 'string';\n\nconst isEngineCommand = (value: unknown): value is EngineCommand => {\n\tif (typeof value !== 'object' || value === null) return false;\n\tconst record = value as Record<string, unknown>;\n\tif (\n\t\ttypeof record.tag !== 'string' ||\n\t\t!ENGINE_COMMAND_TAGS.has(record.tag as EngineCommand['tag'])\n\t) {\n\t\treturn false;\n\t}\n\tswitch (record.tag) {\n\t\tcase 'snapshot.restore':\n\t\tcase 'snapshot.delete':\n\t\t\treturn hasString(record, 'snapshotId');\n\t\tcase 'advance-clock.requested':\n\t\t\treturn typeof record.toMillis === 'number';\n\t\tcase 'shutdown.hardKillRequested':\n\t\t\treturn (\n\t\t\t\t(record.signal === 'SIGINT' || record.signal === 'SIGTERM') &&\n\t\t\t\ttypeof record.exitCode === 'number' &&\n\t\t\t\ttypeof record.at === 'number'\n\t\t\t);\n\t\tcase 'selective-restart.requested':\n\t\t\treturn hasString(record, 'pluginKey');\n\t\tcase 'apply.requested':\n\t\t\treturn record.pluginKey === undefined || typeof record.pluginKey === 'string';\n\t\tcase 'snapshot.capture':\n\t\t\treturn (\n\t\t\t\t(record.snapshotId === undefined || typeof record.snapshotId === 'string') &&\n\t\t\t\t(record.name === undefined || typeof record.name === 'string')\n\t\t\t);\n\t\tdefault:\n\t\t\treturn true;\n\t}\n};\n\nconst findCliSupervisorLiveError = (cause: Cause.Cause<unknown>): CliSupervisorLiveError | null => {\n\tfor (const reason of cause.reasons) {\n\t\tif (!Cause.isFailReason(reason)) continue;\n\t\tconst error = reason.error;\n\t\tif (error instanceof CliSupervisorLiveError) return error;\n\t\tif (\n\t\t\ttypeof error === 'object' &&\n\t\t\terror !== null &&\n\t\t\t(error as { readonly _tag?: unknown })._tag === 'CliSupervisorLiveError'\n\t\t) {\n\t\t\treturn error as CliSupervisorLiveError;\n\t\t}\n\t}\n\treturn null;\n};\n\nconst resolveConfigPath = (configPath: string | undefined): string | null => {\n\tconst target = configPath ?? DEFAULT_CONFIG_PATH;\n\tconst explicit = isAbsolute(target) ? target : resolvePath(process.cwd(), target);\n\tif (existsSync(explicit)) return explicit;\n\tif (configPath !== undefined && configPath !== DEFAULT_CONFIG_PATH) return null;\n\tlet dir = process.cwd();\n\tfor (;;) {\n\t\tconst candidate = resolvePath(dir, 'devstack.config.ts');\n\t\tif (existsSync(candidate)) return candidate;\n\t\tconst parent = resolvePath(dir, '..');\n\t\tif (parent === dir) return null;\n\t\tdir = parent;\n\t}\n};\n\ninterface RawConfigModule {\n\treadonly default?: unknown;\n}\n\nconst validateStackModule = (\n\tresolvedConfigPath: string,\n\tmod: unknown,\n): LoadedConfig & { readonly stack: SupervisedStack } => {\n\tconst m = mod as RawConfigModule;\n\tconst def = m.default;\n\tif (def === null || typeof def !== 'object' || (def as { _tag?: unknown })._tag !== 'Stack') {\n\t\tthrow new CliConfigInvalidError({\n\t\t\tmessage: `config at ${resolvedConfigPath} does not default-export a Stack value (got _tag=${String((def as { _tag?: unknown })?._tag)})`,\n\t\t});\n\t}\n\tlet stack: SupervisedStack;\n\ttry {\n\t\tstack = readStackEngine(def as Stack<SupervisedStack['members']>);\n\t} catch (cause) {\n\t\tthrow new CliConfigInvalidError({\n\t\t\tmessage: `config at ${resolvedConfigPath} default-exported an invalid Stack handle: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t});\n\t}\n\treturn {\n\t\tstack,\n\t\tresolvedConfigPath,\n\t};\n};\n\nconst makeConfigLoader = () => ({\n\tload: (configPath: string | undefined) =>\n\t\tEffect.gen(function* () {\n\t\t\tconst abs = resolveConfigPath(configPath);\n\t\t\tif (abs === null) {\n\t\t\t\tconst attempted =\n\t\t\t\t\tconfigPath !== undefined\n\t\t\t\t\t\t? resolvePath(process.cwd(), configPath)\n\t\t\t\t\t\t: resolvePath(process.cwd(), DEFAULT_CONFIG_PATH);\n\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\tnew CliConfigNotFoundError({\n\t\t\t\t\t\tmessage: `devstack config not found at ${attempted}`,\n\t\t\t\t\t\tsearchedPaths: [attempted],\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst url = pathToFileURL(abs).href;\n\t\t\tconst mod = yield* Effect.tryPromise({\n\t\t\t\ttry: () => import(url) as Promise<unknown>,\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tnew CliConfigInvalidError({\n\t\t\t\t\t\tmessage: `failed to import ${abs}: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t\t\t\tcause,\n\t\t\t\t\t}),\n\t\t\t});\n\t\t\treturn yield* Effect.try({\n\t\t\t\ttry: () => validateStackModule(abs, mod),\n\t\t\t\tcatch: (cause) =>\n\t\t\t\t\tcause instanceof CliConfigInvalidError\n\t\t\t\t\t\t? cause\n\t\t\t\t\t\t: new CliConfigInvalidError({\n\t\t\t\t\t\t\t\tmessage: `invalid config at ${abs}`,\n\t\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t\t}),\n\t\t\t});\n\t\t}) as Effect.Effect<LoadedConfig, CliConfigNotFoundError | CliConfigInvalidError>,\n});\n\n// -----------------------------------------------------------------------------\n// Identity resolution\n// -----------------------------------------------------------------------------\n\ninterface ResolvedIdentity {\n\treadonly app: string;\n\treadonly stack: string;\n\treadonly network: string;\n\treadonly runtimeRoot: string;\n\treadonly stacksRoot: string;\n\treadonly stackRoot: string;\n\treadonly rosterFile: string;\n}\n\n/** Resolve identity from flags + env. App and stack fall through the\n * shared cwd/package metadata resolver before their defaults. */\nconst resolveIdentity = (params: {\n\treadonly app: string | undefined;\n\treadonly stack: string | undefined;\n\treadonly network: string | undefined;\n\treadonly stateDir: string | undefined;\n\treadonly cwd?: string;\n}): ResolvedIdentity => {\n\tconst cwd = params.cwd ?? process.cwd();\n\tconst app = resolveAppName({\n\t\texplicit: params.app,\n\t\tcwd,\n\t});\n\tconst stateDir =\n\t\tparams.stateDir ??\n\t\tprocess.env.DEVSTACK_STATE_DIR ??\n\t\tresolvePath(process.env.HOME ?? process.cwd(), '.devstack');\n\tconst runtimeRoot = resolvePath(stateDir);\n\tconst stacksRoot = resolvePath(runtimeRoot, 'stacks');\n\tconst stack = resolveStackName({\n\t\texplicit: params.stack,\n\t\tcwd,\n\t});\n\tconst network = params.network ?? process.env.DEVSTACK_NETWORK ?? 'sui:local';\n\tconst stackRoot = resolvePath(stacksRoot, stack);\n\treturn {\n\t\tapp,\n\t\tstack,\n\t\tnetwork,\n\t\truntimeRoot,\n\t\tstacksRoot,\n\t\tstackRoot,\n\t\trosterFile: resolvePath(stackRoot, 'roster.json'),\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// Verb deps composition (attached + direct/offline)\n// -----------------------------------------------------------------------------\n\nconst projectionStatusReader = (identity: ResolvedIdentity): StatusReader => ({\n\treadState: (_app, _stack) =>\n\t\tEffect.sync(() => readProjectionSnapshot(identity.stackRoot) as SubscribableState | null),\n});\n\nconst commandResultFromProcess = (): { readonly exitCode: number } => ({\n\texitCode: typeof process.exitCode === 'number' ? process.exitCode : 0,\n});\n\nconst buildDirectDeps = (identity: ResolvedIdentity): CliDeps => {\n\tconst loader = makeConfigLoader();\n\treturn {\n\t\tup: {\n\t\t\trun: (flags) =>\n\t\t\t\trunUpLive(flags.configPath, identity, {\n\t\t\t\t\trenderer: flags.renderer,\n\t\t\t\t\tstdoutIsTty: Boolean((process.stdout as { isTTY?: boolean }).isTTY),\n\t\t\t\t}).pipe(Effect.map(() => commandResultFromProcess())),\n\t\t},\n\t\tapply: {\n\t\t\trun: (flags) =>\n\t\t\t\trunApplyLive(flags.configPath, identity).pipe(Effect.map(() => commandResultFromProcess())),\n\t\t},\n\t\tstatus: { reader: projectionStatusReader(identity) },\n\t\tsnapshot: makeDirectSnapshotDeps(identity),\n\t\tprune: makeDirectPruneDeps({ runtimeRoot: identity.runtimeRoot }),\n\t\tdoctor: {\n\t\t\tprobes: defaultProbes({\n\t\t\t\tstateDir: identity.runtimeRoot,\n\t\t\t\tappRoot: identity.stacksRoot,\n\t\t\t}),\n\t\t},\n\t\tconfig: { loader },\n\t\twipe: {\n\t\t\twipe: () => runWipeDirect(identity),\n\t\t\tconfirm: nodeConfirmPrompt,\n\t\t},\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// `up` — live wiring\n// -----------------------------------------------------------------------------\n\nconst makeSnapshotCommandHandler = (params: {\n\treadonly snapshot: import('../orchestrators/snapshot/index.ts').SnapshotOrchestrator;\n\treadonly fs: FileSystem.FileSystem;\n}): SupervisorCommandHandler => {\n\tconst provideFileSystem = <A, E>(\n\t\teffect: Effect.Effect<A, E, FileSystem.FileSystem>,\n\t): Effect.Effect<A, E, never> =>\n\t\teffect.pipe(Effect.provideService(FileSystem.FileSystem, params.fs));\n\n\treturn (cmd, handlerCtx) => {\n\t\tswitch (cmd.tag) {\n\t\t\tcase 'snapshot.capture':\n\t\t\t\treturn provideFileSystem(\n\t\t\t\t\tparams.snapshot.capture({\n\t\t\t\t\t\tid: cmd.snapshotId,\n\t\t\t\t\t\tlabel: cmd.name,\n\t\t\t\t\t\tonProgress: (progress) =>\n\t\t\t\t\t\t\thandlerCtx.publish({\n\t\t\t\t\t\t\t\ttag: 'snapshot.captureProgress',\n\t\t\t\t\t\t\t\t...(cmd.snapshotId === undefined ? {} : { snapshotId: cmd.snapshotId }),\n\t\t\t\t\t\t\t\t...(cmd.name === undefined ? {} : { name: cmd.name }),\n\t\t\t\t\t\t\t\tphase: progress.phase,\n\t\t\t\t\t\t\t\t...(progress.detail === undefined ? {} : { detail: progress.detail }),\n\t\t\t\t\t\t\t\t...(progress.pausedContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { pausedContainers: progress.pausedContainers }),\n\t\t\t\t\t\t\t\t...(progress.totalContainers === undefined\n\t\t\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t\t\t: { totalContainers: progress.totalContainers }),\n\t\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t}),\n\t\t\t\t).pipe(\n\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'snapshot.captured',\n\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\t...(meta.label === null ? {} : { name: meta.label }),\n\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\tcase 'snapshot.restore':\n\t\t\t\treturn provideFileSystem(params.snapshot.restore({ id: cmd.snapshotId })).pipe(\n\t\t\t\t\tEffect.map((meta) => [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttag: 'snapshot.restored',\n\t\t\t\t\t\t\tsnapshotId: meta.id,\n\t\t\t\t\t\t\tat: Date.now(),\n\t\t\t\t\t\t},\n\t\t\t\t\t]),\n\t\t\t\t);\n\t\t\tcase 'snapshot.list':\n\t\t\t\treturn provideFileSystem(params.snapshot.list).pipe(Effect.as([]));\n\t\t\tcase 'snapshot.delete':\n\t\t\t\treturn provideFileSystem(params.snapshot.delete(cmd.snapshotId)).pipe(Effect.as([]));\n\t\t\tcase 'wipe.requested':\n\t\t\t\treturn provideFileSystem(params.snapshot.wipe({})).pipe(Effect.as([]));\n\t\t\tcase 'prune.requested':\n\t\t\t\treturn provideFileSystem(params.snapshot.prune({})).pipe(Effect.as([]));\n\t\t\tdefault:\n\t\t\t\treturn Effect.succeed([]);\n\t\t}\n\t};\n};\n\nconst installLiveSupervisorRoster = (params: {\n\treadonly stackRoot: string;\n\treadonly app: string;\n\treadonly stack: string;\n}): Effect.Effect<void, unknown, Scope.Scope> =>\n\tEffect.gen(function* () {\n\t\tconst paths = rosterPathsFor(params.stackRoot);\n\t\tconst claimed = yield* claim(paths);\n\t\tif (!claimed.soleHolder) {\n\t\t\tyield* release(paths).pipe(Effect.catch(() => Effect.void));\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliSupervisorLiveError({\n\t\t\t\t\tapp: params.app,\n\t\t\t\t\tstack: params.stack,\n\t\t\t\t\thint: 'use `devstack apply` from another shell, or choose a different --stack name',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t\tyield* Effect.addFinalizer(() => release(paths).pipe(Effect.catch(() => Effect.void)));\n\t\tyield* Effect.forkScoped(heartbeatFiber(paths));\n\t});\n\nconst installCommandChannelBridge = (params: {\n\treadonly stackRoot: string;\n\treadonly handle: SupervisorHandle;\n}): Effect.Effect<\n\t{\n\t\treadonly publishEvent: (event: EngineEvent) => Effect.Effect<void>;\n\t},\n\tunknown,\n\tScope.Scope\n> =>\n\tEffect.gen(function* () {\n\t\tconst subscriber = yield* makeCommandChannelSubscriber(commandChannelPaths(params.stackRoot), {\n\t\t\tfromOffset: 'current',\n\t\t});\n\n\t\tyield* Effect.forkScoped(\n\t\t\tsubscriber.commands.pipe(\n\t\t\t\tStream.runForEach((record) =>\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tif (!isEngineCommand(record.command)) {\n\t\t\t\t\t\t\tyield* subscriber\n\t\t\t\t\t\t\t\t.fail(record.id, 'invalid command', 'command payload did not match EngineCommand')\n\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tyield* params.handle.runCommand(record.command).pipe(\n\t\t\t\t\t\t\tEffect.andThen(subscriber.ack(record.id)),\n\t\t\t\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\t\t\t\tsubscriber\n\t\t\t\t\t\t\t\t\t.fail(record.id, 'command failed', Cause.pretty(cause as Cause.Cause<unknown>))\n\t\t\t\t\t\t\t\t\t.pipe(Effect.catch(() => Effect.void)),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tEffect.catchCause((cause) =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t`command channel failed: ${Cause.pretty(cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t),\n\t\t);\n\n\t\treturn {\n\t\t\tpublishEvent: (event: EngineEvent) =>\n\t\t\t\tsubscriber.publishEvent(event).pipe(Effect.catch(() => Effect.void)),\n\t\t};\n\t});\n\n/**\n * Run `devstack up`. Wires the substrate Layer stack, supervisor,\n * attached renderer, and in-process TUI command queue. The Effect runs\n * as the outer Node fiber so SIGINT reaches scope finalizers.\n */\nconst runUpLive = (\n\tconfigPath: string | undefined,\n\tidentity: ResolvedIdentity,\n\toptions: {\n\t\treadonly renderer: GlobalFlags['renderer'];\n\t\treadonly stdoutIsTty: boolean;\n\t},\n): Effect.Effect<void> => {\n\tconst loader = makeConfigLoader();\n\treturn Effect.gen(function* () {\n\t\tconst loaded = yield* loader.load(configPath).pipe(\n\t\t\tEffect.catch((err) =>\n\t\t\t\tEffect.sync(() => {\n\t\t\t\t\tprocess.stderr.write(`error: ${err.message}\\n`);\n\t\t\t\t\tprocess.exitCode = err._tag === 'CliConfigNotFoundError' ? 66 : 78;\n\t\t\t\t\treturn null;\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t\tif (loaded === null) return;\n\t\tconst stack = (loaded as LoadedConfig & { readonly stack: SupervisedStack }).stack;\n\n\t\tconst identityValue: Identity = {\n\t\t\tapp: appName(identity.app),\n\t\t\tstack: stackName(stack.options.stackName ?? identity.stack),\n\t\t\tchain: chainId(identity.network),\n\t\t};\n\n\t\tconst appRoot = dirname(loaded.resolvedConfigPath);\n\t\tconst rendererMode = resolveUpRendererMode({\n\t\t\tcliRenderer: options.renderer,\n\t\t\tstackRenderer: stack.options.renderer,\n\t\t\tstdoutIsTty: options.stdoutIsTty,\n\t\t});\n\t\tconst substrateLayers = layerProductionOrchestrators({\n\t\t\tcodegen: {\n\t\t\t\tappRoot,\n\t\t\t\toutputDir: stack.options.codegen?.outputDir,\n\t\t\t\tstackSubdir: stack.options.codegen?.stackSubdir ?? null,\n\t\t\t},\n\t\t}).pipe(Layer.provideMerge(buildSubstrateLayers(identityValue, identity.runtimeRoot)));\n\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst state = yield* makeProjectionRef();\n\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst snapshotCommandHandler = makeSnapshotCommandHandler({ snapshot, fs });\n\t\t\tconst orchestratorSinks = yield* buildProductionOrchestratorSinks();\n\t\t\tconst postAcquireHook = yield* buildProductionPostAcquireHook({\n\t\t\t\textras: stack.options.extras,\n\t\t\t});\n\t\t\tyield* superviseStackEffect(\n\t\t\t\t{ _tag: 'Stack', members: stack.members, options: stack.options },\n\t\t\t\tidentityValue,\n\t\t\t\tstate,\n\t\t\t\t{\n\t\t\t\t\torchestratorSinks,\n\t\t\t\t\tcommandHandler: snapshotCommandHandler,\n\t\t\t\t\tpostAcquireHook,\n\t\t\t\t\textendContext: extendBuiltInPluginContext,\n\t\t\t\t\tbeforeInitialAcquire: (handle) =>\n\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\tconst stackPaths = yield* StackPathsService;\n\t\t\t\t\t\t\tconst commandChannel = yield* installCommandChannelBridge({\n\t\t\t\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\t\t\t\thandle,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tyield* installLiveSupervisorRoster({\n\t\t\t\t\t\t\t\tstackRoot: stackPaths.stackRoot,\n\t\t\t\t\t\t\t\tapp: String(identityValue.app),\n\t\t\t\t\t\t\t\tstack: String(identityValue.stack),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tconst rendererEvents = yield* Queue.unbounded<EngineEvent>();\n\t\t\t\t\t\t\tconst renderer = makeTuiSurface({\n\t\t\t\t\t\t\t\tmode: rendererMode,\n\t\t\t\t\t\t\t\tpublishCommand: makeQueueCommandPublisher(handle.commands),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tyield* Effect.addFinalizer(() =>\n\t\t\t\t\t\t\t\trenderer.flush.pipe(Effect.catch(() => Effect.void)),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\trenderer.mount(handle.state, Stream.fromQueue(rendererEvents)).pipe(\n\t\t\t\t\t\t\t\t\tEffect.catch((cause) =>\n\t\t\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\t\t\tprocess.stderr.write(`renderer failed: ${cause.detail ?? String(cause)}\\n`);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\tpersistProjectionChanges(stackPaths.stackRoot, handle.state),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tyield* Effect.forkScoped(\n\t\t\t\t\t\t\t\tStream.fromQueue(handle.events).pipe(\n\t\t\t\t\t\t\t\t\tStream.runForEach((event) =>\n\t\t\t\t\t\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\t\t\t\t\t\tyield* Queue.offer(rendererEvents, event);\n\t\t\t\t\t\t\t\t\t\t\tyield* commandChannel.publishEvent(event);\n\t\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t).pipe(Effect.provide(layerBuiltInPluginRuntime(orchestratorSinks)));\n\t\t});\n\n\t\tyield* program.pipe(\n\t\t\tEffect.provide(substrateLayers),\n\t\t\tEffect.provide(Logger.layer([])),\n\t\t\tEffect.matchCauseEffect({\n\t\t\t\tonFailure: (cause) =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tconst live = findCliSupervisorLiveError(cause as Cause.Cause<unknown>);\n\t\t\t\t\t\tif (live !== null) {\n\t\t\t\t\t\t\tprocess.stderr.write(`error: supervisor live for ${live.app}/${live.stack}\\n`);\n\t\t\t\t\t\t\tif (live.hint !== undefined) {\n\t\t\t\t\t\t\t\tprocess.stderr.write(`hint: ${live.hint}\\n`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tprocess.exitCode = ExitCode.SUPERVISOR_LIVE;\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t`\\nerror: stack failed\\n${Cause.pretty(cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}),\n\t\t\t\tonSuccess: () =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tprocess.exitCode ??= 0;\n\t\t\t\t\t}),\n\t\t\t}),\n\t\t);\n\t});\n};\n\nconst runApplyAgainstLiveSupervisor = (\n\tidentity: ResolvedIdentity,\n\tidentityValue: Identity,\n): Effect.Effect<boolean> =>\n\tEffect.gen(function* () {\n\t\tconst stackRoot = stackRootFor(identity.runtimeRoot, String(identityValue.stack));\n\t\tconst presence = yield* probeSupervisorPresence(resolvePath(stackRoot, 'roster.json')).pipe(\n\t\t\tEffect.catch(() => Effect.succeed({ live: false, pid: null, hostname: null })),\n\t\t);\n\t\tif (!presence.live) return false;\n\n\t\tconst exit = yield* Effect.exit(\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst publisher = yield* makeCommandChannelPublisher(commandChannelPaths(stackRoot));\n\t\t\t\tconst published = yield* publisher.publish({ tag: 'apply.requested' });\n\t\t\t\tconst reply = yield* publisher.awaitCompletion(published.id, {\n\t\t\t\t\ttimeoutMillis: LIVE_APPLY_ACK_TIMEOUT_MILLIS,\n\t\t\t\t});\n\t\t\t\tif (!reply.ok) {\n\t\t\t\t\treturn yield* Effect.fail(reply.message);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\n\t\tif (Exit.isFailure(exit)) {\n\t\t\tprocess.stderr.write(\n\t\t\t\t`\\nerror: live stack apply failed\\n${Cause.pretty(exit.cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn true;\n\t\t}\n\n\t\tprocess.exitCode ??= 0;\n\t\treturn true;\n\t});\n\nconst runApplyLive = (\n\tconfigPath: string | undefined,\n\tidentity: ResolvedIdentity,\n): Effect.Effect<void> => {\n\tconst loader = makeConfigLoader();\n\treturn Effect.gen(function* () {\n\t\tconst loaded = yield* loader.load(configPath).pipe(\n\t\t\tEffect.matchEffect({\n\t\t\t\tonFailure: (err) =>\n\t\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\t\tprocess.stderr.write(`error: ${err.message}\\n`);\n\t\t\t\t\t\tprocess.exitCode = err._tag === 'CliConfigNotFoundError' ? 66 : 78;\n\t\t\t\t\t\treturn yield* Effect.fail('config-load-failed' as const);\n\t\t\t\t\t}),\n\t\t\t\tonSuccess: (v) => Effect.succeed(v),\n\t\t\t}),\n\t\t);\n\t\tconst stack = (loaded as LoadedConfig & { readonly stack: SupervisedStack }).stack;\n\t\tconst identityValue: Identity = {\n\t\t\tapp: appName(identity.app),\n\t\t\tstack: stackName(stack.options.stackName ?? identity.stack),\n\t\t\tchain: chainId(identity.network),\n\t\t};\n\t\tif (yield* runApplyAgainstLiveSupervisor(identity, identityValue)) {\n\t\t\treturn;\n\t\t}\n\t\tconst appRoot = dirname(loaded.resolvedConfigPath);\n\t\tconst substrateLayers = layerProductionOrchestrators({\n\t\t\tcodegen: {\n\t\t\t\tappRoot,\n\t\t\t\toutputDir: stack.options.codegen?.outputDir,\n\t\t\t\tstackSubdir: stack.options.codegen?.stackSubdir ?? null,\n\t\t\t},\n\t\t}).pipe(Layer.provideMerge(buildSubstrateLayers(identityValue, identity.runtimeRoot)));\n\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst state = yield* makeProjectionRef();\n\t\t\tconst orchestratorSinks = yield* buildProductionOrchestratorSinks();\n\t\t\tconst postAcquireHook = yield* buildProductionPostAcquireHook({\n\t\t\t\textras: stack.options.extras,\n\t\t\t});\n\t\t\tyield* superviseStackEffect(\n\t\t\t\t{ _tag: 'Stack', members: stack.members, options: stack.options },\n\t\t\t\tidentityValue,\n\t\t\t\tstate,\n\t\t\t\t{\n\t\t\t\t\torchestratorSinks,\n\t\t\t\t\tpostAcquireHook,\n\t\t\t\t\tlifetime: 'one-shot',\n\t\t\t\t\textendContext: extendBuiltInPluginContext,\n\t\t\t\t},\n\t\t\t).pipe(Effect.provide(layerBuiltInPluginRuntime(orchestratorSinks)));\n\t\t\tconst stackPaths = yield* StackPathsService;\n\t\t\tyield* writeProjectionSnapshot(stackPaths.stackRoot, yield* SubscriptionRef.get(state));\n\t\t});\n\n\t\tyield* program.pipe(\n\t\t\tEffect.provide(substrateLayers),\n\t\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t\t\tEffect.matchCauseEffect({\n\t\t\t\tonFailure: (cause) =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tprocess.stderr.write(\n\t\t\t\t\t\t\t`\\nerror: stack apply failed\\n${Cause.pretty(cause as Cause.Cause<unknown>)}\\n`,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t}),\n\t\t\t\tonSuccess: () =>\n\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\tprocess.exitCode ??= 0;\n\t\t\t\t\t}),\n\t\t\t}),\n\t\t);\n\t}).pipe(Effect.catch(() => Effect.void));\n};\n\nconst snapshotIdentityParticipants = (meta: SnapshotMetadata): ReadonlyArray<RestoreParticipant> =>\n\tObject.entries(meta.identity).map(([plugin, value]) => ({\n\t\tplugin,\n\t\tliveIdentity: Effect.succeed({ [plugin]: value }),\n\t}));\n\nconst identityValueFor = (identity: ResolvedIdentity, stack?: SupervisedStack): Identity => ({\n\tapp: appName(identity.app),\n\tstack: stackName(stack?.options.stackName ?? identity.stack),\n\tchain: chainId(identity.network),\n});\n\nconst directSnapshotLayers = (identity: ResolvedIdentity) =>\n\tlayerProductionOrchestrators().pipe(\n\t\tLayer.provideMerge(buildSubstrateLayers(identityValueFor(identity), identity.runtimeRoot)),\n\t);\n\nconst provideFileSystem = <A, E>(\n\tfs: FileSystem.FileSystem,\n\teffect: Effect.Effect<A, E, FileSystem.FileSystem>,\n): Effect.Effect<A, E, never> => effect.pipe(Effect.provideService(FileSystem.FileSystem, fs));\n\nconst ensureNoLiveSupervisor = (\n\tidentity: ResolvedIdentity,\n\thint: string,\n): Effect.Effect<void, CliSupervisorLiveError> =>\n\tEffect.gen(function* () {\n\t\tconst presence = yield* probeSupervisorPresence(identity.rosterFile).pipe(\n\t\t\tEffect.catch(() => Effect.succeed({ live: false, pid: null, hostname: null })),\n\t\t);\n\t\tif (presence.live) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew CliSupervisorLiveError({\n\t\t\t\t\tapp: identity.app,\n\t\t\t\t\tstack: identity.stack,\n\t\t\t\t\thint,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t});\n\nconst runSnapshotRestoreDirect = (\n\tidentity: ResolvedIdentity,\n\tsnapshotId: string,\n): Effect.Effect<void, unknown> => {\n\tconst program = Effect.gen(function* () {\n\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tconst entries = yield* provideFileSystem(fs, snapshot.list);\n\t\tconst meta = entries.find((entry) => entry.id === snapshotId)?.metadata ?? null;\n\t\tconst participants = meta === null ? [] : snapshotIdentityParticipants(meta);\n\t\tyield* provideFileSystem(fs, snapshot.restore({ id: snapshotId, participants }));\n\t});\n\tconst restored = program.pipe(\n\t\tEffect.provide(directSnapshotLayers(identity)),\n\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t);\n\treturn ensureNoLiveSupervisor(\n\t\tidentity,\n\t\t'shut down the attached `devstack up` session before restoring a snapshot',\n\t).pipe(Effect.andThen(restored));\n};\n\nconst runSnapshotDeleteDirect = (\n\tidentity: ResolvedIdentity,\n\tsnapshotId: string,\n): Effect.Effect<void, unknown> => {\n\tconst program = Effect.gen(function* () {\n\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\tconst fs = yield* FileSystem.FileSystem;\n\t\tyield* provideFileSystem(fs, snapshot.delete(snapshotId));\n\t});\n\treturn program.pipe(\n\t\tEffect.provide(directSnapshotLayers(identity)),\n\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t);\n};\n\nconst runSnapshotCaptureDirect = (\n\tidentity: ResolvedIdentity,\n\targs: { readonly snapshotId?: string; readonly name?: string; readonly configPath?: string },\n): Effect.Effect<{ readonly snapshotId: string; readonly name: string }, unknown> => {\n\tconst loader = makeConfigLoader();\n\treturn Effect.gen(function* () {\n\t\tconst loaded = yield* loader.load(args.configPath);\n\t\tconst stack = (loaded as LoadedConfig & { readonly stack: SupervisedStack }).stack;\n\t\tconst identityValue = identityValueFor(identity, stack);\n\t\tconst appRoot = dirname(loaded.resolvedConfigPath);\n\t\tconst substrateLayers = layerProductionOrchestrators({\n\t\t\tcodegen: {\n\t\t\t\tappRoot,\n\t\t\t\toutputDir: stack.options.codegen?.outputDir,\n\t\t\t\tstackSubdir: stack.options.codegen?.stackSubdir ?? null,\n\t\t\t},\n\t\t}).pipe(Layer.provideMerge(buildSubstrateLayers(identityValue, identity.runtimeRoot)));\n\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst state = yield* makeProjectionRef();\n\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tconst orchestratorSinks = yield* buildProductionOrchestratorSinks();\n\t\t\tconst postAcquireHook = yield* buildProductionPostAcquireHook({\n\t\t\t\textras: stack.options.extras,\n\t\t\t});\n\t\t\tlet captureExit: Exit.Exit<void, unknown> = Exit.succeed(undefined);\n\t\t\tconst capturedMeta: { current: SnapshotMetadata | null } = { current: null };\n\t\t\tyield* superviseStackEffect(\n\t\t\t\t{ _tag: 'Stack', members: stack.members, options: stack.options },\n\t\t\t\tidentityValue,\n\t\t\t\tstate,\n\t\t\t\t{\n\t\t\t\t\torchestratorSinks,\n\t\t\t\t\tpostAcquireHook,\n\t\t\t\t\tlifetime: 'one-shot',\n\t\t\t\t\textendContext: extendBuiltInPluginContext,\n\t\t\t\t\twithinScope: () =>\n\t\t\t\t\t\tprovideFileSystem(fs, snapshot.capture({ id: args.snapshotId, label: args.name })).pipe(\n\t\t\t\t\t\t\tEffect.tap((meta) =>\n\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\tcapturedMeta.current = meta;\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\t\t\tEffect.exit,\n\t\t\t\t\t\t\tEffect.tap((exit) =>\n\t\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\t\tcaptureExit = exit;\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\tEffect.asVoid,\n\t\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t).pipe(Effect.provide(layerBuiltInPluginRuntime(orchestratorSinks)));\n\t\t\tif (Exit.isFailure(captureExit)) {\n\t\t\t\tyield* Effect.failCause(captureExit.cause);\n\t\t\t}\n\t\t\tif (capturedMeta.current === null) {\n\t\t\t\treturn yield* Effect.die('snapshot capture completed without metadata');\n\t\t\t}\n\t\t\tconst meta = capturedMeta.current;\n\t\t\tconst stackPaths = yield* StackPathsService;\n\t\t\tyield* writeProjectionSnapshot(stackPaths.stackRoot, yield* SubscriptionRef.get(state));\n\t\t\treturn { snapshotId: meta.id, name: meta.label ?? meta.id };\n\t\t});\n\n\t\treturn yield* program.pipe(\n\t\t\tEffect.provide(substrateLayers),\n\t\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t\t);\n\t});\n};\n\nconst makeDirectSnapshotDeps = (identity: ResolvedIdentity): CliDeps['snapshot'] => ({\n\treader: makeSnapshotReader(identity),\n\tcapture: (args) => runSnapshotCaptureDirect(identity, args),\n\trestore: (snapshotId) => runSnapshotRestoreDirect(identity, snapshotId),\n\tdelete: (snapshotId) => runSnapshotDeleteDirect(identity, snapshotId),\n\tconfirm: nodeConfirmPrompt,\n});\n\nconst runWipeDirect = (identity: ResolvedIdentity): Effect.Effect<void, unknown> =>\n\tEffect.gen(function* () {\n\t\tyield* ensureNoLiveSupervisor(identity, 'shut down the attached `devstack up` session first');\n\t\tconst program = Effect.gen(function* () {\n\t\t\tconst snapshot = yield* SnapshotOrchestratorService;\n\t\t\tconst fs = yield* FileSystem.FileSystem;\n\t\t\tyield* provideFileSystem(fs, snapshot.wipe({}));\n\t\t\tyield* removeRouterDispatchFilesForStack({\n\t\t\t\truntimeRoot: identity.runtimeRoot,\n\t\t\t\tapp: identity.app,\n\t\t\t\tstack: identity.stack,\n\t\t\t});\n\t\t});\n\t\treturn yield* program.pipe(\n\t\t\tEffect.provide(directSnapshotLayers(identity)),\n\t\t\tEffect.provide(Logger.layer([Logger.consolePretty()])),\n\t\t);\n\t});\n\nconst identityInputsFromArgv = (\n\targv: ReadonlyArray<string>,\n\tenv: Readonly<Record<string, string | undefined>>,\n) => {\n\tlet app = env.DEVSTACK_APP;\n\tlet stack = env.DEVSTACK_STACK;\n\tlet network = env.DEVSTACK_NETWORK;\n\tlet stateDir = env.DEVSTACK_STATE_DIR;\n\tlet configPath = env.DEVSTACK_CONFIG;\n\tfor (let i = 0; i < argv.length; i += 1) {\n\t\tconst token = argv[i]!;\n\t\tconst readValue = (name: string): string | undefined => {\n\t\t\tif (token.startsWith(`--${name}=`)) return token.slice(name.length + 3);\n\t\t\tif (token === `--${name}`) return argv[i + 1];\n\t\t\treturn undefined;\n\t\t};\n\t\tapp = readValue('app') ?? app;\n\t\tstack = readValue('stack') ?? stack;\n\t\tnetwork = readValue('network') ?? network;\n\t\tstateDir = readValue('state-dir') ?? stateDir;\n\t\tconfigPath = readValue('config') ?? configPath;\n\t}\n\treturn { app, stack, network, stateDir, configPath };\n};\n\nconst identityCwdFromConfig = (configPath: string | undefined): string => {\n\tconst resolved = resolveConfigPath(configPath);\n\treturn resolved === null ? process.cwd() : dirname(resolved);\n};\n\n// -----------------------------------------------------------------------------\n// Bin entry\n// -----------------------------------------------------------------------------\n\nexport const runCli = async (\n\targv: ReadonlyArray<string> = process.argv.slice(2),\n): Promise<void> => {\n\tconst stdinIsTty = Boolean((process.stdin as { isTTY?: boolean }).isTTY);\n\tconst env: Record<string, string | undefined> = { ...process.env };\n\tconst identityInputs = identityInputsFromArgv(argv, env);\n\tconst identity = resolveIdentity({\n\t\tapp: identityInputs.app,\n\t\tstack: identityInputs.stack,\n\t\tnetwork: identityInputs.network,\n\t\tstateDir: identityInputs.stateDir,\n\t\tcwd: identityCwdFromConfig(identityInputs.configPath),\n\t});\n\tconst deps = buildDirectDeps(identity);\n\tawait Effect.runPromise(\n\t\tdispatch(deps, {\n\t\t\targv,\n\t\t\tenv: {\n\t\t\t\t...env,\n\t\t\t\tDEVSTACK_APP: identity.app,\n\t\t\t\tDEVSTACK_STACK: identity.stack,\n\t\t\t\tDEVSTACK_STATE_DIR: identity.runtimeRoot,\n\t\t\t},\n\t\t\tstdinIsTty,\n\t\t}),\n\t);\n};\n\nconst isMainEntrypoint = (): boolean => {\n\tconst argvPath = process.argv[1];\n\tif (argvPath === undefined) return false;\n\ttry {\n\t\treturn realpathSync(argvPath) === realpathSync(fileURLToPath(import.meta.url));\n\t} catch {\n\t\treturn import.meta.url === pathToFileURL(argvPath).href;\n\t}\n};\n\nif (isMainEntrypoint()) {\n\trunCli()\n\t\t.catch((err) => {\n\t\t\tprocess.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n\t\t\tprocess.exitCode = 1;\n\t\t})\n\t\t.then(() => {\n\t\t\tprocess.exit(process.exitCode ?? 0);\n\t\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"main.mjs","names":["resolvePath"],"sources":["../../src/cli/main.ts"],"sourcesContent":["// devstack CLI bin entry — argv → identity → deps → dispatch → exit.\n//\n// This file is the executable entry the `bin: { devstack: ... }`\n// package.json field points at. Build output: `dist/cli/main.mjs`.\n//\n// Architecture invariant (surfaces/cli/index.ts header):\n// \"`up` must hand its long-running effect to the outer Node runtime\n// directly, not nest a runtime — otherwise SIGINT cannot reach\n// scope finalizers and container teardown leaks.\"\n//\n// Shape:\n// 1. Pre-parse identity inputs from argv + env (see\n// `identityInputsFromArgv`).\n// 2. Resolve identity (app / stack / network / runtime root) via the\n// shared `api/inference-network` helpers.\n// 3. Build the dispatcher's `CliDeps` bundle from each verb's wiring\n// module in `cli/wirings/`.\n// 4. Hand control to the Stricli-backed dispatcher, which routes to\n// the verb-scoped wiring function.\n\nimport { realpathSync } from 'node:fs';\nimport { dirname, resolve as resolvePath } from 'node:path';\nimport { fileURLToPath, pathToFileURL } from 'node:url';\n\nimport { Effect } from 'effect';\n\nimport { readProjectionSnapshot } from '../substrate/runtime/index.ts';\nimport type { SubscribableState } from '../substrate/projection.ts';\nimport { dispatch, type CliDeps, CliUsageError } from '../surfaces/cli/index.ts';\nimport { emitFailure, nodeProcessIO } from '../surfaces/cli/output.ts';\nimport { ENV_VARS } from '../surfaces/cli/flags.ts';\nimport { defaultProbes } from './doctor-probes.ts';\nimport { nodeConfirmPrompt } from '../surfaces/cli/commands/confirm-node.ts';\nimport type { StatusReader } from '../surfaces/cli/commands/status.ts';\nimport { ExitCode } from '../surfaces/cli/sysexits.ts';\nimport { makeSnapshotReader } from './snapshot-reader.ts';\nimport {\n\tDevstackNetworkParseError,\n\tresolveAppName,\n\tresolveNetworkSync,\n\tresolveStackName,\n\tresolveStateDir,\n} from '../api/inference-network.ts';\nimport { makeDirectPruneDeps } from './prune-direct.ts';\nimport { runUpLive } from './wirings/up.ts';\nimport { runApplyLive } from './wirings/apply.ts';\nimport {\n\trunSnapshotCaptureLiveAware,\n\trunSnapshotDeleteDirect,\n\trunSnapshotRestoreDirect,\n} from './wirings/snapshot.ts';\nimport { runWipeDirect, runWipePlanDirect } from './wirings/wipe.ts';\nimport { makeConfigLoader, resolveConfigPath } from './wirings/config-loader.ts';\nimport type { ResolvedIdentity } from './wirings/identity.ts';\n\n// -----------------------------------------------------------------------------\n// Identity resolution\n// -----------------------------------------------------------------------------\n\n/** Resolve identity from flags + env. App and stack fall through the\n * shared cwd/package metadata resolver before their defaults.\n *\n * State-dir precedence ladder:\n * `--state-dir` flag (`stateDir`) > `config.options.stateDir`\n * (`configStateDir`) > `$DEVSTACK_STATE_DIR` > `<cwd>/.devstack`.\n * The flag maps to `resolveStateDir`'s top `runtimeRoot` rung and the\n * config value to its `stateDir` rung so the flag always wins over a\n * config-declared `defineDevstack({ stateDir })`.\n *\n * Stack-name precedence ladder (the SAME flag-beats-config shape as\n * state-dir, so the two are consistent and reviewable side-by-side):\n * `--stack` flag / `$DEVSTACK_STACK` (`params.stack`)\n * > config's `defineDevstack({ stackName })`\n * > cwd/package inference (default `'main'`).\n * Config-vs-explicit resolution can't happen here (the config isn't\n * loaded yet for the no-config verbs), so we record the explicit value\n * on `ResolvedIdentity.explicitStack` and let the verb wirings apply\n * `config.stackName` ONLY when no explicit stack was given — see\n * `effectiveStackName` in `cli/wirings/identity.ts`. `params.stack` is\n * exactly the explicit `--stack`-or-`$DEVSTACK_STACK` value (the argv\n * pre-parser seeds it from env, then lets the flag overwrite it), and\n * is `undefined` when neither was provided. */\nconst resolveIdentity = (params: {\n\treadonly app: string | undefined;\n\treadonly stack: string | undefined;\n\treadonly network: string | undefined;\n\treadonly stateDir: string | undefined;\n\treadonly configStateDir?: string | undefined;\n\treadonly cwd?: string;\n}): ResolvedIdentity => {\n\tconst cwd = params.cwd ?? process.cwd();\n\tconst app = resolveAppName({\n\t\texplicit: params.app,\n\t\tcwd,\n\t});\n\tconst runtimeRoot = resolveStateDir({\n\t\truntimeRoot: params.stateDir,\n\t\tstateDir: params.configStateDir,\n\t\tenv: process.env.DEVSTACK_STATE_DIR,\n\t\tcwd,\n\t});\n\tconst stacksRoot = resolvePath(runtimeRoot, 'stacks');\n\t// `resolveStackName` here folds explicit (flag/env) > inferred >\n\t// default. Crucially it does NOT see `config.stackName`: a non-empty\n\t// `params.stack` means the operator was explicit, so `stack` already\n\t// equals the explicit value and `config.stackName` must not override\n\t// it downstream. An empty `params.stack` falls through to the\n\t// inferred/default name, which a verb's `config.stackName` may then\n\t// supersede via `effectiveStackName`.\n\tconst explicitStack =\n\t\tparams.stack !== undefined && params.stack.length > 0 ? params.stack : undefined;\n\tconst stack = resolveStackName({\n\t\texplicit: params.stack,\n\t\tcwd,\n\t});\n\t// Centralized explicit > env > default ladder. Throws\n\t// `DevstackNetworkParseError` on a malformed value so the CLI fails\n\t// fast with a structured error instead of a downstream cryptic\n\t// chain-probe failure. The raw input is preserved (not the\n\t// canonical name) so chain-keyed cache namespaces stay stable.\n\tconst network = resolveNetworkSync({\n\t\texplicit: params.network,\n\t\tenv: process.env.DEVSTACK_NETWORK,\n\t\texplicitSource: '--network',\n\t}).raw;\n\tconst stackRoot = resolvePath(stacksRoot, stack);\n\treturn {\n\t\tapp,\n\t\tstack,\n\t\tnetwork,\n\t\truntimeRoot,\n\t\tstacksRoot,\n\t\tstackRoot,\n\t\trosterFile: resolvePath(stackRoot, 'roster.json'),\n\t\texplicitStack,\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// Verb deps composition\n// -----------------------------------------------------------------------------\n\nconst projectionStatusReader = (identity: ResolvedIdentity): StatusReader => ({\n\treadState: () =>\n\t\tEffect.sync(() => readProjectionSnapshot(identity.stackRoot) as SubscribableState | null),\n});\n\nconst buildDirectDeps = (identity: ResolvedIdentity): CliDeps => {\n\treturn {\n\t\tup: {\n\t\t\trun: (flags) =>\n\t\t\t\trunUpLive(flags.configPath, identity, {\n\t\t\t\t\trenderer: flags.renderer,\n\t\t\t\t\tstdoutIsTty: Boolean((process.stdout as { isTTY?: boolean }).isTTY),\n\t\t\t\t}),\n\t\t},\n\t\tapply: {\n\t\t\trun: (flags) => runApplyLive(flags.configPath, identity),\n\t\t},\n\t\tstatus: { reader: projectionStatusReader(identity) },\n\t\tsnapshot: {\n\t\t\treader: makeSnapshotReader(identity),\n\t\t\tcapture: (args) => runSnapshotCaptureLiveAware(identity, args),\n\t\t\trestore: (snapshotId) => runSnapshotRestoreDirect(identity, snapshotId),\n\t\t\tdelete: (snapshotId) => runSnapshotDeleteDirect(identity, snapshotId),\n\t\t\tconfirm: nodeConfirmPrompt,\n\t\t},\n\t\tprune: makeDirectPruneDeps({ runtimeRoot: identity.runtimeRoot }),\n\t\tdoctor: {\n\t\t\tprobes: defaultProbes({\n\t\t\t\tstateDir: identity.runtimeRoot,\n\t\t\t\tappRoot: identity.stacksRoot,\n\t\t\t}),\n\t\t},\n\t\tconfig: { loader: makeConfigLoader() },\n\t\twipe: {\n\t\t\twipe: () => runWipeDirect(identity),\n\t\t\tplan: () => runWipePlanDirect(identity),\n\t\t\tconfirm: nodeConfirmPrompt,\n\t\t},\n\t};\n};\n\n// -----------------------------------------------------------------------------\n// Argv pre-parser\n// -----------------------------------------------------------------------------\n\n/** @internal Exported for tests. Resolves identity flag inputs from a\n * `--app <x>` / `--stack <x>` / `--network <x>` / `--state-dir <x>` /\n * `--config <x>` argv, falling back to `DEVSTACK_*` env vars. Throws\n * on a missing or flag-shaped value so a typo doesn't silently demote\n * a downstream flag, and on a duplicate flag (`--app a --app b`) so\n * the pre-parser does not silently last-write-wins a value that\n * Stricli will later reject outright. */\nexport const identityInputsFromArgv = (\n\targv: ReadonlyArray<string>,\n\tenv: Readonly<Record<string, string | undefined>>,\n) => {\n\tlet app = env.DEVSTACK_APP;\n\tlet stack = env.DEVSTACK_STACK;\n\tlet network = env.DEVSTACK_NETWORK;\n\t// `stateDir` intentionally captures the `--state-dir` flag ONLY. The\n\t// full ladder — `--state-dir` flag > `config.options.stateDir`\n\t// (`defineDevstack({ stateDir })`) > `$DEVSTACK_STATE_DIR` >\n\t// `<cwd>/.devstack` — is assembled at the `resolveStateDir(...)`\n\t// call-site in `resolveIdentity`: the flag wins (top `runtimeRoot`\n\t// rung), the best-effort config value sits below it (`stateDir`\n\t// rung), then env, then the cwd default. Keeping the pre-parser a\n\t// thin flag-extractor means config + env precedence live in one place.\n\tlet stateDir: string | undefined;\n\tlet configPath = env.DEVSTACK_CONFIG;\n\t// Tracks which flags have been seen on the argv side so a second\n\t// occurrence trips a usage error before the value silently overwrites\n\t// the first. Env-sourced defaults are NOT counted (they are not user\n\t// argv).\n\tconst seenArgvFlags = new Set<string>();\n\tfor (let i = 0; i < argv.length; i += 1) {\n\t\tconst token = argv[i]!;\n\t\tconst readValue = (name: string): string | undefined => {\n\t\t\tlet value: string | undefined;\n\t\t\t// `--name=value` form: trust the literal between `=` and end.\n\t\t\tif (token.startsWith(`--${name}=`)) {\n\t\t\t\tvalue = token.slice(name.length + 3);\n\t\t\t}\n\t\t\t// `--name value` form: peek the next token. Reject another\n\t\t\t// flag token (`--foo`) as the value — it almost certainly\n\t\t\t// means the user meant `--name <empty>` (typo / forgotten\n\t\t\t// argument) and quietly absorbing `--foo` as the value\n\t\t\t// silently demotes a downstream flag.\n\t\t\telse if (token === `--${name}`) {\n\t\t\t\tconst next = argv[i + 1];\n\t\t\t\tif (next === undefined) {\n\t\t\t\t\tthrow new CliUsageError({ message: `flag --${name} requires a value` });\n\t\t\t\t}\n\t\t\t\tif (next.startsWith('--')) {\n\t\t\t\t\tthrow new CliUsageError({\n\t\t\t\t\t\tmessage: `flag --${name} requires a value; got \"${next}\" which looks like a flag`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tvalue = next;\n\t\t\t}\n\t\t\tif (value === undefined) return undefined;\n\t\t\tif (seenArgvFlags.has(name)) {\n\t\t\t\tthrow new CliUsageError({ message: `flag --${name} given more than once` });\n\t\t\t}\n\t\t\tseenArgvFlags.add(name);\n\t\t\treturn value;\n\t\t};\n\t\tapp = readValue('app') ?? app;\n\t\tstack = readValue('stack') ?? stack;\n\t\tnetwork = readValue('network') ?? network;\n\t\tstateDir = readValue('state-dir') ?? stateDir;\n\t\tconfigPath = readValue('config') ?? configPath;\n\t}\n\treturn { app, stack, network, stateDir, configPath };\n};\n\nconst identityCwdFromConfig = (configPath: string | undefined): string => {\n\tconst resolved = resolveConfigPath(configPath);\n\treturn resolved === null ? process.cwd() : dirname(resolved);\n};\n\n/** Whether the resolved argv is a purely-informational invocation that\n * never consumes `identity.runtimeRoot` (the only value the config\n * pre-load feeds). For these we SKIP `configStateDirBestEffort` so we\n * don't dynamic-import (and run the top-level side effects of) the\n * user's `devstack.config.ts` — plus walk parent dirs — for commands\n * the file header itself says must stay cheap:\n *\n * - empty argv → Stricli prints root help\n * - `--help`/`-h` or `--version`/`-v` anywhere → Stricli short-circuits\n * - first token `schema` → emits the static CLI schema (no state dir)\n *\n * An unknown verb also never reaches a state-dir consumer (Stricli\n * fails the parse), but we keep pre-loading on the general path: the\n * pre-parser already accepted the identity flags, and gating on a\n * closed verb set here would duplicate the dispatcher's route table.\n * The two flagged-as-wasteful informational paths (help/version/schema)\n * are the ones with a registered short-circuit, so skipping exactly\n * those removes the eager-import surprise without re-deriving routes. */\nconst argvSkipsConfigPreload = (argv: ReadonlyArray<string>): boolean => {\n\tif (argv.length === 0) return true;\n\tfor (const token of argv) {\n\t\tif (token === '--help' || token === '-h' || token === '--version' || token === '-v') {\n\t\t\treturn true;\n\t\t}\n\t}\n\tconst firstVerb = argv.find((token) => !token.startsWith('-'));\n\treturn firstVerb === 'schema';\n};\n\n/** Best-effort read of `config.options.stateDir` (the value a program\n * sets via `defineDevstack({ stateDir })`) for the state-dir precedence\n * ladder in `resolveIdentity`. Swallows EVERY config-loader failure\n * (not-found AND evaluation errors) and returns `undefined`:\n *\n * - No-config verbs (`prune`, `wipe`) MUST keep resolving identity\n * without a config, so a missing config silently falls through to\n * the flag > env > cwd ladder.\n * - A genuinely malformed config is NOT surfaced here — the verbs that\n * actually consume config (`up` / `apply` via `makeConfigLoader`)\n * re-load it and surface the typed `CliConfig*` error through the\n * normal envelope path, so behavior for those verbs is unchanged.\n *\n * This is one redundant config evaluation for `up` / `apply` (the verb\n * wiring re-loads via its own loader); threading the loaded value into\n * the verb dispatch would require touching the off-limits `wirings/up.ts`\n * signature, so the duplicate import is accepted deliberately. */\nconst configStateDirBestEffort = async (\n\tconfigPath: string | undefined,\n): Promise<string | undefined> => {\n\tconst loaded = await Effect.runPromise(makeConfigLoader().load(configPath).pipe(Effect.option));\n\tif (loaded._tag === 'None') return undefined;\n\tconst options = (loaded.value.stack as { readonly options?: { readonly stateDir?: string } })\n\t\t.options;\n\tconst stateDir = options?.stateDir;\n\treturn stateDir !== undefined && stateDir.length > 0 ? stateDir : undefined;\n};\n\n// -----------------------------------------------------------------------------\n// Bin entry\n// -----------------------------------------------------------------------------\n\nexport const runCli = async (\n\targv: ReadonlyArray<string> = process.argv.slice(2),\n): Promise<void> => {\n\tconst stdinIsTty = Boolean((process.stdin as { isTTY?: boolean }).isTTY);\n\tconst env: Record<string, string | undefined> = { ...process.env };\n\tlet identityInputs: ReturnType<typeof identityInputsFromArgv>;\n\ttry {\n\t\tidentityInputs = identityInputsFromArgv(argv, env);\n\t} catch (cause) {\n\t\tconst error =\n\t\t\tcause instanceof CliUsageError\n\t\t\t\t? cause\n\t\t\t\t: new CliUsageError({\n\t\t\t\t\t\tmessage: cause instanceof Error ? cause.message : String(cause),\n\t\t\t\t\t});\n\t\tconst jsonMode = env[ENV_VARS.JSON] === '1' || argv.includes('--json');\n\t\tawait Effect.runPromise(\n\t\t\temitFailure(nodeProcessIO, jsonMode ? 'json' : 'human', {\n\t\t\t\tcommand: '(parse-argv)',\n\t\t\t\telapsedMs: 0,\n\t\t\t\terror,\n\t\t\t}),\n\t\t);\n\t\treturn;\n\t}\n\t// Best-effort config pre-load for the state-dir ladder. Swallows\n\t// not-found / malformed configs so no-config verbs (prune/wipe) keep\n\t// working; the `--state-dir` flag still wins over the config value.\n\t// Skipped for informational invocations (help/version/schema/empty)\n\t// that never read `identity.runtimeRoot`, so those commands don't\n\t// dynamic-import the user's config (and run its top-level side\n\t// effects) just to print help.\n\tconst configStateDir = argvSkipsConfigPreload(argv)\n\t\t? undefined\n\t\t: await configStateDirBestEffort(identityInputs.configPath);\n\tlet identity: ResolvedIdentity;\n\ttry {\n\t\tidentity = resolveIdentity({\n\t\t\tapp: identityInputs.app,\n\t\t\tstack: identityInputs.stack,\n\t\t\tnetwork: identityInputs.network,\n\t\t\tstateDir: identityInputs.stateDir,\n\t\t\tconfigStateDir,\n\t\t\tcwd: identityCwdFromConfig(identityInputs.configPath),\n\t\t});\n\t} catch (cause) {\n\t\t// `resolveIdentity` -> `resolveNetworkSync` throws\n\t\t// `DevstackNetworkParseError` (a plain Error, NOT a CliError) on a\n\t\t// malformed `--network`/`$DEVSTACK_NETWORK` value. This runs OUTSIDE\n\t\t// the argv pre-parse try/catch above and BEFORE dispatch, so without\n\t\t// this guard the throw escapes to the bin entry's generic `.catch`\n\t\t// (exit 1, no envelope). Convert to `CliUsageError` and route through\n\t\t// the same envelope path the parse-argv block uses so a bad value\n\t\t// exits USAGE (64) with a JSON envelope in `--json` mode — never the\n\t\t// disallowed generic exit 1.\n\t\tconst error =\n\t\t\tcause instanceof DevstackNetworkParseError\n\t\t\t\t? new CliUsageError({ message: cause.message })\n\t\t\t\t: cause instanceof CliUsageError\n\t\t\t\t\t? cause\n\t\t\t\t\t: new CliUsageError({\n\t\t\t\t\t\t\tmessage: cause instanceof Error ? cause.message : String(cause),\n\t\t\t\t\t\t});\n\t\tconst jsonMode = env[ENV_VARS.JSON] === '1' || argv.includes('--json');\n\t\tawait Effect.runPromise(\n\t\t\temitFailure(nodeProcessIO, jsonMode ? 'json' : 'human', {\n\t\t\t\tcommand: '(resolve-identity)',\n\t\t\t\telapsedMs: 0,\n\t\t\t\terror,\n\t\t\t}),\n\t\t);\n\t\treturn;\n\t}\n\tconst deps = buildDirectDeps(identity);\n\tawait Effect.runPromise(\n\t\tdispatch(deps, {\n\t\t\targv,\n\t\t\tenv: {\n\t\t\t\t...env,\n\t\t\t\tDEVSTACK_APP: identity.app,\n\t\t\t\tDEVSTACK_STACK: identity.stack,\n\t\t\t\tDEVSTACK_STATE_DIR: identity.runtimeRoot,\n\t\t\t},\n\t\t\tstdinIsTty,\n\t\t}),\n\t);\n};\n\nconst isMainEntrypoint = (): boolean => {\n\tconst argvPath = process.argv[1];\n\tif (argvPath === undefined) return false;\n\ttry {\n\t\treturn realpathSync(argvPath) === realpathSync(fileURLToPath(import.meta.url));\n\t} catch {\n\t\treturn import.meta.url === pathToFileURL(argvPath).href;\n\t}\n};\n\nif (isMainEntrypoint()) {\n\t// Intentionally do NOT call `process.exit(...)` after `runCli`:\n\t// `process.exit` synchronously terminates the event loop before any\n\t// pending `setImmediate` work flushes. The `up` lifecycle's hard-kill\n\t// path schedules its escalation via `setImmediate(process.exit)` in\n\t// `up-lifecycle.ts:scheduleProcessExit` (the file-header invariant for\n\t// SIGINT → finalizers requires the outer Node fiber to drain\n\t// naturally). Letting Node's natural exit handle the shutdown\n\t// preserves that invariant. We only set `process.exitCode` so the\n\t// final OS exit code reflects the verb's outcome.\n\trunCli().catch((err) => {\n\t\tprocess.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n\t\tprocess.exitCode = ExitCode.GENERIC;\n\t});\n}\n"],"mappings":"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"}
@@ -1,213 +1,43 @@
1
- import { checkHolderLiveness } from "../substrate/runtime/cross-process/liveness.mjs";
2
- import { DockerSpawner, layerDockerHostDefault } from "../runtime/docker/client.mjs";
3
- import { readRoster } from "../substrate/runtime/cross-process/roster.mjs";
4
- import { LabelKey } from "../runtime/docker/labels.mjs";
5
- import { listDevstackContainers, listDevstackImages, listDevstackNetworks, listDevstackRouterContainers, listDevstackVolumes } from "../runtime/docker/inventory.mjs";
6
- import { removeDevstackContainers, removeDevstackImages, removeDevstackNetworksBestEffort, removeDevstackRouterContainers, removeDevstackVolumes } from "../runtime/docker/sweep.mjs";
7
- import { ROUTER_SHARED_APP, removeRouterProfileStateForDockerStack } from "../orchestrators/router/cleanup.mjs";
1
+ import { collectLifecyclePruneInventory, runLifecyclePrune } from "../orchestrators/lifecycle-prune/index.mjs";
8
2
  import { summarizePruneGroups } from "../surfaces/cli/commands/prune.mjs";
9
- import { selectPruneTargets } from "../surfaces/cli/commands/prune-picker.mjs";
10
- import { Effect, Layer } from "effect";
11
- import { existsSync } from "node:fs";
12
- import { join } from "node:path";
13
- import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem";
14
- import * as NodePath from "@effect/platform-node/NodePath";
15
- import * as NodeChildProcessSpawner from "@effect/platform-node/NodeChildProcessSpawner";
16
- import { ChildProcessSpawner } from "effect/unstable/process/ChildProcessSpawner";
3
+ import "../surfaces/cli/commands/index.mjs";
4
+ import { selectPruneTargets } from "../surfaces/cli/commands/prune-picker-entry.mjs";
5
+ import { Effect } from "effect";
17
6
  //#region src/cli/prune-direct.ts
18
- const layerDockerSpawnerFromNode = Layer.effect(DockerSpawner, Effect.gen(function* () {
19
- return yield* ChildProcessSpawner;
20
- }));
21
- const dockerLayer = Layer.merge(layerDockerHostDefault, layerDockerSpawnerFromNode.pipe(Layer.provideMerge(NodeChildProcessSpawner.layer.pipe(Layer.provideMerge(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer))))));
22
- const emptyBucket = () => ({
23
- containers: 0,
24
- runningContainers: 0,
25
- networks: 0,
26
- volumes: 0,
27
- images: 0
7
+ const adaptGroup = (group) => ({
8
+ key: group.key,
9
+ app: group.app,
10
+ stack: group.stack,
11
+ live: group.live,
12
+ livePids: group.livePids,
13
+ shared: group.shared,
14
+ sharedKind: group.sharedKind,
15
+ autoPrunable: group.autoPrunable,
16
+ containers: group.containers,
17
+ runningContainers: group.runningContainers,
18
+ networks: group.networks,
19
+ volumes: group.volumes,
20
+ images: group.images
28
21
  });
29
- const groupKey = (app, stack) => `${app}/${stack}`;
30
- const readAppStack = (labels) => {
31
- const app = labels[LabelKey.app];
32
- const stack = labels[LabelKey.stack];
33
- if (app === void 0 || app.length === 0) return null;
34
- if (stack === void 0 || stack.length === 0) return null;
35
- return {
36
- app,
37
- stack
38
- };
39
- };
40
- const routerStackForContainer = (name) => ({
41
- app: ROUTER_SHARED_APP,
42
- stack: name
43
- });
44
- const addBucket = (buckets, identity) => {
45
- const key = groupKey(identity.app, identity.stack);
46
- let bucket = buckets.get(key);
47
- if (bucket === void 0) {
48
- bucket = emptyBucket();
49
- buckets.set(key, bucket);
50
- }
51
- return bucket;
52
- };
53
- const livePidsForStack = (runtimeRoot, stack) => {
54
- const rosterFile = join(runtimeRoot, "stacks", stack, "roster.json");
55
- if (!existsSync(rosterFile)) return Effect.succeed([]);
56
- return Effect.gen(function* () {
57
- const doc = yield* readRoster(rosterFile).pipe(Effect.catch(() => Effect.succeed(null)));
58
- if (doc === null) return [];
59
- const pids = [];
60
- for (const holder of doc.holders) if ((yield* checkHolderLiveness(holder).pipe(Effect.catch(() => Effect.succeed("alive")))) === "alive") pids.push(holder.pid);
61
- return pids;
62
- });
63
- };
64
- const isSharedGroup = (app, stack) => stack === "_per-app_" || app === "devstack-router";
65
- const isRouterGroup = (group) => group.app === "devstack-router" && group.stack.startsWith(`devstack-router-`);
66
- const collectDirectPruneInventory = (options) => Effect.gen(function* () {
67
- const [containers, routerContainers, networks, volumes, images] = yield* Effect.all([
68
- listDevstackContainers(),
69
- listDevstackRouterContainers(),
70
- listDevstackNetworks(),
71
- listDevstackVolumes(),
72
- listDevstackImages()
73
- ], { concurrency: "unbounded" }).pipe(Effect.provide(dockerLayer));
74
- const buckets = /* @__PURE__ */ new Map();
75
- for (const container of containers) {
76
- const identity = readAppStack(container.labels);
77
- if (identity === null) continue;
78
- const bucket = addBucket(buckets, identity);
79
- bucket.containers += 1;
80
- if (container.state === "running") bucket.runningContainers += 1;
81
- }
82
- for (const container of routerContainers) {
83
- const bucket = addBucket(buckets, routerStackForContainer(container.name));
84
- bucket.containers += 1;
85
- if (container.state === "running") bucket.runningContainers += 1;
86
- }
87
- for (const network of networks) {
88
- const identity = readAppStack(network.labels);
89
- if (identity === null) continue;
90
- addBucket(buckets, identity).networks += 1;
91
- }
92
- for (const volume of volumes) {
93
- const identity = readAppStack(volume.labels);
94
- if (identity === null) continue;
95
- addBucket(buckets, identity).volumes += 1;
96
- }
97
- for (const image of images) {
98
- const identity = readAppStack(image.labels);
99
- if (identity === null) continue;
100
- addBucket(buckets, identity).images += 1;
101
- }
102
- const groups = [];
103
- for (const [key, bucket] of buckets) {
104
- const [app, stack] = key.split("/");
105
- const routerGroup = app === ROUTER_SHARED_APP;
106
- const livePids = routerGroup ? [] : yield* livePidsForStack(options.runtimeRoot, stack);
107
- groups.push({
108
- key,
109
- app,
110
- stack,
111
- live: routerGroup ? bucket.runningContainers > 0 : livePids.length > 0,
112
- livePids,
113
- shared: isSharedGroup(app, stack),
114
- containers: bucket.containers,
115
- runningContainers: bucket.runningContainers,
116
- networks: bucket.networks,
117
- volumes: bucket.volumes,
118
- images: bucket.images
119
- });
120
- }
121
- groups.sort((a, b) => {
122
- if (a.app !== b.app) return a.app < b.app ? -1 : 1;
123
- return a.stack < b.stack ? -1 : a.stack > b.stack ? 1 : 0;
124
- });
22
+ const adaptInventory = (inventory) => {
23
+ const groups = inventory.groups.map(adaptGroup);
125
24
  return {
126
25
  groups,
127
26
  totals: summarizePruneGroups(groups)
128
27
  };
129
- });
130
- const selectedGroups = (inventory, selection) => {
131
- const selected = new Set(selection.groupKeys);
132
- return inventory.groups.filter((group) => selected.has(group.key));
133
28
  };
134
- const pruneDirectSelection = (options, selection) => Effect.gen(function* () {
135
- const groups = selectedGroups(yield* collectDirectPruneInventory(options), selection);
136
- let skippedLiveGroups = 0;
137
- let containersRemoved = 0;
138
- let networksRemoved = 0;
139
- let networksSkipped = 0;
140
- let volumesRemoved = 0;
141
- let imagesRemoved = 0;
142
- const prunableGroups = [];
143
- for (const group of groups) {
144
- if (group.live) {
145
- skippedLiveGroups += 1;
146
- continue;
147
- }
148
- prunableGroups.push(group);
149
- if (selection.dryRun) {
150
- if (selection.resources.containers) containersRemoved += group.containers;
151
- if (selection.resources.networks) networksRemoved += group.networks;
152
- if (selection.resources.volumes) volumesRemoved += group.volumes;
153
- if (selection.resources.images) imagesRemoved += group.images;
154
- continue;
155
- }
156
- }
157
- if (!selection.dryRun && selection.resources.containers) for (const group of prunableGroups) if (isRouterGroup(group)) containersRemoved += yield* removeDevstackRouterContainers(group.stack).pipe(Effect.provide(dockerLayer));
158
- else {
159
- const match = {
160
- app: group.app,
161
- stack: group.stack
162
- };
163
- containersRemoved += yield* removeDevstackContainers(match).pipe(Effect.provide(dockerLayer));
164
- }
165
- if (!selection.dryRun && selection.resources.networks) for (const group of prunableGroups) {
166
- const result = yield* removeDevstackNetworksBestEffort({
167
- app: group.app,
168
- stack: group.stack
169
- }).pipe(Effect.provide(dockerLayer));
170
- networksRemoved += result.removed;
171
- networksSkipped += result.skippedInUse;
172
- }
173
- if (!selection.dryRun && selection.resources.volumes) for (const group of prunableGroups) {
174
- const match = {
175
- app: group.app,
176
- stack: group.stack
177
- };
178
- volumesRemoved += yield* removeDevstackVolumes(match).pipe(Effect.provide(dockerLayer));
179
- }
180
- if (!selection.dryRun && selection.resources.images) for (const group of prunableGroups) {
181
- const match = {
182
- app: group.app,
183
- stack: group.stack
184
- };
185
- imagesRemoved += yield* removeDevstackImages(match).pipe(Effect.provide(dockerLayer));
186
- }
187
- if (!selection.dryRun) for (const group of prunableGroups) {
188
- if (!isRouterGroup(group)) continue;
189
- yield* removeRouterProfileStateForDockerStack({
190
- runtimeRoot: options.runtimeRoot,
191
- routerStack: group.stack
192
- });
193
- }
194
- return {
195
- kind: "completed",
196
- summary: {
197
- inspectedGroups: groups.length,
198
- selectedGroups: groups.length,
199
- skippedLiveGroups,
200
- containersRemoved,
201
- networksRemoved,
202
- networksSkipped,
203
- volumesRemoved,
204
- imagesRemoved
205
- }
206
- };
207
- });
29
+ const collectInventory = (options) => collectLifecyclePruneInventory(options).pipe(Effect.map(adaptInventory));
30
+ const pruneSelection = (options, selection) => runLifecyclePrune(options, {
31
+ groupKeys: selection.groupKeys,
32
+ resources: selection.resources,
33
+ dryRun: selection.dryRun
34
+ }).pipe(Effect.map((summary) => ({
35
+ kind: "completed",
36
+ summary
37
+ })));
208
38
  const makeDirectPruneDeps = (options) => ({
209
- inventory: () => collectDirectPruneInventory(options),
210
- prune: (selection) => pruneDirectSelection(options, selection),
39
+ inventory: () => collectInventory(options),
40
+ prune: (selection) => pruneSelection(options, selection),
211
41
  select: (inventory, resources) => selectPruneTargets(inventory, resources)
212
42
  });
213
43
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"prune-direct.mjs","names":["joinPath"],"sources":["../../src/cli/prune-direct.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join as joinPath } from 'node:path';\n\nimport * as NodeChildProcessSpawner from '@effect/platform-node/NodeChildProcessSpawner';\nimport * as NodeFileSystem from '@effect/platform-node/NodeFileSystem';\nimport * as NodePath from '@effect/platform-node/NodePath';\nimport { Effect, Layer } from 'effect';\nimport { ChildProcessSpawner } from 'effect/unstable/process/ChildProcessSpawner';\n\nimport {\n\tDockerHost,\n\tDockerSpawner,\n\tLabelKey,\n\tlayerDockerHostDefault,\n\tlistDevstackContainers,\n\tlistDevstackImages,\n\tlistDevstackNetworks,\n\tlistDevstackRouterContainers,\n\tlistDevstackVolumes,\n\tremoveDevstackContainers,\n\tremoveDevstackImages,\n\tremoveDevstackNetworksBestEffort,\n\tremoveDevstackRouterContainers,\n\tremoveDevstackVolumes,\n} from '../runtime/docker/index.ts';\nimport {\n\tROUTER_SHARED_APP,\n\tremoveRouterProfileStateForDockerStack,\n} from '../orchestrators/router/cleanup.ts';\nimport { checkHolderLiveness, readRoster } from '../substrate/runtime/cross-process/index.ts';\nimport {\n\tsummarizePruneGroups,\n\ttype PruneDeps,\n\ttype PruneGroup,\n\ttype PruneInventory,\n\ttype PruneOutcome,\n\ttype PruneSelection,\n} from '../surfaces/cli/commands/index.ts';\nimport { selectPruneTargets } from '../surfaces/cli/commands/prune-picker.tsx';\n\ninterface DirectPruneOptions {\n\treadonly runtimeRoot: string;\n}\n\ntype ResourceBucket = {\n\tcontainers: number;\n\trunningContainers: number;\n\tnetworks: number;\n\tvolumes: number;\n\timages: number;\n};\n\nconst layerDockerSpawnerFromNode: Layer.Layer<DockerSpawner, never, ChildProcessSpawner> =\n\tLayer.effect(\n\t\tDockerSpawner,\n\t\tEffect.gen(function* () {\n\t\t\treturn yield* ChildProcessSpawner;\n\t\t}),\n\t);\n\nconst dockerLayer: Layer.Layer<DockerHost | DockerSpawner> = Layer.merge(\n\tlayerDockerHostDefault,\n\tlayerDockerSpawnerFromNode.pipe(\n\t\tLayer.provideMerge(\n\t\t\tNodeChildProcessSpawner.layer.pipe(\n\t\t\t\tLayer.provideMerge(Layer.mergeAll(NodeFileSystem.layer, NodePath.layer)),\n\t\t\t),\n\t\t),\n\t),\n);\n\nconst emptyBucket = (): ResourceBucket => ({\n\tcontainers: 0,\n\trunningContainers: 0,\n\tnetworks: 0,\n\tvolumes: 0,\n\timages: 0,\n});\n\nconst groupKey = (app: string, stack: string): string => `${app}/${stack}`;\n\nconst readAppStack = (\n\tlabels: Readonly<Record<string, string>>,\n): { readonly app: string; readonly stack: string } | null => {\n\tconst app = labels[LabelKey.app];\n\tconst stack = labels[LabelKey.stack];\n\tif (app === undefined || app.length === 0) return null;\n\tif (stack === undefined || stack.length === 0) return null;\n\treturn { app, stack };\n};\n\nconst routerStackForContainer = (\n\tname: string,\n): { readonly app: string; readonly stack: string } => ({\n\tapp: ROUTER_SHARED_APP,\n\tstack: name,\n});\n\nconst addBucket = (\n\tbuckets: Map<string, ResourceBucket>,\n\tidentity: { readonly app: string; readonly stack: string },\n): ResourceBucket => {\n\tconst key = groupKey(identity.app, identity.stack);\n\tlet bucket = buckets.get(key);\n\tif (bucket === undefined) {\n\t\tbucket = emptyBucket();\n\t\tbuckets.set(key, bucket);\n\t}\n\treturn bucket;\n};\n\nconst livePidsForStack = (\n\truntimeRoot: string,\n\tstack: string,\n): Effect.Effect<ReadonlyArray<number>> => {\n\tconst rosterFile = joinPath(runtimeRoot, 'stacks', stack, 'roster.json');\n\tif (!existsSync(rosterFile)) return Effect.succeed([]);\n\treturn Effect.gen(function* () {\n\t\tconst doc = yield* readRoster(rosterFile).pipe(Effect.catch(() => Effect.succeed(null)));\n\t\tif (doc === null) return [];\n\t\tconst pids: Array<number> = [];\n\t\tfor (const holder of doc.holders) {\n\t\t\tconst live = yield* checkHolderLiveness(holder).pipe(\n\t\t\t\tEffect.catch(() => Effect.succeed('alive' as const)),\n\t\t\t);\n\t\t\tif (live === 'alive') pids.push(holder.pid);\n\t\t}\n\t\treturn pids;\n\t});\n};\n\nconst isSharedGroup = (app: string, stack: string): boolean =>\n\tstack === '_per-app_' || app === ROUTER_SHARED_APP;\n\nconst isRouterGroup = (group: Pick<PruneGroup, 'app' | 'stack'>): boolean =>\n\tgroup.app === ROUTER_SHARED_APP && group.stack.startsWith(`${ROUTER_SHARED_APP}-`);\n\nexport const collectDirectPruneInventory = (\n\toptions: DirectPruneOptions,\n): Effect.Effect<PruneInventory, unknown> =>\n\tEffect.gen(function* () {\n\t\tconst [containers, routerContainers, networks, volumes, images] = yield* Effect.all(\n\t\t\t[\n\t\t\t\tlistDevstackContainers(),\n\t\t\t\tlistDevstackRouterContainers(),\n\t\t\t\tlistDevstackNetworks(),\n\t\t\t\tlistDevstackVolumes(),\n\t\t\t\tlistDevstackImages(),\n\t\t\t],\n\t\t\t{ concurrency: 'unbounded' },\n\t\t).pipe(Effect.provide(dockerLayer));\n\n\t\tconst buckets = new Map<string, ResourceBucket>();\n\n\t\tfor (const container of containers) {\n\t\t\tconst identity = readAppStack(container.labels);\n\t\t\tif (identity === null) continue;\n\t\t\tconst bucket = addBucket(buckets, identity);\n\t\t\tbucket.containers += 1;\n\t\t\tif (container.state === 'running') bucket.runningContainers += 1;\n\t\t}\n\t\tfor (const container of routerContainers) {\n\t\t\tconst bucket = addBucket(buckets, routerStackForContainer(container.name));\n\t\t\tbucket.containers += 1;\n\t\t\tif (container.state === 'running') bucket.runningContainers += 1;\n\t\t}\n\t\tfor (const network of networks) {\n\t\t\tconst identity = readAppStack(network.labels);\n\t\t\tif (identity === null) continue;\n\t\t\taddBucket(buckets, identity).networks += 1;\n\t\t}\n\t\tfor (const volume of volumes) {\n\t\t\tconst identity = readAppStack(volume.labels);\n\t\t\tif (identity === null) continue;\n\t\t\taddBucket(buckets, identity).volumes += 1;\n\t\t}\n\t\tfor (const image of images) {\n\t\t\tconst identity = readAppStack(image.labels);\n\t\t\tif (identity === null) continue;\n\t\t\taddBucket(buckets, identity).images += 1;\n\t\t}\n\n\t\tconst groups: Array<PruneGroup> = [];\n\t\tfor (const [key, bucket] of buckets) {\n\t\t\tconst [app, stack] = key.split('/') as [string, string];\n\t\t\tconst routerGroup = app === ROUTER_SHARED_APP;\n\t\t\tconst livePids = routerGroup ? [] : yield* livePidsForStack(options.runtimeRoot, stack);\n\t\t\tgroups.push({\n\t\t\t\tkey,\n\t\t\t\tapp,\n\t\t\t\tstack,\n\t\t\t\tlive: routerGroup ? bucket.runningContainers > 0 : livePids.length > 0,\n\t\t\t\tlivePids,\n\t\t\t\tshared: isSharedGroup(app, stack),\n\t\t\t\tcontainers: bucket.containers,\n\t\t\t\trunningContainers: bucket.runningContainers,\n\t\t\t\tnetworks: bucket.networks,\n\t\t\t\tvolumes: bucket.volumes,\n\t\t\t\timages: bucket.images,\n\t\t\t});\n\t\t}\n\n\t\tgroups.sort((a, b) => {\n\t\t\tif (a.app !== b.app) return a.app < b.app ? -1 : 1;\n\t\t\treturn a.stack < b.stack ? -1 : a.stack > b.stack ? 1 : 0;\n\t\t});\n\n\t\treturn { groups, totals: summarizePruneGroups(groups) };\n\t});\n\nconst selectedGroups = (\n\tinventory: PruneInventory,\n\tselection: PruneSelection,\n): ReadonlyArray<PruneGroup> => {\n\tconst selected = new Set(selection.groupKeys);\n\treturn inventory.groups.filter((group) => selected.has(group.key));\n};\n\nexport const pruneDirectSelection = (\n\toptions: DirectPruneOptions,\n\tselection: PruneSelection,\n): Effect.Effect<PruneOutcome, unknown> =>\n\tEffect.gen(function* () {\n\t\tconst inventory = yield* collectDirectPruneInventory(options);\n\t\tconst groups = selectedGroups(inventory, selection);\n\t\tlet skippedLiveGroups = 0;\n\t\tlet containersRemoved = 0;\n\t\tlet networksRemoved = 0;\n\t\tlet networksSkipped = 0;\n\t\tlet volumesRemoved = 0;\n\t\tlet imagesRemoved = 0;\n\n\t\tconst prunableGroups: Array<PruneGroup> = [];\n\t\tfor (const group of groups) {\n\t\t\tif (group.live) {\n\t\t\t\tskippedLiveGroups += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tprunableGroups.push(group);\n\t\t\tif (selection.dryRun) {\n\t\t\t\tif (selection.resources.containers) containersRemoved += group.containers;\n\t\t\t\tif (selection.resources.networks) networksRemoved += group.networks;\n\t\t\t\tif (selection.resources.volumes) volumesRemoved += group.volumes;\n\t\t\t\tif (selection.resources.images) imagesRemoved += group.images;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tif (!selection.dryRun && selection.resources.containers) {\n\t\t\tfor (const group of prunableGroups) {\n\t\t\t\tif (isRouterGroup(group)) {\n\t\t\t\t\tcontainersRemoved += yield* removeDevstackRouterContainers(group.stack).pipe(\n\t\t\t\t\t\tEffect.provide(dockerLayer),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst match = { app: group.app, stack: group.stack };\n\t\t\t\t\tcontainersRemoved += yield* removeDevstackContainers(match).pipe(\n\t\t\t\t\t\tEffect.provide(dockerLayer),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!selection.dryRun && selection.resources.networks) {\n\t\t\tfor (const group of prunableGroups) {\n\t\t\t\tconst match = { app: group.app, stack: group.stack };\n\t\t\t\tconst result = yield* removeDevstackNetworksBestEffort(match).pipe(\n\t\t\t\t\tEffect.provide(dockerLayer),\n\t\t\t\t);\n\t\t\t\tnetworksRemoved += result.removed;\n\t\t\t\tnetworksSkipped += result.skippedInUse;\n\t\t\t}\n\t\t}\n\n\t\tif (!selection.dryRun && selection.resources.volumes) {\n\t\t\tfor (const group of prunableGroups) {\n\t\t\t\tconst match = { app: group.app, stack: group.stack };\n\t\t\t\tvolumesRemoved += yield* removeDevstackVolumes(match).pipe(Effect.provide(dockerLayer));\n\t\t\t}\n\t\t}\n\n\t\tif (!selection.dryRun && selection.resources.images) {\n\t\t\tfor (const group of prunableGroups) {\n\t\t\t\tconst match = { app: group.app, stack: group.stack };\n\t\t\t\timagesRemoved += yield* removeDevstackImages(match).pipe(Effect.provide(dockerLayer));\n\t\t\t}\n\t\t}\n\n\t\tif (!selection.dryRun) {\n\t\t\tfor (const group of prunableGroups) {\n\t\t\t\tif (!isRouterGroup(group)) continue;\n\t\t\t\tyield* removeRouterProfileStateForDockerStack({\n\t\t\t\t\truntimeRoot: options.runtimeRoot,\n\t\t\t\t\trouterStack: group.stack,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tkind: 'completed' as const,\n\t\t\tsummary: {\n\t\t\t\tinspectedGroups: groups.length,\n\t\t\t\tselectedGroups: groups.length,\n\t\t\t\tskippedLiveGroups,\n\t\t\t\tcontainersRemoved,\n\t\t\t\tnetworksRemoved,\n\t\t\t\tnetworksSkipped,\n\t\t\t\tvolumesRemoved,\n\t\t\t\timagesRemoved,\n\t\t\t},\n\t\t};\n\t});\n\nexport const makeDirectPruneDeps = (options: DirectPruneOptions): PruneDeps => ({\n\tinventory: () => collectDirectPruneInventory(options),\n\tprune: (selection) => pruneDirectSelection(options, selection),\n\tselect: (inventory, resources) => selectPruneTargets(inventory, resources),\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"prune-direct.mjs","names":[],"sources":["../../src/cli/prune-direct.ts"],"sourcesContent":["// L4-adjacent CLI infrastructure for `devstack prune`.\n//\n// Per STYLE_GUIDE §7: `cli/*.ts` modules sit alongside the bin entry\n// (`cli/main.ts`) and may import L3 orchestrator/substrate barrels —\n// they are NOT L4 surfaces proper. The actual cross-stack Docker\n// orchestration lives at `orchestrators/lifecycle-prune/`; this file\n// is the deps-builder the bin entry hands to the `prune` verb runner.\n\nimport { Effect } from 'effect';\n\nimport {\n\tcollectLifecyclePruneInventory,\n\ttype LifecyclePruneError,\n\ttype LifecyclePruneGroup,\n\ttype LifecyclePruneInventory,\n\ttype LifecyclePruneOptions,\n\trunLifecyclePrune,\n} from '../orchestrators/lifecycle-prune/index.ts';\nimport {\n\tsummarizePruneGroups,\n\ttype PruneDeps,\n\ttype PruneGroup,\n\ttype PruneInventory,\n\ttype PruneOutcome,\n\ttype PruneSelection,\n} from '../surfaces/cli/commands/index.ts';\nimport { selectPruneTargets } from '../surfaces/cli/commands/prune-picker-entry.ts';\n\nconst adaptGroup = (group: LifecyclePruneGroup): PruneGroup => ({\n\tkey: group.key,\n\tapp: group.app,\n\tstack: group.stack,\n\tlive: group.live,\n\tlivePids: group.livePids,\n\tshared: group.shared,\n\tsharedKind: group.sharedKind,\n\tautoPrunable: group.autoPrunable,\n\tcontainers: group.containers,\n\trunningContainers: group.runningContainers,\n\tnetworks: group.networks,\n\tvolumes: group.volumes,\n\timages: group.images,\n});\n\nconst adaptInventory = (inventory: LifecyclePruneInventory): PruneInventory => {\n\tconst groups = inventory.groups.map(adaptGroup);\n\treturn { groups, totals: summarizePruneGroups(groups) };\n};\n\n// Internal helpers preserve the orchestrator's typed `LifecyclePruneError`\n// channel. The `PruneDeps` surface contract still accepts `unknown` for\n// the E channel (the surface module owns its own CliError projection via\n// `mapUnknownPruneError`); Effect's covariant E channel means\n// `LifecyclePruneError` flows up cleanly without erasing the type here.\n\nconst collectInventory = (\n\toptions: LifecyclePruneOptions,\n): Effect.Effect<PruneInventory, LifecyclePruneError> =>\n\tcollectLifecyclePruneInventory(options).pipe(Effect.map(adaptInventory));\n\nconst pruneSelection = (\n\toptions: LifecyclePruneOptions,\n\tselection: PruneSelection,\n): Effect.Effect<PruneOutcome, LifecyclePruneError> =>\n\trunLifecyclePrune(options, {\n\t\tgroupKeys: selection.groupKeys,\n\t\tresources: selection.resources,\n\t\tdryRun: selection.dryRun,\n\t}).pipe(Effect.map((summary) => ({ kind: 'completed' as const, summary })));\n\nexport const makeDirectPruneDeps = (options: LifecyclePruneOptions): PruneDeps => ({\n\tinventory: () => collectInventory(options),\n\tprune: (selection) => pruneSelection(options, selection),\n\tselect: (inventory, resources) => selectPruneTargets(inventory, resources),\n});\n"],"mappings":";;;;;;AA4BA,MAAM,cAAc,WAA4C;CAC/D,KAAK,MAAM;CACX,KAAK,MAAM;CACX,OAAO,MAAM;CACb,MAAM,MAAM;CACZ,UAAU,MAAM;CAChB,QAAQ,MAAM;CACd,YAAY,MAAM;CAClB,cAAc,MAAM;CACpB,YAAY,MAAM;CAClB,mBAAmB,MAAM;CACzB,UAAU,MAAM;CAChB,SAAS,MAAM;CACf,QAAQ,MAAM;CACd;AAED,MAAM,kBAAkB,cAAuD;CAC9E,MAAM,SAAS,UAAU,OAAO,IAAI,WAAW;AAC/C,QAAO;EAAE;EAAQ,QAAQ,qBAAqB,OAAO;EAAE;;AASxD,MAAM,oBACL,YAEA,+BAA+B,QAAQ,CAAC,KAAK,OAAO,IAAI,eAAe,CAAC;AAEzE,MAAM,kBACL,SACA,cAEA,kBAAkB,SAAS;CAC1B,WAAW,UAAU;CACrB,WAAW,UAAU;CACrB,QAAQ,UAAU;CAClB,CAAC,CAAC,KAAK,OAAO,KAAK,aAAa;CAAE,MAAM;CAAsB;CAAS,EAAE,CAAC;AAE5E,MAAa,uBAAuB,aAA+C;CAClF,iBAAiB,iBAAiB,QAAQ;CAC1C,QAAQ,cAAc,eAAe,SAAS,UAAU;CACxD,SAAS,WAAW,cAAc,mBAAmB,WAAW,UAAU;CAC1E"}
@@ -1,9 +1,10 @@
1
+ import { decodeJsonTextSync } from "../substrate/runtime/runtime-decode.mjs";
1
2
  import { SnapshotLayout, SnapshotMetadataSchema, parseSnapshotId } from "../orchestrators/snapshot/descriptor.mjs";
2
- import { Effect, Schema } from "effect";
3
+ import "../orchestrators/snapshot/index.mjs";
4
+ import { Effect } from "effect";
3
5
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
4
6
  import { resolve } from "node:path";
5
7
  //#region src/cli/snapshot-reader.ts
6
- const decodeSnapshotMetadata = Schema.decodeUnknownSync(SnapshotMetadataSchema);
7
8
  const makeSnapshotReader = (identity) => {
8
9
  const readEntries = () => {
9
10
  const snapshotDir = resolve(identity.stackRoot, "snapshots");
@@ -21,7 +22,10 @@ const makeSnapshotReader = (identity) => {
21
22
  size: null
22
23
  }];
23
24
  try {
24
- const meta = decodeSnapshotMetadata(JSON.parse(readFileSync(metaPath, "utf8")));
25
+ const meta = decodeJsonTextSync(SnapshotMetadataSchema, readFileSync(metaPath, "utf8"), {
26
+ source: metaPath,
27
+ mkError: (issue) => issue
28
+ });
25
29
  return [{
26
30
  snapshotId: parsedEntryId,
27
31
  name: meta.label,
@@ -47,20 +51,19 @@ const makeSnapshotReader = (identity) => {
47
51
  try: () => {
48
52
  const entries = readEntries();
49
53
  const byId = entries.find((entry) => entry.snapshotId === snapshotRef);
50
- if (byId !== void 0) return {
51
- tag: "found",
52
- entry: byId
53
- };
54
54
  const byName = entries.filter((entry) => entry.name === snapshotRef);
55
- if (byName.length === 0) return { tag: "not-found" };
56
- if (byName.length === 1) return {
55
+ const distinct = /* @__PURE__ */ new Map();
56
+ if (byId !== void 0) distinct.set(byId.snapshotId, byId);
57
+ for (const entry of byName) distinct.set(entry.snapshotId, entry);
58
+ if (distinct.size === 0) return { tag: "not-found" };
59
+ if (distinct.size === 1) return {
57
60
  tag: "found",
58
- entry: byName[0]
61
+ entry: distinct.values().next().value
59
62
  };
60
63
  return {
61
64
  tag: "ambiguous",
62
65
  snapshotRef,
63
- matches: byName
66
+ matches: Array.from(distinct.values())
64
67
  };
65
68
  },
66
69
  catch: (cause) => cause
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-reader.mjs","names":["resolvePath"],"sources":["../../src/cli/snapshot-reader.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { resolve as resolvePath } from 'node:path';\n\nimport { Effect, Schema } from 'effect';\n\nimport {\n\tSnapshotLayout,\n\tSnapshotMetadataSchema,\n\tparseSnapshotId,\n} from '../orchestrators/snapshot/index.ts';\nimport type {\n\tSnapshotEntry,\n\tSnapshotReader,\n\tSnapshotResolveResult,\n} from '../surfaces/cli/commands/snapshot.ts';\n\nconst decodeSnapshotMetadata = Schema.decodeUnknownSync(SnapshotMetadataSchema);\n\nexport interface SnapshotReaderIdentity {\n\treadonly stackRoot: string;\n}\n\nexport const makeSnapshotReader = (identity: SnapshotReaderIdentity): SnapshotReader => {\n\tconst readEntries = (): ReadonlyArray<SnapshotEntry> => {\n\t\tconst snapshotDir = resolvePath(identity.stackRoot, 'snapshots');\n\t\tif (!existsSync(snapshotDir)) return [];\n\t\treturn readdirSync(snapshotDir, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n\t\t\t.flatMap((entry) => {\n\t\t\t\tconst parsedEntryId = parseSnapshotId(entry.name);\n\t\t\t\tif (parsedEntryId === null) return [];\n\t\t\t\tconst dir = resolvePath(snapshotDir, entry.name);\n\t\t\t\tconst fallbackCreatedAt = statSync(dir).mtimeMs;\n\t\t\t\tconst metaPath = resolvePath(dir, SnapshotLayout.metaFile);\n\t\t\t\tif (!existsSync(metaPath)) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: null,\n\t\t\t\t\t\t\tcreatedAt: fallbackCreatedAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(readFileSync(metaPath, 'utf8')) as unknown;\n\t\t\t\t\tconst meta = decodeSnapshotMetadata(parsed);\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: meta.label,\n\t\t\t\t\t\t\tcreatedAt: meta.createdAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t} catch {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: null,\n\t\t\t\t\t\t\tcreatedAt: fallbackCreatedAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t});\n\t};\n\treturn {\n\t\tlist: () =>\n\t\t\tEffect.try({\n\t\t\t\ttry: readEntries,\n\t\t\t\tcatch: (cause) => cause,\n\t\t\t}).pipe(Effect.orElseSucceed(() => [])),\n\t\tresolve: (snapshotRef) =>\n\t\t\tEffect.try({\n\t\t\t\ttry: (): SnapshotResolveResult => {\n\t\t\t\t\tconst entries = readEntries();\n\t\t\t\t\tconst byId = entries.find((entry) => entry.snapshotId === snapshotRef);\n\t\t\t\t\tif (byId !== undefined) return { tag: 'found', entry: byId };\n\t\t\t\t\tconst byName = entries.filter((entry) => entry.name === snapshotRef);\n\t\t\t\t\tif (byName.length === 0) return { tag: 'not-found' };\n\t\t\t\t\tif (byName.length === 1) return { tag: 'found', entry: byName[0]! };\n\t\t\t\t\treturn { tag: 'ambiguous', snapshotRef, matches: byName };\n\t\t\t\t},\n\t\t\t\tcatch: (cause) => cause,\n\t\t\t}).pipe(Effect.orElseSucceed((): SnapshotResolveResult => ({ tag: 'not-found' }))),\n\t};\n};\n"],"mappings":";;;;;AAgBA,MAAM,yBAAyB,OAAO,kBAAkB,uBAAuB;AAM/E,MAAa,sBAAsB,aAAqD;CACvF,MAAM,oBAAkD;EACvD,MAAM,cAAcA,QAAY,SAAS,WAAW,YAAY;AAChE,MAAI,CAAC,WAAW,YAAY,CAAE,QAAO,EAAE;AACvC,SAAO,YAAY,aAAa,EAAE,eAAe,MAAM,CAAC,CACtD,QAAQ,UAAU,MAAM,aAAa,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CACrE,SAAS,UAAU;GACnB,MAAM,gBAAgB,gBAAgB,MAAM,KAAK;AACjD,OAAI,kBAAkB,KAAM,QAAO,EAAE;GACrC,MAAM,MAAMA,QAAY,aAAa,MAAM,KAAK;GAChD,MAAM,oBAAoB,SAAS,IAAI,CAAC;GACxC,MAAM,WAAWA,QAAY,KAAK,eAAe,SAAS;AAC1D,OAAI,CAAC,WAAW,SAAS,CACxB,QAAO,CACN;IACC,YAAY;IACZ,MAAM;IACN,WAAW;IACX,MAAM;IACN,CACD;AAEF,OAAI;IAEH,MAAM,OAAO,uBADE,KAAK,MAAM,aAAa,UAAU,OAAO,CACd,CAAC;AAC3C,WAAO,CACN;KACC,YAAY;KACZ,MAAM,KAAK;KACX,WAAW,KAAK;KAChB,MAAM;KACN,CACD;WACM;AACP,WAAO,CACN;KACC,YAAY;KACZ,MAAM;KACN,WAAW;KACX,MAAM;KACN,CACD;;IAED;;AAEJ,QAAO;EACN,YACC,OAAO,IAAI;GACV,KAAK;GACL,QAAQ,UAAU;GAClB,CAAC,CAAC,KAAK,OAAO,oBAAoB,EAAE,CAAC,CAAC;EACxC,UAAU,gBACT,OAAO,IAAI;GACV,WAAkC;IACjC,MAAM,UAAU,aAAa;IAC7B,MAAM,OAAO,QAAQ,MAAM,UAAU,MAAM,eAAe,YAAY;AACtE,QAAI,SAAS,KAAA,EAAW,QAAO;KAAE,KAAK;KAAS,OAAO;KAAM;IAC5D,MAAM,SAAS,QAAQ,QAAQ,UAAU,MAAM,SAAS,YAAY;AACpE,QAAI,OAAO,WAAW,EAAG,QAAO,EAAE,KAAK,aAAa;AACpD,QAAI,OAAO,WAAW,EAAG,QAAO;KAAE,KAAK;KAAS,OAAO,OAAO;KAAK;AACnE,WAAO;KAAE,KAAK;KAAa;KAAa,SAAS;KAAQ;;GAE1D,QAAQ,UAAU;GAClB,CAAC,CAAC,KAAK,OAAO,qBAA4C,EAAE,KAAK,aAAa,EAAE,CAAC;EACnF"}
1
+ {"version":3,"file":"snapshot-reader.mjs","names":["resolvePath"],"sources":["../../src/cli/snapshot-reader.ts"],"sourcesContent":["import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';\nimport { resolve as resolvePath } from 'node:path';\n\nimport { Effect } from 'effect';\n\nimport {\n\tSnapshotLayout,\n\tSnapshotMetadataSchema,\n\tparseSnapshotId,\n} from '../orchestrators/snapshot/index.ts';\nimport { decodeJsonTextSync } from '../substrate/runtime/runtime-decode.ts';\nimport type {\n\tSnapshotEntry,\n\tSnapshotReader,\n\tSnapshotResolveResult,\n} from '../surfaces/cli/commands/snapshot.ts';\n\nexport interface SnapshotReaderIdentity {\n\treadonly stackRoot: string;\n}\n\nexport const makeSnapshotReader = (identity: SnapshotReaderIdentity): SnapshotReader => {\n\tconst readEntries = (): ReadonlyArray<SnapshotEntry> => {\n\t\tconst snapshotDir = resolvePath(identity.stackRoot, 'snapshots');\n\t\tif (!existsSync(snapshotDir)) return [];\n\t\treturn readdirSync(snapshotDir, { withFileTypes: true })\n\t\t\t.filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))\n\t\t\t.flatMap((entry) => {\n\t\t\t\tconst parsedEntryId = parseSnapshotId(entry.name);\n\t\t\t\tif (parsedEntryId === null) return [];\n\t\t\t\tconst dir = resolvePath(snapshotDir, entry.name);\n\t\t\t\tconst fallbackCreatedAt = statSync(dir).mtimeMs;\n\t\t\t\tconst metaPath = resolvePath(dir, SnapshotLayout.metaFile);\n\t\t\t\tif (!existsSync(metaPath)) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: null,\n\t\t\t\t\t\t\tcreatedAt: fallbackCreatedAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst meta = decodeJsonTextSync(SnapshotMetadataSchema, readFileSync(metaPath, 'utf8'), {\n\t\t\t\t\t\tsource: metaPath,\n\t\t\t\t\t\tmkError: (issue) => issue,\n\t\t\t\t\t});\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: meta.label,\n\t\t\t\t\t\t\tcreatedAt: meta.createdAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t} catch {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsnapshotId: parsedEntryId,\n\t\t\t\t\t\t\tname: null,\n\t\t\t\t\t\t\tcreatedAt: fallbackCreatedAt,\n\t\t\t\t\t\t\tsize: null,\n\t\t\t\t\t\t} satisfies SnapshotEntry,\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t});\n\t};\n\treturn {\n\t\tlist: () =>\n\t\t\tEffect.try({\n\t\t\t\ttry: readEntries,\n\t\t\t\tcatch: (cause) => cause,\n\t\t\t}).pipe(Effect.orElseSucceed(() => [])),\n\t\tresolve: (snapshotRef) =>\n\t\t\tEffect.try({\n\t\t\t\ttry: (): SnapshotResolveResult => {\n\t\t\t\t\tconst entries = readEntries();\n\t\t\t\t\t// Resolve id-vs-name in a single pass so a ref that matches\n\t\t\t\t\t// BOTH an id AND a name (different entries) surfaces as\n\t\t\t\t\t// ambiguous instead of silently shadowing the name match\n\t\t\t\t\t// with the id match. The auto-mint format\n\t\t\t\t\t// (`snap-<ts>-<uuid>`) satisfies the same grammar as a\n\t\t\t\t\t// user-supplied name, so id-first fall-through was a real\n\t\t\t\t\t// foot-gun: a user typing a label that happened to equal\n\t\t\t\t\t// an existing snapshot id would restore the wrong artifact.\n\t\t\t\t\tconst byId = entries.find((entry) => entry.snapshotId === snapshotRef);\n\t\t\t\t\tconst byName = entries.filter((entry) => entry.name === snapshotRef);\n\n\t\t\t\t\t// Same entry matched by both axes (unusual but well-defined):\n\t\t\t\t\t// caller's intent is unambiguous because there is exactly\n\t\t\t\t\t// one matching artifact.\n\t\t\t\t\tconst distinct = new Map<string, SnapshotEntry>();\n\t\t\t\t\tif (byId !== undefined) distinct.set(byId.snapshotId, byId);\n\t\t\t\t\tfor (const entry of byName) distinct.set(entry.snapshotId, entry);\n\n\t\t\t\t\tif (distinct.size === 0) return { tag: 'not-found' };\n\t\t\t\t\tif (distinct.size === 1) {\n\t\t\t\t\t\tconst only = distinct.values().next().value as SnapshotEntry;\n\t\t\t\t\t\treturn { tag: 'found', entry: only };\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttag: 'ambiguous',\n\t\t\t\t\t\tsnapshotRef,\n\t\t\t\t\t\tmatches: Array.from(distinct.values()),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\tcatch: (cause) => cause,\n\t\t\t}).pipe(Effect.orElseSucceed((): SnapshotResolveResult => ({ tag: 'not-found' }))),\n\t};\n};\n"],"mappings":";;;;;;;AAqBA,MAAa,sBAAsB,aAAqD;CACvF,MAAM,oBAAkD;EACvD,MAAM,cAAcA,QAAY,SAAS,WAAW,YAAY;AAChE,MAAI,CAAC,WAAW,YAAY,CAAE,QAAO,EAAE;AACvC,SAAO,YAAY,aAAa,EAAE,eAAe,MAAM,CAAC,CACtD,QAAQ,UAAU,MAAM,aAAa,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,CACrE,SAAS,UAAU;GACnB,MAAM,gBAAgB,gBAAgB,MAAM,KAAK;AACjD,OAAI,kBAAkB,KAAM,QAAO,EAAE;GACrC,MAAM,MAAMA,QAAY,aAAa,MAAM,KAAK;GAChD,MAAM,oBAAoB,SAAS,IAAI,CAAC;GACxC,MAAM,WAAWA,QAAY,KAAK,eAAe,SAAS;AAC1D,OAAI,CAAC,WAAW,SAAS,CACxB,QAAO,CACN;IACC,YAAY;IACZ,MAAM;IACN,WAAW;IACX,MAAM;IACN,CACD;AAEF,OAAI;IACH,MAAM,OAAO,mBAAmB,wBAAwB,aAAa,UAAU,OAAO,EAAE;KACvF,QAAQ;KACR,UAAU,UAAU;KACpB,CAAC;AACF,WAAO,CACN;KACC,YAAY;KACZ,MAAM,KAAK;KACX,WAAW,KAAK;KAChB,MAAM;KACN,CACD;WACM;AACP,WAAO,CACN;KACC,YAAY;KACZ,MAAM;KACN,WAAW;KACX,MAAM;KACN,CACD;;IAED;;AAEJ,QAAO;EACN,YACC,OAAO,IAAI;GACV,KAAK;GACL,QAAQ,UAAU;GAClB,CAAC,CAAC,KAAK,OAAO,oBAAoB,EAAE,CAAC,CAAC;EACxC,UAAU,gBACT,OAAO,IAAI;GACV,WAAkC;IACjC,MAAM,UAAU,aAAa;IAS7B,MAAM,OAAO,QAAQ,MAAM,UAAU,MAAM,eAAe,YAAY;IACtE,MAAM,SAAS,QAAQ,QAAQ,UAAU,MAAM,SAAS,YAAY;IAKpE,MAAM,2BAAW,IAAI,KAA4B;AACjD,QAAI,SAAS,KAAA,EAAW,UAAS,IAAI,KAAK,YAAY,KAAK;AAC3D,SAAK,MAAM,SAAS,OAAQ,UAAS,IAAI,MAAM,YAAY,MAAM;AAEjE,QAAI,SAAS,SAAS,EAAG,QAAO,EAAE,KAAK,aAAa;AACpD,QAAI,SAAS,SAAS,EAErB,QAAO;KAAE,KAAK;KAAS,OADV,SAAS,QAAQ,CAAC,MAAM,CAAC;KACF;AAErC,WAAO;KACN,KAAK;KACL;KACA,SAAS,MAAM,KAAK,SAAS,QAAQ,CAAC;KACtC;;GAEF,QAAQ,UAAU;GAClB,CAAC,CAAC,KAAK,OAAO,qBAA4C,EAAE,KAAK,aAAa,EAAE,CAAC;EACnF"}
@@ -19,7 +19,10 @@ const scheduleProcessExit = (exitCode) => {
19
19
  });
20
20
  };
21
21
  const makeQueueCommandPublisher = (commands, options = {}) => (command) => {
22
- if (command.tag === "shutdown.hardKillRequested") (options.scheduleHardExit ?? scheduleProcessExit)(command.exitCode);
22
+ if (command.tag === "shutdown.hardKillRequested") {
23
+ (options.scheduleHardExit ?? scheduleProcessExit)(command.exitCode);
24
+ return;
25
+ }
23
26
  Effect.runFork(Queue.offer(commands, command));
24
27
  };
25
28
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"up-lifecycle.mjs","names":[],"sources":["../../src/cli/up-lifecycle.ts"],"sourcesContent":["import { Effect, Queue } from 'effect';\n\nimport type { EngineCommand } from '../substrate/events.ts';\nimport { resolveMode, type RendererMode } from '../surfaces/tui/mode-detect.ts';\nimport type { CliRendererMode } from '../surfaces/cli/flags.ts';\n\nexport interface ResolveUpRendererModeInput {\n\treadonly cliRenderer: CliRendererMode | undefined;\n\treadonly stackRenderer: 'tui' | 'plain' | 'silent' | undefined;\n\treadonly stdoutIsTty: boolean;\n}\n\nconst toRendererMode = (\n\tmode: CliRendererMode | 'tui' | 'plain' | 'silent' | undefined,\n): RendererMode | undefined => {\n\tswitch (mode) {\n\t\tcase undefined:\n\t\t\treturn undefined;\n\t\tcase 'tui':\n\t\t\treturn 'ink';\n\t\tcase 'plain':\n\t\tcase 'silent':\n\t\t\treturn mode;\n\t}\n};\n\nexport const resolveUpRendererMode = (input: ResolveUpRendererModeInput): RendererMode =>\n\tresolveMode({\n\t\trequested: toRendererMode(input.cliRenderer ?? input.stackRenderer),\n\t\tstdoutIsTty: input.stdoutIsTty,\n\t});\n\nexport interface QueueCommandPublisherOptions {\n\treadonly scheduleHardExit?: (exitCode: number) => void;\n}\n\nconst scheduleProcessExit = (exitCode: number): void => {\n\tsetImmediate(() => {\n\t\tprocess.exit(exitCode);\n\t});\n};\n\nexport const makeQueueCommandPublisher =\n\t(\n\t\tcommands: Queue.Enqueue<EngineCommand>,\n\t\toptions: QueueCommandPublisherOptions = {},\n\t): ((command: EngineCommand) => void) =>\n\t(command) => {\n\t\tif (command.tag === 'shutdown.hardKillRequested') {\n\t\t\t(options.scheduleHardExit ?? scheduleProcessExit)(command.exitCode);\n\t\t}\n\t\tEffect.runFork(Queue.offer(commands, command));\n\t};\n"],"mappings":";;;AAYA,MAAM,kBACL,SAC8B;AAC9B,SAAQ,MAAR;EACC,KAAK,KAAA,EACJ;EACD,KAAK,MACJ,QAAO;EACR,KAAK;EACL,KAAK,SACJ,QAAO;;;AAIV,MAAa,yBAAyB,UACrC,YAAY;CACX,WAAW,eAAe,MAAM,eAAe,MAAM,cAAc;CACnE,aAAa,MAAM;CACnB,CAAC;AAMH,MAAM,uBAAuB,aAA2B;AACvD,oBAAmB;AAClB,UAAQ,KAAK,SAAS;GACrB;;AAGH,MAAa,6BAEX,UACA,UAAwC,EAAE,MAE1C,YAAY;AACZ,KAAI,QAAQ,QAAQ,6BACnB,EAAC,QAAQ,oBAAoB,qBAAqB,QAAQ,SAAS;AAEpE,QAAO,QAAQ,MAAM,MAAM,UAAU,QAAQ,CAAC"}
1
+ {"version":3,"file":"up-lifecycle.mjs","names":[],"sources":["../../src/cli/up-lifecycle.ts"],"sourcesContent":["import { Effect, Queue } from 'effect';\n\nimport type { EngineCommand } from '../substrate/events.ts';\nimport { resolveMode, type RendererMode } from '../surfaces/tui/mode-detect.ts';\nimport type { CliRendererMode } from '../surfaces/cli/flags.ts';\n\nexport interface ResolveUpRendererModeInput {\n\treadonly cliRenderer: CliRendererMode | undefined;\n\treadonly stackRenderer: 'tui' | 'plain' | 'silent' | undefined;\n\treadonly stdoutIsTty: boolean;\n}\n\nconst toRendererMode = (\n\tmode: CliRendererMode | 'tui' | 'plain' | 'silent' | undefined,\n): RendererMode | undefined => {\n\tswitch (mode) {\n\t\tcase undefined:\n\t\t\treturn undefined;\n\t\tcase 'tui':\n\t\t\treturn 'ink';\n\t\tcase 'plain':\n\t\tcase 'silent':\n\t\t\treturn mode;\n\t}\n};\n\nexport const resolveUpRendererMode = (input: ResolveUpRendererModeInput): RendererMode =>\n\tresolveMode({\n\t\trequested: toRendererMode(input.cliRenderer ?? input.stackRenderer),\n\t\tstdoutIsTty: input.stdoutIsTty,\n\t});\n\nexport interface QueueCommandPublisherOptions {\n\treadonly scheduleHardExit?: (exitCode: number) => void;\n}\n\nconst scheduleProcessExit = (exitCode: number): void => {\n\tsetImmediate(() => {\n\t\tprocess.exit(exitCode);\n\t});\n};\n\nexport const makeQueueCommandPublisher =\n\t(\n\t\tcommands: Queue.Enqueue<EngineCommand>,\n\t\toptions: QueueCommandPublisherOptions = {},\n\t): ((command: EngineCommand) => void) =>\n\t(command) => {\n\t\t// `hardKillRequested` escalates directly via `process.exit` —\n\t\t// `setImmediate(process.exit)` fires before the supervisor's\n\t\t// command loop can dequeue in the same tick, so any queue offer\n\t\t// here would be dead code. The supervisor still observes the\n\t\t// hard-kill through the signal handler chain\n\t\t// (`substrate/runtime/lifecycle/signals.ts`); this publisher\n\t\t// only handles the TUI keypress path and the platform exit is\n\t\t// authoritative for it.\n\t\tif (command.tag === 'shutdown.hardKillRequested') {\n\t\t\t(options.scheduleHardExit ?? scheduleProcessExit)(command.exitCode);\n\t\t\treturn;\n\t\t}\n\t\tEffect.runFork(Queue.offer(commands, command));\n\t};\n"],"mappings":";;;AAYA,MAAM,kBACL,SAC8B;AAC9B,SAAQ,MAAR;EACC,KAAK,KAAA,EACJ;EACD,KAAK,MACJ,QAAO;EACR,KAAK;EACL,KAAK,SACJ,QAAO;;;AAIV,MAAa,yBAAyB,UACrC,YAAY;CACX,WAAW,eAAe,MAAM,eAAe,MAAM,cAAc;CACnE,aAAa,MAAM;CACnB,CAAC;AAMH,MAAM,uBAAuB,aAA2B;AACvD,oBAAmB;AAClB,UAAQ,KAAK,SAAS;GACrB;;AAGH,MAAa,6BAEX,UACA,UAAwC,EAAE,MAE1C,YAAY;AASZ,KAAI,QAAQ,QAAQ,8BAA8B;AACjD,GAAC,QAAQ,oBAAoB,qBAAqB,QAAQ,SAAS;AACnE;;AAED,QAAO,QAAQ,MAAM,MAAM,UAAU,QAAQ,CAAC"}