@nimbus-sh/worker 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 (408) hide show
  1. package/README.md +219 -0
  2. package/dist/_shared/bytes.d.ts +18 -0
  3. package/dist/_shared/bytes.d.ts.map +1 -0
  4. package/dist/_shared/bytes.js +17 -0
  5. package/dist/_shared/cache-stats.d.ts +146 -0
  6. package/dist/_shared/cache-stats.d.ts.map +1 -0
  7. package/dist/_shared/cache-stats.js +162 -0
  8. package/dist/_shared/exports-resolver.d.ts +76 -0
  9. package/dist/_shared/exports-resolver.d.ts.map +1 -0
  10. package/dist/_shared/exports-resolver.js +284 -0
  11. package/dist/_shared/install-phase.d.ts +47 -0
  12. package/dist/_shared/install-phase.d.ts.map +1 -0
  13. package/dist/_shared/install-phase.js +1 -0
  14. package/dist/_shared/real-node-imports.d.ts +38 -0
  15. package/dist/_shared/real-node-imports.d.ts.map +1 -0
  16. package/dist/_shared/real-node-imports.js +46 -0
  17. package/dist/_shared/retry.d.ts +93 -0
  18. package/dist/_shared/retry.d.ts.map +1 -0
  19. package/dist/_shared/retry.js +161 -0
  20. package/dist/_shared/session-id.d.ts +39 -0
  21. package/dist/_shared/session-id.d.ts.map +1 -0
  22. package/dist/_shared/session-id.js +127 -0
  23. package/dist/_shared/session-router.d.ts +104 -0
  24. package/dist/_shared/session-router.d.ts.map +1 -0
  25. package/dist/_shared/session-router.js +165 -0
  26. package/dist/_shared/w7-frame.d.ts +93 -0
  27. package/dist/_shared/w7-frame.d.ts.map +1 -0
  28. package/dist/_shared/w7-frame.js +402 -0
  29. package/dist/auth/index.d.ts +16 -0
  30. package/dist/auth/index.d.ts.map +1 -0
  31. package/dist/auth/index.js +15 -0
  32. package/dist/auth/middleware.d.ts +85 -0
  33. package/dist/auth/middleware.d.ts.map +1 -0
  34. package/dist/auth/middleware.js +150 -0
  35. package/dist/auth/token.d.ts +96 -0
  36. package/dist/auth/token.d.ts.map +1 -0
  37. package/dist/auth/token.js +226 -0
  38. package/dist/auth/types.d.ts +141 -0
  39. package/dist/auth/types.d.ts.map +1 -0
  40. package/dist/auth/types.js +114 -0
  41. package/dist/bindings/d1.d.ts +102 -0
  42. package/dist/bindings/d1.d.ts.map +1 -0
  43. package/dist/bindings/d1.js +549 -0
  44. package/dist/bindings/kv.d.ts +82 -0
  45. package/dist/bindings/kv.d.ts.map +1 -0
  46. package/dist/bindings/kv.js +290 -0
  47. package/dist/bindings/r2.d.ts +137 -0
  48. package/dist/bindings/r2.d.ts.map +1 -0
  49. package/dist/bindings/r2.js +379 -0
  50. package/dist/cirrus-npm-cjs.generated.d.ts +17 -0
  51. package/dist/cirrus-npm-cjs.generated.d.ts.map +1 -0
  52. package/dist/cirrus-npm-cjs.generated.js +41 -0
  53. package/dist/cirrus-plugin-react.generated.d.ts +34 -0
  54. package/dist/cirrus-plugin-react.generated.d.ts.map +1 -0
  55. package/dist/cirrus-plugin-react.generated.js +33 -0
  56. package/dist/constants.d.ts +34 -0
  57. package/dist/constants.d.ts.map +1 -0
  58. package/dist/constants.js +116 -0
  59. package/dist/esbuild-wasm-bundle.generated.d.ts +41 -0
  60. package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -0
  61. package/dist/esbuild-wasm-bundle.generated.js +40 -0
  62. package/dist/facets/cirrus-real.d.ts +147 -0
  63. package/dist/facets/cirrus-real.d.ts.map +1 -0
  64. package/dist/facets/cirrus-real.js +981 -0
  65. package/dist/facets/inner-do-registry.d.ts +41 -0
  66. package/dist/facets/inner-do-registry.d.ts.map +1 -0
  67. package/dist/facets/inner-do-registry.js +51 -0
  68. package/dist/facets/manager.d.ts +314 -0
  69. package/dist/facets/manager.d.ts.map +1 -0
  70. package/dist/facets/manager.js +2681 -0
  71. package/dist/facets/process.d.ts +318 -0
  72. package/dist/facets/process.d.ts.map +1 -0
  73. package/dist/facets/process.js +567 -0
  74. package/dist/facets/real-vite-fs-shim.d.ts +151 -0
  75. package/dist/facets/real-vite-fs-shim.d.ts.map +1 -0
  76. package/dist/facets/real-vite-fs-shim.js +1279 -0
  77. package/dist/facets/real-vite-hmr.d.ts +142 -0
  78. package/dist/facets/real-vite-hmr.d.ts.map +1 -0
  79. package/dist/facets/real-vite-hmr.js +476 -0
  80. package/dist/facets/vite-dev-server.d.ts +293 -0
  81. package/dist/facets/vite-dev-server.d.ts.map +1 -0
  82. package/dist/facets/vite-dev-server.js +2580 -0
  83. package/dist/facets/wasm-swap-registry.d.ts +261 -0
  84. package/dist/facets/wasm-swap-registry.d.ts.map +1 -0
  85. package/dist/facets/wasm-swap-registry.js +551 -0
  86. package/dist/facets/ws-terminal.d.ts +107 -0
  87. package/dist/facets/ws-terminal.d.ts.map +1 -0
  88. package/dist/facets/ws-terminal.js +207 -0
  89. package/dist/git/commands.d.ts +13 -0
  90. package/dist/git/commands.d.ts.map +1 -0
  91. package/dist/git/commands.js +633 -0
  92. package/dist/git/network-facet.d.ts +61 -0
  93. package/dist/git/network-facet.d.ts.map +1 -0
  94. package/dist/git/network-facet.js +700 -0
  95. package/dist/git-bundle.generated.d.ts +16 -0
  96. package/dist/git-bundle.generated.d.ts.map +1 -0
  97. package/dist/git-bundle.generated.js +15 -0
  98. package/dist/index.d.ts +41 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +73 -0
  101. package/dist/loaders/child-process/spawn-facet.d.ts +90 -0
  102. package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -0
  103. package/dist/loaders/child-process/spawn-facet.js +103 -0
  104. package/dist/loaders/child-process/spawn-pool.d.ts +110 -0
  105. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -0
  106. package/dist/loaders/child-process/spawn-pool.js +161 -0
  107. package/dist/loaders/fanout-pool.d.ts +195 -0
  108. package/dist/loaders/fanout-pool.d.ts.map +1 -0
  109. package/dist/loaders/fanout-pool.js +326 -0
  110. package/dist/loaders/generated-workers.d.ts +26 -0
  111. package/dist/loaders/generated-workers.d.ts.map +1 -0
  112. package/dist/loaders/generated-workers.js +25 -0
  113. package/dist/loaders/index.d.ts +15 -0
  114. package/dist/loaders/index.d.ts.map +1 -0
  115. package/dist/loaders/index.js +13 -0
  116. package/dist/loaders/loader-pool.d.ts +273 -0
  117. package/dist/loaders/loader-pool.d.ts.map +1 -0
  118. package/dist/loaders/loader-pool.js +624 -0
  119. package/dist/loaders/npm-resolve-preamble.d.ts +34 -0
  120. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -0
  121. package/dist/loaders/npm-resolve-preamble.js +237 -0
  122. package/dist/loaders/pre-bundle-preamble.d.ts +41 -0
  123. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -0
  124. package/dist/loaders/pre-bundle-preamble.js +114 -0
  125. package/dist/loaders/vendor/codegen.d.ts +24 -0
  126. package/dist/loaders/vendor/codegen.d.ts.map +1 -0
  127. package/dist/loaders/vendor/codegen.js +44 -0
  128. package/dist/loaders/vendor/errors.d.ts +24 -0
  129. package/dist/loaders/vendor/errors.d.ts.map +1 -0
  130. package/dist/loaders/vendor/errors.js +46 -0
  131. package/dist/loaders/vendor/index.d.ts +16 -0
  132. package/dist/loaders/vendor/index.d.ts.map +1 -0
  133. package/dist/loaders/vendor/index.js +11 -0
  134. package/dist/loaders/vendor/pool.d.ts +88 -0
  135. package/dist/loaders/vendor/pool.d.ts.map +1 -0
  136. package/dist/loaders/vendor/pool.js +353 -0
  137. package/dist/loaders/vendor/primitives.d.ts +11 -0
  138. package/dist/loaders/vendor/primitives.d.ts.map +1 -0
  139. package/dist/loaders/vendor/primitives.js +33 -0
  140. package/dist/loaders/vendor/serialize.d.ts +3 -0
  141. package/dist/loaders/vendor/serialize.d.ts.map +1 -0
  142. package/dist/loaders/vendor/serialize.js +25 -0
  143. package/dist/loaders/vendor/types.d.ts +60 -0
  144. package/dist/loaders/vendor/types.d.ts.map +1 -0
  145. package/dist/loaders/vendor/types.js +4 -0
  146. package/dist/npm/cache.d.ts +136 -0
  147. package/dist/npm/cache.d.ts.map +1 -0
  148. package/dist/npm/cache.js +429 -0
  149. package/dist/npm/install-batch-facet.d.ts +129 -0
  150. package/dist/npm/install-batch-facet.d.ts.map +1 -0
  151. package/dist/npm/install-batch-facet.js +598 -0
  152. package/dist/npm/install-facet.d.ts +29 -0
  153. package/dist/npm/install-facet.d.ts.map +1 -0
  154. package/dist/npm/install-facet.js +9 -0
  155. package/dist/npm/installer.d.ts +239 -0
  156. package/dist/npm/installer.d.ts.map +1 -0
  157. package/dist/npm/installer.js +2022 -0
  158. package/dist/npm/npx-install.d.ts +74 -0
  159. package/dist/npm/npx-install.d.ts.map +1 -0
  160. package/dist/npm/npx-install.js +302 -0
  161. package/dist/npm/pre-bundle-facet.d.ts +168 -0
  162. package/dist/npm/pre-bundle-facet.d.ts.map +1 -0
  163. package/dist/npm/pre-bundle-facet.js +653 -0
  164. package/dist/npm/r2-cache.d.ts +286 -0
  165. package/dist/npm/r2-cache.d.ts.map +1 -0
  166. package/dist/npm/r2-cache.js +506 -0
  167. package/dist/npm/resolve-facet.d.ts +202 -0
  168. package/dist/npm/resolve-facet.d.ts.map +1 -0
  169. package/dist/npm/resolve-facet.js +833 -0
  170. package/dist/npm/resolve-one-facet.d.ts +204 -0
  171. package/dist/npm/resolve-one-facet.d.ts.map +1 -0
  172. package/dist/npm/resolve-one-facet.js +437 -0
  173. package/dist/npm/resolver.d.ts +109 -0
  174. package/dist/npm/resolver.d.ts.map +1 -0
  175. package/dist/npm/resolver.js +899 -0
  176. package/dist/npm/tarball-stream.d.ts +85 -0
  177. package/dist/npm/tarball-stream.d.ts.map +1 -0
  178. package/dist/npm/tarball-stream.js +205 -0
  179. package/dist/npm/tarball.d.ts +51 -0
  180. package/dist/npm/tarball.d.ts.map +1 -0
  181. package/dist/npm/tarball.js +185 -0
  182. package/dist/observability/diag-counters.d.ts +292 -0
  183. package/dist/observability/diag-counters.d.ts.map +1 -0
  184. package/dist/observability/diag-counters.js +302 -0
  185. package/dist/observability/heap-estimate.d.ts +166 -0
  186. package/dist/observability/heap-estimate.d.ts.map +1 -0
  187. package/dist/observability/heap-estimate.js +192 -0
  188. package/dist/observability/heavy-alloc-coord.d.ts +95 -0
  189. package/dist/observability/heavy-alloc-coord.d.ts.map +1 -0
  190. package/dist/observability/heavy-alloc-coord.js +149 -0
  191. package/dist/observability/oom-classify.d.ts +56 -0
  192. package/dist/observability/oom-classify.d.ts.map +1 -0
  193. package/dist/observability/oom-classify.js +118 -0
  194. package/dist/observability/oom-discriminator.d.ts +192 -0
  195. package/dist/observability/oom-discriminator.d.ts.map +1 -0
  196. package/dist/observability/oom-discriminator.js +233 -0
  197. package/dist/real-vite-bundle.generated.d.ts +46 -0
  198. package/dist/real-vite-bundle.generated.d.ts.map +1 -0
  199. package/dist/real-vite-bundle.generated.js +53 -0
  200. package/dist/replica/routing.d.ts +171 -0
  201. package/dist/replica/routing.d.ts.map +1 -0
  202. package/dist/replica/routing.js +288 -0
  203. package/dist/replica/suspension.d.ts +36 -0
  204. package/dist/replica/suspension.d.ts.map +1 -0
  205. package/dist/replica/suspension.js +49 -0
  206. package/dist/router/index.d.ts +156 -0
  207. package/dist/router/index.d.ts.map +1 -0
  208. package/dist/router/index.js +220 -0
  209. package/dist/runtime/assets-loader.d.ts +71 -0
  210. package/dist/runtime/assets-loader.d.ts.map +1 -0
  211. package/dist/runtime/assets-loader.js +128 -0
  212. package/dist/runtime/barrel-detect.d.ts +46 -0
  213. package/dist/runtime/barrel-detect.d.ts.map +1 -0
  214. package/dist/runtime/barrel-detect.js +73 -0
  215. package/dist/runtime/barrel-synthesizer.d.ts +181 -0
  216. package/dist/runtime/barrel-synthesizer.d.ts.map +1 -0
  217. package/dist/runtime/barrel-synthesizer.js +541 -0
  218. package/dist/runtime/bun-repl.d.ts +46 -0
  219. package/dist/runtime/bun-repl.d.ts.map +1 -0
  220. package/dist/runtime/bun-repl.js +326 -0
  221. package/dist/runtime/bun-runner.d.ts +66 -0
  222. package/dist/runtime/bun-runner.d.ts.map +1 -0
  223. package/dist/runtime/bun-runner.js +219 -0
  224. package/dist/runtime/clang-runner.d.ts +38 -0
  225. package/dist/runtime/clang-runner.d.ts.map +1 -0
  226. package/dist/runtime/clang-runner.js +1033 -0
  227. package/dist/runtime/comment-strip.d.ts +37 -0
  228. package/dist/runtime/comment-strip.d.ts.map +1 -0
  229. package/dist/runtime/comment-strip.js +74 -0
  230. package/dist/runtime/esbuild-service.d.ts +201 -0
  231. package/dist/runtime/esbuild-service.d.ts.map +1 -0
  232. package/dist/runtime/esbuild-service.js +1444 -0
  233. package/dist/runtime/esbuild-wasm-bytes.d.ts +87 -0
  234. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -0
  235. package/dist/runtime/esbuild-wasm-bytes.js +131 -0
  236. package/dist/runtime/framework-detect.d.ts +71 -0
  237. package/dist/runtime/framework-detect.d.ts.map +1 -0
  238. package/dist/runtime/framework-detect.js +178 -0
  239. package/dist/runtime/long-running-handle.d.ts +133 -0
  240. package/dist/runtime/long-running-handle.d.ts.map +1 -0
  241. package/dist/runtime/long-running-handle.js +192 -0
  242. package/dist/runtime/node-repl.d.ts +36 -0
  243. package/dist/runtime/node-repl.d.ts.map +1 -0
  244. package/dist/runtime/node-repl.js +293 -0
  245. package/dist/runtime/node-runner.d.ts +111 -0
  246. package/dist/runtime/node-runner.d.ts.map +1 -0
  247. package/dist/runtime/node-runner.js +194 -0
  248. package/dist/runtime/node-shims.d.ts +24 -0
  249. package/dist/runtime/node-shims.d.ts.map +1 -0
  250. package/dist/runtime/node-shims.js +3019 -0
  251. package/dist/runtime/package-manager.d.ts +118 -0
  252. package/dist/runtime/package-manager.d.ts.map +1 -0
  253. package/dist/runtime/package-manager.js +420 -0
  254. package/dist/runtime/port-registry.d.ts +80 -0
  255. package/dist/runtime/port-registry.d.ts.map +1 -0
  256. package/dist/runtime/port-registry.js +166 -0
  257. package/dist/runtime/process-logs-api.d.ts +102 -0
  258. package/dist/runtime/process-logs-api.d.ts.map +1 -0
  259. package/dist/runtime/process-logs-api.js +253 -0
  260. package/dist/runtime/process-logs.d.ts +311 -0
  261. package/dist/runtime/process-logs.d.ts.map +1 -0
  262. package/dist/runtime/process-logs.js +656 -0
  263. package/dist/runtime/process-table.d.ts +65 -0
  264. package/dist/runtime/process-table.d.ts.map +1 -0
  265. package/dist/runtime/process-table.js +107 -0
  266. package/dist/runtime/project-detect.d.ts +21 -0
  267. package/dist/runtime/project-detect.d.ts.map +1 -0
  268. package/dist/runtime/project-detect.js +46 -0
  269. package/dist/runtime/python-repl.d.ts +66 -0
  270. package/dist/runtime/python-repl.d.ts.map +1 -0
  271. package/dist/runtime/python-repl.js +563 -0
  272. package/dist/runtime/python-runner.d.ts +50 -0
  273. package/dist/runtime/python-runner.d.ts.map +1 -0
  274. package/dist/runtime/python-runner.js +870 -0
  275. package/dist/runtime/repl-session.d.ts +160 -0
  276. package/dist/runtime/repl-session.d.ts.map +1 -0
  277. package/dist/runtime/repl-session.js +393 -0
  278. package/dist/runtime/require-resolver.d.ts +52 -0
  279. package/dist/runtime/require-resolver.d.ts.map +1 -0
  280. package/dist/runtime/require-resolver.js +690 -0
  281. package/dist/runtime/router-basename.d.ts +36 -0
  282. package/dist/runtime/router-basename.d.ts.map +1 -0
  283. package/dist/runtime/router-basename.js +310 -0
  284. package/dist/runtime/ruby-repl.d.ts +43 -0
  285. package/dist/runtime/ruby-repl.d.ts.map +1 -0
  286. package/dist/runtime/ruby-repl.js +229 -0
  287. package/dist/runtime/ruby-runner.d.ts +62 -0
  288. package/dist/runtime/ruby-runner.d.ts.map +1 -0
  289. package/dist/runtime/ruby-runner.js +737 -0
  290. package/dist/runtime/runtime-catalog.d.ts +99 -0
  291. package/dist/runtime/runtime-catalog.d.ts.map +1 -0
  292. package/dist/runtime/runtime-catalog.js +183 -0
  293. package/dist/runtime/runtime-registry.d.ts +136 -0
  294. package/dist/runtime/runtime-registry.d.ts.map +1 -0
  295. package/dist/runtime/runtime-registry.js +318 -0
  296. package/dist/runtime/streams.d.ts +13 -0
  297. package/dist/runtime/streams.d.ts.map +1 -0
  298. package/dist/runtime/streams.js +402 -0
  299. package/dist/runtime/wasi-instance.d.ts +190 -0
  300. package/dist/runtime/wasi-instance.d.ts.map +1 -0
  301. package/dist/runtime/wasi-instance.js +2044 -0
  302. package/dist/runtime/wasm-runner.d.ts +117 -0
  303. package/dist/runtime/wasm-runner.d.ts.map +1 -0
  304. package/dist/runtime/wasm-runner.js +705 -0
  305. package/dist/session/bindings.d.ts +168 -0
  306. package/dist/session/bindings.d.ts.map +1 -0
  307. package/dist/session/bindings.js +524 -0
  308. package/dist/session/ctx-exports.d.ts +16 -0
  309. package/dist/session/ctx-exports.d.ts.map +1 -0
  310. package/dist/session/ctx-exports.js +22 -0
  311. package/dist/session/diag.d.ts +62 -0
  312. package/dist/session/diag.d.ts.map +1 -0
  313. package/dist/session/diag.js +118 -0
  314. package/dist/session/fs-watch.d.ts +132 -0
  315. package/dist/session/fs-watch.d.ts.map +1 -0
  316. package/dist/session/fs-watch.js +255 -0
  317. package/dist/session/helpers.d.ts +150 -0
  318. package/dist/session/helpers.d.ts.map +1 -0
  319. package/dist/session/helpers.js +472 -0
  320. package/dist/session/hibernation.d.ts +145 -0
  321. package/dist/session/hibernation.d.ts.map +1 -0
  322. package/dist/session/hibernation.js +385 -0
  323. package/dist/session/init-phases.d.ts +87 -0
  324. package/dist/session/init-phases.d.ts.map +1 -0
  325. package/dist/session/init-phases.js +137 -0
  326. package/dist/session/init.d.ts +46 -0
  327. package/dist/session/init.d.ts.map +1 -0
  328. package/dist/session/init.js +3579 -0
  329. package/dist/session/keys.d.ts +56 -0
  330. package/dist/session/keys.d.ts.map +1 -0
  331. package/dist/session/keys.js +55 -0
  332. package/dist/session/nimbus-session.d.ts +434 -0
  333. package/dist/session/nimbus-session.d.ts.map +1 -0
  334. package/dist/session/nimbus-session.js +1084 -0
  335. package/dist/session/programmatic.d.ts +105 -0
  336. package/dist/session/programmatic.d.ts.map +1 -0
  337. package/dist/session/programmatic.js +326 -0
  338. package/dist/session/replica-routes.d.ts +68 -0
  339. package/dist/session/replica-routes.d.ts.map +1 -0
  340. package/dist/session/replica-routes.js +77 -0
  341. package/dist/session/routes.d.ts +29 -0
  342. package/dist/session/routes.d.ts.map +1 -0
  343. package/dist/session/routes.js +1331 -0
  344. package/dist/session/rpc.d.ts +323 -0
  345. package/dist/session/rpc.d.ts.map +1 -0
  346. package/dist/session/rpc.js +808 -0
  347. package/dist/session/state-store.d.ts +210 -0
  348. package/dist/session/state-store.d.ts.map +1 -0
  349. package/dist/session/state-store.js +459 -0
  350. package/dist/session/supervisor-rpc.d.ts +269 -0
  351. package/dist/session/supervisor-rpc.d.ts.map +1 -0
  352. package/dist/session/supervisor-rpc.js +437 -0
  353. package/dist/session/ws-hibernation-config.d.ts +64 -0
  354. package/dist/session/ws-hibernation-config.d.ts.map +1 -0
  355. package/dist/session/ws-hibernation-config.js +89 -0
  356. package/dist/session/ws.d.ts +95 -0
  357. package/dist/session/ws.d.ts.map +1 -0
  358. package/dist/session/ws.js +395 -0
  359. package/dist/shell/features.d.ts +410 -0
  360. package/dist/shell/features.d.ts.map +1 -0
  361. package/dist/shell/features.js +1885 -0
  362. package/dist/shell/unix-commands.d.ts +15 -0
  363. package/dist/shell/unix-commands.d.ts.map +1 -0
  364. package/dist/shell/unix-commands.js +3703 -0
  365. package/dist/stubs/lifo-ui.d.ts +10 -0
  366. package/dist/stubs/lifo-ui.d.ts.map +1 -0
  367. package/dist/stubs/lifo-ui.js +1 -0
  368. package/dist/tailwind-play.generated.d.ts +19 -0
  369. package/dist/tailwind-play.generated.d.ts.map +1 -0
  370. package/dist/tailwind-play.generated.js +18 -0
  371. package/dist/vfs/dev-provider.d.ts +64 -0
  372. package/dist/vfs/dev-provider.d.ts.map +1 -0
  373. package/dist/vfs/dev-provider.js +191 -0
  374. package/dist/vfs/events.d.ts +51 -0
  375. package/dist/vfs/events.d.ts.map +1 -0
  376. package/dist/vfs/events.js +127 -0
  377. package/dist/vfs/path.d.ts +30 -0
  378. package/dist/vfs/path.d.ts.map +1 -0
  379. package/dist/vfs/path.js +41 -0
  380. package/dist/vfs/seed-project.d.ts +62 -0
  381. package/dist/vfs/seed-project.d.ts.map +1 -0
  382. package/dist/vfs/seed-project.js +1045 -0
  383. package/dist/vfs/sqlite-vfs.d.ts +435 -0
  384. package/dist/vfs/sqlite-vfs.d.ts.map +1 -0
  385. package/dist/vfs/sqlite-vfs.js +1670 -0
  386. package/dist/vfs/symlink-registry.d.ts +64 -0
  387. package/dist/vfs/symlink-registry.d.ts.map +1 -0
  388. package/dist/vfs/symlink-registry.js +137 -0
  389. package/dist/wrangler/nimbus-wrangler.d.ts +157 -0
  390. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -0
  391. package/dist/wrangler/nimbus-wrangler.js +931 -0
  392. package/package.json +77 -0
  393. package/public/_assets/cirrus-plugin-react.bundle.js +70740 -0
  394. package/public/_assets/esbuild-0.24.2.wasm +0 -0
  395. package/public/_assets/real-vite-bundle.js +101478 -0
  396. package/public/_assets/rollup.wasm +0 -0
  397. package/public/favicon.svg +8 -0
  398. package/public/index.html +565 -0
  399. package/public/s/index.html +2379 -0
  400. package/scripts/bundle-esbuild-wasm.mjs +244 -0
  401. package/scripts/bundle-facet-workers.mjs +137 -0
  402. package/scripts/bundle-git.mjs +118 -0
  403. package/scripts/bundle-npm-cjs.mjs +363 -0
  404. package/scripts/bundle-plugin-react.mjs +480 -0
  405. package/scripts/bundle-real-vite.mjs +959 -0
  406. package/scripts/bundle-runtime.mjs +600 -0
  407. package/scripts/bundle-tailwind-play.mjs +130 -0
  408. package/scripts/patch-lifo-ui.mjs +131 -0
@@ -0,0 +1,808 @@
1
+ /**
2
+ * session/rpc.ts — Supervisor RPC + W8 child_process + legacy VFS impls.
3
+ *
4
+ * Why free-functions instead of class methods:
5
+ * the DO RPC fabric calls these by name, so the supervisor's class
6
+ * MUST keep the method names as delegators (otherwise the fabric
7
+ * looks them up and finds nothing). Putting the bodies in free
8
+ * functions and having the class methods one-line-delegate keeps
9
+ * the class file small AND lets these be unit-tested without a DO
10
+ * harness (the `RpcHost` parameter is a narrow contract).
11
+ *
12
+ * Bodies for every `_rpc*`, `vfs*`, `_emit*`, and `_reportExternalExit`
13
+ * method live here. The class retains the method NAMES as one-line
14
+ * delegators in src/session/nimbus-session.ts.
15
+ * 1-line delegators (per plan §IX.4 R1: DO RPC fabric uses name dispatch
16
+ * via the stub).
17
+ *
18
+ * Per DEFECT-D1: ctx is taken via `(self as any).ctx` cast where needed
19
+ * (rpcInnerDoFetch uses self.ctx.id and self.ctx.facets; rpcPutRegistryEntries
20
+ * uses self.ctx.storage.sql). The InitHost-style escape applies because
21
+ * these ~3 sites would each need ctx threaded through; cast at boundary
22
+ * is acceptable per plan §IX recommendation 1.
23
+ */
24
+ import { enc } from '../_shared/bytes.js';
25
+ import { getInnerDoClass } from '../facets/inner-do-registry.js';
26
+ import { NpmCache } from '../npm/cache.js';
27
+ import { EsbuildService } from '../runtime/esbuild-service.js';
28
+ import { notifyTerminalEvent } from '../runtime/process-logs-api.js';
29
+ import { NimbusLoaderPool } from '../loaders/loader-pool.js';
30
+ import { recordFailure, getLastRpcFrame, getLastFacetId, } from '../observability/oom-discriminator.js';
31
+ import { classifyError } from '../observability/oom-classify.js';
32
+ export async function _rpcReadFile(self, path) {
33
+ self.ensureSqliteFs();
34
+ try {
35
+ return self.sqliteFs.readFileString(path.replace(/^\/+/, ''));
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ /**
42
+ * Read a file as raw bytes (Uint8Array). Used by git network facet for
43
+ * binary .git/objects/** and packfile reads, where TextDecoder/TextEncoder
44
+ * round-tripping through readFile (string) would corrupt bytes.
45
+ */
46
+ export async function _rpcReadFileBytes(self, path) {
47
+ self.ensureSqliteFs();
48
+ try {
49
+ return self.sqliteFs.readFile(path.replace(/^\/+/, ''));
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Phase-3 inner-DO fetch dispatcher. Called by NimbusDOStub.fetch()
57
+ * from the inner Worker via the env.NIMBUS_SESSION loopback. We
58
+ * resolve the inner DO class from the module-level registry (keyed
59
+ * by <thisDoId>:<bindingName>), use ctx.facets.get with the inner's
60
+ * id string as the facet id, and forward the serialized Request.
61
+ *
62
+ * All steps run in THIS RPC method's context, so no cross-request
63
+ * I/O boundaries are crossed — the ctx.facets stub and its fetch()
64
+ * are both created here.
65
+ */
66
+ export async function _rpcInnerDoFetch(self, req) {
67
+ const cls = getInnerDoClass(self.ctx.id.toString(), req.bindingName);
68
+ if (!cls) {
69
+ const body = enc.encode(`Nimbus: inner DO binding '${req.bindingName}' has no registered class (supervisor=${self.ctx.id.toString()})`);
70
+ return {
71
+ status: 502,
72
+ statusText: 'Bad Gateway',
73
+ headers: [['Content-Type', 'text/plain']],
74
+ body: body.buffer,
75
+ };
76
+ }
77
+ const facetName = 'innerDO-' + req.bindingName + '-' + req.id;
78
+ const facet = self.ctx.facets.get(facetName, async () => ({
79
+ class: cls,
80
+ id: req.id, // FacetStartupOptions.id — inner DO sees this as its ctx.id
81
+ }));
82
+ try {
83
+ // Reconstruct the Request in the current context.
84
+ const headers = new Headers();
85
+ for (const [k, v] of req.headers)
86
+ headers.append(k, v);
87
+ const r = new Request(req.url, {
88
+ method: req.method,
89
+ headers,
90
+ body: req.body,
91
+ });
92
+ const res = await facet.fetch(r);
93
+ const resHeaderList = [];
94
+ res.headers.forEach((v, k) => { resHeaderList.push([k, v]); });
95
+ const resBody = await res.arrayBuffer();
96
+ return {
97
+ status: res.status,
98
+ statusText: res.statusText,
99
+ headers: resHeaderList,
100
+ body: resBody,
101
+ };
102
+ }
103
+ catch (e) {
104
+ const body = enc.encode(`Nimbus inner DO error: ${e?.message || String(e)}`);
105
+ return {
106
+ status: 500,
107
+ statusText: 'Internal Server Error',
108
+ headers: [['Content-Type', 'text/plain']],
109
+ body: body.buffer,
110
+ };
111
+ }
112
+ }
113
+ export async function _rpcWriteFile(self, path, content) {
114
+ self.ensureSqliteFs();
115
+ const p = path.replace(/^\/+/, '');
116
+ const parts = p.split('/');
117
+ for (let i = 1; i < parts.length; i++) {
118
+ const dir = parts.slice(0, i).join('/');
119
+ if (dir && !self.sqliteFs.exists(dir))
120
+ self.sqliteFs.mkdir(dir, { recursive: true });
121
+ }
122
+ // binary-fs wave: SqliteVFS.writeFile already accepts string | Uint8Array
123
+ // (sqlite-vfs.ts:937), so we forward the content shape unchanged. RPC
124
+ // structured-clone preserves Uint8Array across the boundary; structured-
125
+ // clone doesn't accept Buffer subclass instances, so fs.writeFileSync on
126
+ // a Buffer flows through node-shims.ts:writeFileSync which stores it as
127
+ // a plain Uint8Array on the cell — the shape that arrives here.
128
+ self.sqliteFs.writeFile(p, content);
129
+ }
130
+ export async function _rpcStat(self, path) {
131
+ self.ensureSqliteFs();
132
+ try {
133
+ return self.sqliteFs.stat(path.replace(/^\/+/, ''));
134
+ }
135
+ catch {
136
+ return null;
137
+ }
138
+ }
139
+ export async function _rpcReaddir(self, path) {
140
+ self.ensureSqliteFs();
141
+ try {
142
+ return self.sqliteFs.readdir(path.replace(/^\/+/, ''));
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ }
148
+ export async function _rpcExists(self, path) {
149
+ self.ensureSqliteFs();
150
+ return self.sqliteFs.exists(path.replace(/^\/+/, ''));
151
+ }
152
+ export async function _rpcMkdir(self, path) {
153
+ self.ensureSqliteFs();
154
+ self.sqliteFs.mkdir(path.replace(/^\/+/, ''), { recursive: true });
155
+ }
156
+ /**
157
+ * Called by CirrusHmrRPC.hmrSend. Runs in the DO's own context so
158
+ * we can legally write to hibernatable WS sockets owned by this
159
+ * DO. The HmrBridge holds the client→WS map; we delegate to it.
160
+ */
161
+ export async function _rpcHmrRelay(self, clientId, msg) {
162
+ if (!self.cirrusReal)
163
+ return;
164
+ self.cirrusReal.hmr.relayToBrowser(clientId, msg);
165
+ }
166
+ export async function _rpcUnlink(self, path) {
167
+ self.ensureSqliteFs();
168
+ try {
169
+ self.sqliteFs.unlink(path.replace(/^\/+/, ''));
170
+ }
171
+ catch { }
172
+ }
173
+ /**
174
+ * Bulk-write files and directories via one transactionSync().
175
+ * Called from facets that accumulate writes locally (git clone/fetch/pull,
176
+ * potentially others) to avoid thousands of individual writeFile RPCs.
177
+ *
178
+ * payload: {
179
+ * inodes: BatchInodeEntry[],
180
+ * chunks: { path, chunkId, data: Uint8Array | ArrayBuffer }[],
181
+ * deletePaths?: string[]
182
+ * }
183
+ */
184
+ export async function _rpcWriteBatch(self, payload) {
185
+ self.ensureSqliteFs();
186
+ const inodes = Array.isArray(payload?.inodes) ? payload.inodes : [];
187
+ const rawChunks = Array.isArray(payload?.chunks) ? payload.chunks : [];
188
+ const deletePaths = Array.isArray(payload?.deletePaths) ? payload.deletePaths : undefined;
189
+ // Normalize chunk data — RPC may deliver Uint8Array, ArrayBuffer, or { type: 'Buffer', data: [...] }
190
+ const chunks = rawChunks.map((c) => {
191
+ let data;
192
+ if (c.data instanceof Uint8Array) {
193
+ data = c.data;
194
+ }
195
+ else if (c.data instanceof ArrayBuffer) {
196
+ data = new Uint8Array(c.data);
197
+ }
198
+ else if (ArrayBuffer.isView(c.data)) {
199
+ data = new Uint8Array(c.data.buffer, c.data.byteOffset, c.data.byteLength);
200
+ }
201
+ else if (Array.isArray(c.data)) {
202
+ data = new Uint8Array(c.data);
203
+ }
204
+ else if (c.data && typeof c.data === 'object' && Array.isArray(c.data.data)) {
205
+ // Buffer JSON serialization fallback
206
+ data = new Uint8Array(c.data.data);
207
+ }
208
+ else {
209
+ data = new Uint8Array(0);
210
+ }
211
+ return { path: String(c.path), chunkId: Number(c.chunkId), data };
212
+ });
213
+ return self.sqliteFs.writeBatch({
214
+ inodes,
215
+ chunks,
216
+ deletePaths,
217
+ });
218
+ }
219
+ /**
220
+ * W7 — Streaming bulk-write entry point. Receives a
221
+ * ReadableStream<Uint8Array> in the W7 wire format (see
222
+ * src/_shared/w7-frame.ts), decodes inode metadata + chunks lazily,
223
+ * and feeds them into SqliteVFS.writeStream().
224
+ *
225
+ * Bypasses the 32 MiB structured-clone cap that constrained the
226
+ * legacy writeBatch path — workerd flow-controls the byte stream
227
+ * end-to-end.
228
+ *
229
+ * Atomicity guarantee mirrors writeBatch: either ALL inodes +
230
+ * chunks land in SQLite or NONE do. SqliteVFS.writeStream defers
231
+ * the actual transactionSync until the chunk iterator is fully
232
+ * drained (v1 spool-then-commit), so a stream error mid-transit
233
+ * aborts before any SQL state mutates.
234
+ */
235
+ export async function _rpcWriteBatchStream(self, stream) {
236
+ self.ensureSqliteFs();
237
+ // [P0a — COORDINATOR-OVERLOAD]
238
+ //
239
+ // Wave-1 (semaphore here): rejected. Parking peer-side awaits in a
240
+ // user-space queue extended each peer's _rpcFanoutExecute round-trip
241
+ // time, which made workerd cancel the peer→coordinator PARENT RPC
242
+ // with the same overload error (verified prod 7c3f1b25:
243
+ // "[batch-fanout] aborted: ExecutionError: Durable Object is
244
+ // overloaded"). The semaphore moved the queue-age problem one layer
245
+ // up — same symptom, worse blast radius (whole-batch abort instead
246
+ // of per-package fail).
247
+ //
248
+ // Wave-2 (shared flush + adaptive shard cap, no semaphore): the
249
+ // producer-side fix. The peer-side install-batch-facet now shares
250
+ // ONE inode/chunk accumulator across all packages in a peer's
251
+ // shard (src/npm/install-batch-facet.ts), so 39 packages → ~3-5
252
+ // RPCs to coordinator instead of 39+. Combined with shard cap of 8
253
+ // (src/npm/installer.ts), 620 deps → 8 peers × ~3 flushes = ~24
254
+ // total writeBatchStream RPCs at the coordinator (vs 620+ pre-fix).
255
+ // Workerd's input-gate queue depth on the coordinator stays well
256
+ // under the queue-age threshold without any user-space semaphore.
257
+ const { decodeWriteBatchStream } = await import('../_shared/w7-frame.js');
258
+ const decoded = await decodeWriteBatchStream(stream);
259
+ return self.sqliteFs.writeStream({
260
+ inodes: decoded.inodes,
261
+ chunkIter: decoded.chunkIter,
262
+ deletePaths: decoded.deletePaths,
263
+ });
264
+ }
265
+ /**
266
+ * Bulk-write npm registry cache entries in ONE RPC. Used by the
267
+ * resolver-facet to flush a wave of resolved packages back to the
268
+ * supervisor without per-entry round-trips.
269
+ *
270
+ * Payload is the array of RegistryCacheEntry shapes from src/npm-cache.ts.
271
+ * Returns { written, failed } so the facet can surface partial-write
272
+ * warnings to the install log.
273
+ */
274
+ export async function _rpcPutRegistryEntries(self, entries) {
275
+ self.ensureSqliteFs();
276
+ const npmCache = new NpmCache(self.ctx.storage.sql);
277
+ if (!Array.isArray(entries))
278
+ return { written: 0, failed: 0 };
279
+ return npmCache.putRegistryEntries(entries);
280
+ }
281
+ export async function _rpcStdout(self, pid, data) {
282
+ // Always buffer raw data (keeps ANSI for replay). Terminal paint only
283
+ // if someone is listening — detached sessions shouldn't silently lose
284
+ // output. Skip pid=0 (the supervisor-rpc fallback when no props.pid
285
+ // was threaded) to avoid polluting a sentinel slot with output from
286
+ // un-traceable facets.
287
+ try {
288
+ if (pid > 0)
289
+ self.processLogs.append(pid, 'stdout', data);
290
+ if (self.terminal)
291
+ self.terminal.write(data);
292
+ }
293
+ catch (e) {
294
+ // Fix 5: surface RPC envelope errors when NIMBUS_DEBUG=1. Silent
295
+ // drops here are exactly what hides bugs; default-off so we don't
296
+ // blow up terminals with normal-operation noise, but diagnosable on
297
+ // demand.
298
+ if (self.nimbusDebug && self.terminal) {
299
+ try {
300
+ self.terminal.write(`\x1b[33m[rpc-error] _rpcStdout(pid=${pid}) threw: ${e?.message || e}\x1b[0m\r\n`);
301
+ }
302
+ catch { }
303
+ }
304
+ }
305
+ }
306
+ export async function _rpcStderr(self, pid, data) {
307
+ try {
308
+ if (pid > 0)
309
+ self.processLogs.append(pid, 'stderr', data);
310
+ // Terminal gets red wrapping; the ring buffer keeps it raw so the
311
+ // stream tag can drive color decisions at replay time.
312
+ if (self.terminal)
313
+ self.terminal.write(`\x1b[31m${data}\x1b[0m`);
314
+ }
315
+ catch (e) {
316
+ if (self.nimbusDebug && self.terminal) {
317
+ try {
318
+ self.terminal.write(`\x1b[33m[rpc-error] _rpcStderr(pid=${pid}) threw: ${e?.message || e}\x1b[0m\r\n`);
319
+ }
320
+ catch { }
321
+ }
322
+ }
323
+ }
324
+ /**
325
+ * Called by facets from their `finally` block after I/O has drained.
326
+ * Marks the log store so `logs` / `ps` can show the exit code, and
327
+ * fires `_emitExitDump` if the process exited non-zero with buffered
328
+ * output.
329
+ *
330
+ * Idempotent — double-call is a no-op (ProcessLogStore.markExit guards).
331
+ */
332
+ export async function _rpcReportExit(self, pid, code, tail) {
333
+ if (pid <= 0)
334
+ return; // Ignore the pid-0 sentinel.
335
+ if (tail)
336
+ self.processLogs.append(pid, 'stderr', tail);
337
+ // Guard against double-reporting: if we've already recorded exit
338
+ // (e.g. from an external kill path) don't dump twice.
339
+ if (self.processLogs.getExit(pid))
340
+ return;
341
+ self.processLogs.markExit(pid, code);
342
+ // Structured exit notification for the tabs UI. Idempotent on the
343
+ // client — subscribeExit fires once, and the shell-exec finalizer
344
+ // also emits, so we dedupe on pid there. Include the command (when
345
+ // available via ProcessTable) so the UI can surface a tab for pids
346
+ // whose spawn event was suppressed (e.g. `node -e` short evals).
347
+ const cmdFromTable = self.processTable.get(pid)?.command;
348
+ notifyTerminalEvent(self.terminal, { type: 'exit', pid, code, command: cmdFromTable });
349
+ // SHELL-FOLLOWUPS-5 (2026-05-11): only dump on non-zero exit.
350
+ //
351
+ // Pre-fix Fix-4 policy was "dump whenever the ring buffer has
352
+ // bytes, regardless of code" (intent: catch the
353
+ // clean-but-silent failure where stderr traceback was buffered
354
+ // but user wasn't watching). Real-world cost: every successful
355
+ // `node -e`, `python -c`, etc. printed stdout once live, then
356
+ // again as a post-exit dump — double-print on the happy path.
357
+ //
358
+ // New policy:
359
+ // - Non-zero exit AND non-empty buffer → dump (failure context)
360
+ // - Zero exit → no dump (live stream already showed it)
361
+ //
362
+ // Reconnect-replay path is preserved by the `logs <pid>` shell
363
+ // command + `/api/processes/<pid>/logs` endpoint, neither of
364
+ // which depends on the inline dump.
365
+ //
366
+ // NOTE: _emitShellExecDone (below) carries an identical gate;
367
+ // both paths must agree because either may fire first depending
368
+ // on facet vs. shell-finalizer ordering.
369
+ if (code !== 0 && self.processLogs.size(pid) > 0) {
370
+ self._emitExitDump(pid, code);
371
+ }
372
+ // Fix 5: verbose exit trace gated on NIMBUS_DEBUG=1. Facets already
373
+ // get a spawn banner via FacetManager.onSpawn; this closes the loop.
374
+ if (self.nimbusDebug && self.terminal) {
375
+ const entry = self.processTable.get(pid);
376
+ const cmd = entry?.command || `pid ${pid}`;
377
+ const colorExit = code === 0 ? '\x1b[2m' : '\x1b[2;31m';
378
+ self.terminal.write(`${colorExit}[facet exited: pid=${pid} code=${code} cmd="${cmd}"]\x1b[0m\r\n`);
379
+ }
380
+ }
381
+ /**
382
+ * Emit a formatted exit-dump banner + last 30 lines of output to the
383
+ * terminal. Called from both the facet-reported exit path and the
384
+ * external-kill path (timeout / abort).
385
+ *
386
+ * Race notes:
387
+ * - Terminal.write is buffered with a 5ms flush; concurrent writes
388
+ * from facet stdout still in flight interleave cleanly at flush
389
+ * time.
390
+ * - If no terminal is attached, the dump is simply skipped — the
391
+ * log buffer still has everything, so `logs <pid>` recovers it.
392
+ */
393
+ export function _emitExitDump(self, pid, code) {
394
+ if (!self.terminal)
395
+ return;
396
+ const entry = self.processTable.get(pid);
397
+ const cmd = entry?.command || `pid ${pid}`;
398
+ const chunks = self.processLogs.tail(pid, { lines: 30 });
399
+ const sep = '─'.repeat(60);
400
+ const color = code === 0 ? '\x1b[2;33m' : '\x1b[31m'; // yellow-dim for clean-silent
401
+ self.terminal.write(`\r\n${color}${sep}\r\n` +
402
+ `Process ${pid} (${cmd}) exited with code ${code}\r\n` +
403
+ `${sep}\x1b[0m\r\n`);
404
+ for (const c of chunks) {
405
+ const painted = c.stream === 'stderr' ? `\x1b[31m${c.data}\x1b[0m` : c.data;
406
+ self.terminal.write(painted);
407
+ }
408
+ self.terminal.write(`${color}${sep}\x1b[0m\r\n`);
409
+ }
410
+ /**
411
+ * Fix 3 + Fix 4 + Fix 5: finalizer for shellExecuteTracked.
412
+ *
413
+ * Runs after a tracked shell.execute finishes (any path). Chooses when
414
+ * to emit the exit-dump banner and when to log the debug trace.
415
+ *
416
+ * Dump policy (Fix 4):
417
+ * - Non-zero exit AND any buffered output → always dump.
418
+ * - Zero exit AND buffered output has >0 bytes → dump anyway. Rationale:
419
+ * an npm run that returned "success" while the ring buffer still has
420
+ * a traceback is the exact "clean-but-silent failure" we're hunting.
421
+ * The replay is unique information the user didn't see live (e.g.
422
+ * because the terminal was reconnected after the fact).
423
+ * - Zero exit AND empty buffer → nothing to say. Skip.
424
+ *
425
+ * Trace policy (Fix 5):
426
+ * - NIMBUS_DEBUG=1: always print `[exited pid=N code=C duration=Xms]`.
427
+ * - Default: print only for non-zero OR long-running scripts (the
428
+ * cmd-start banner makes them expect an exit marker).
429
+ *
430
+ * Called with the already-marked pid (processTable.exit + processLogs.markExit
431
+ * ran in shellExecuteTracked's finally).
432
+ */
433
+ export function _emitShellExecDone(self, pid, cmd, code, durationMs) {
434
+ const bufSize = self.processLogs.size(pid);
435
+ // SHELL-FOLLOWUPS-5 (2026-05-11): only dump on non-zero exit.
436
+ //
437
+ // Pre-fix policy was "dump regardless of code when buffer non-empty"
438
+ // (Fix 4 from W3.5 era, intent: catch clean-but-silent failure
439
+ // where user couldn't see live output e.g. across reconnect).
440
+ //
441
+ // Real-world cost: for every successful `node -e`, `python -c`,
442
+ // `npx X --version`, etc., user saw output once live + once
443
+ // again in the post-exit dump. Annoying double-print for the
444
+ // common-case interactive session.
445
+ //
446
+ // New policy:
447
+ // - Non-zero exit AND non-empty buffer → dump (failure context)
448
+ // - Zero exit → no dump (live stream already showed it)
449
+ //
450
+ // Reconnect-replay path is preserved by the `logs <pid>` shell
451
+ // command + `/api/processes/<pid>/logs` endpoint, neither of
452
+ // which depends on the inline dump.
453
+ const shouldDump = bufSize > 0 && code !== 0;
454
+ if (shouldDump) {
455
+ self._emitExitDump(pid, code);
456
+ }
457
+ if (self.terminal) {
458
+ const traceAlways = self.nimbusDebug;
459
+ const isLongRunning = /^(vite|wrangler|next|nuxt|astro|remix|dev|serve|start|watch)\b/.test(cmd);
460
+ if (traceAlways || code !== 0 || isLongRunning) {
461
+ const colorExit = code === 0 ? '\x1b[2m' : '\x1b[2;31m';
462
+ self.terminal.write(`${colorExit}[shell exited: pid=${pid} code=${code} duration=${durationMs}ms]\x1b[0m\r\n`);
463
+ }
464
+ }
465
+ }
466
+ /**
467
+ * External-exit path: invoked by FacetManager when a process is killed
468
+ * outside the facet's own try/finally (timeout, explicit abort, or the
469
+ * `kill` shell command). Appends a synthetic stderr line so the dump
470
+ * has useful context, then runs the same dump machinery.
471
+ */
472
+ export function _reportExternalExit(self, pid, code, reason) {
473
+ if (self.processLogs.getExit(pid))
474
+ return;
475
+ if (reason) {
476
+ self.processLogs.append(pid, 'stderr', `[process killed: ${reason}]\n`);
477
+ }
478
+ self.processLogs.markExit(pid, code, reason);
479
+ const cmdFromTable = self.processTable.get(pid)?.command;
480
+ notifyTerminalEvent(self.terminal, { type: 'exit', pid, code, reason, command: cmdFromTable });
481
+ if (self.terminal && self.processLogs.size(pid) > 0) {
482
+ self._emitExitDump(pid, code);
483
+ }
484
+ // W5 Lever 5: ring entry for every external exit with a non-zero
485
+ // code. The FacetManager already records its own exits inline via
486
+ // _w5RecordTermination — this catches the residual paths
487
+ // (timeouts dispatched via the timeout-handler in FacetManager
488
+ // call back through hooks.onExternalExit, which reaches here).
489
+ // The ring is bounded; double-recording is harmless.
490
+ if (code !== 0) {
491
+ try {
492
+ let cause = classifyError(reason);
493
+ if (code === 124 && cause === 'unknown')
494
+ cause = 'rpc_timeout';
495
+ recordFailure({
496
+ at: Date.now(),
497
+ phase: 'facet',
498
+ cause,
499
+ rssEstimateBytes: self._diagPeakRss,
500
+ heapUsedBytes: self._diagPeakHeapUsed,
501
+ lruBytes: 0, inFlightBytes: 0,
502
+ lastRpcFrame: getLastRpcFrame(),
503
+ lastFacetId: getLastFacetId(),
504
+ exitCode: code,
505
+ pid,
506
+ message: reason,
507
+ });
508
+ }
509
+ catch { /* fail-soft */ }
510
+ }
511
+ }
512
+ /**
513
+ * W1: bootstrap the log-janitor alarm cycle.
514
+ *
515
+ * Schedules an alarm for `Date.now() + 60_000` with reason
516
+ * `'log-janitor'`. When it fires, `dispatchAlarm` (in
517
+ * ./hibernation.ts) runs `processLogs.dropOlderThan(orphanCheck)` and
518
+ * re-schedules the next 60s alarm — fully replacing the setTimeout
519
+ * chain we used to run.
520
+ *
521
+ * Why alarm-based instead of setTimeout: per Cloudflare DO docs
522
+ * (https://developers.cloudflare.com/durable-objects/concepts/durable-object-lifecycle/),
523
+ * a recurring `setTimeout`/`setInterval` PREVENTS the DO from
524
+ * hibernating. That left every Nimbus session billed for duration
525
+ * continuously while in memory. Alarms persist across hibernation;
526
+ * the DO sleeps between fires, dropping per-session billable
527
+ * duration by ~99% during idle windows.
528
+ *
529
+ * Idempotent: guarded by `self.processLogsJanitorWired`. Safe to
530
+ * call repeatedly. Fail-soft: scheduleAlarm warn+returns on
531
+ * runtimes without setAlarm (older wrangler-dev).
532
+ */
533
+ export function _ensureLogJanitor(self, ctx) {
534
+ if (self.processLogsJanitorWired)
535
+ return;
536
+ self.processLogsJanitorWired = true;
537
+ // Fire-and-forget: scheduleAlarm is async (storage IO) but the
538
+ // alarm bootstrap is non-blocking from the ctor's POV. Any throw
539
+ // is swallowed inside scheduleAlarm.
540
+ void (async () => {
541
+ try {
542
+ const { scheduleAlarm } = await import('./hibernation.js');
543
+ await scheduleAlarm(ctx, 'log-janitor', Date.now() + 60_000);
544
+ }
545
+ catch (e) {
546
+ console.warn('[nimbus/W1] _ensureLogJanitor bootstrap threw:', e?.message);
547
+ }
548
+ })();
549
+ }
550
+ /**
551
+ * W1: orphan-pid predicate exposed for the alarm dispatcher. A pid is
552
+ * "orphaned" if the process table has no record of it — either reap()
553
+ * already removed it, or it never fully registered. Long-running
554
+ * facets that hang and get GC'd fall into this category.
555
+ */
556
+ export function _logJanitorOrphanCheck(self) {
557
+ return (pid) => !self.processTable.get(pid);
558
+ }
559
+ export async function _rpcPrefetch(self, cwd, entryCode) {
560
+ // W2.6a: de-quarantined. require-resolver.ts is now the primary
561
+ // content-bundle source for FacetManager.exec via buildPrefetchBundle.
562
+ // This RPC entrypoint is retained for facet-side callers that may
563
+ // want to refresh the bundle mid-execution; today only the
564
+ // SupervisorRPC.prefetch surface exposes it externally.
565
+ self.ensureSqliteFs();
566
+ const { prefetchForRequire } = await import('../runtime/require-resolver.js');
567
+ return prefetchForRequire(self.sqliteFs, entryCode, cwd).bundle;
568
+ }
569
+ export async function _rpcRegisterPort(self, pid, port) {
570
+ // Port registration stores the facet association
571
+ // The actual facet stub is stored by FacetManager separately
572
+ self.portRegistry.register(port, pid, null);
573
+ }
574
+ export async function _rpcUnregisterPort(self, port) {
575
+ self.portRegistry.unregister(port);
576
+ }
577
+ export async function _rpcTransform(self, code, loader) {
578
+ if (!self.esbuildService) {
579
+ self.ensureSqliteFs();
580
+ self.esbuildService = new EsbuildService(self.sqliteFs);
581
+ }
582
+ try {
583
+ const result = await self.esbuildService.transform(code, {
584
+ loader: loader || 'ts',
585
+ format: 'esm',
586
+ target: 'esnext',
587
+ sourcemap: 'inline',
588
+ });
589
+ return { code: result.code, map: result.map };
590
+ }
591
+ catch (e) {
592
+ return null;
593
+ }
594
+ }
595
+ // ── child_process RPC entrypoints [W8 Phase 1] ────────────────────────
596
+ //
597
+ // Delegate to the lazily-constructed FacetProcessManager. Defensive
598
+ // ensureFacetProcessManager() handles cold-start cases where a child
599
+ // facet calls cp* before the supervisor has initialized the broker
600
+ // (e.g., immediately after DO hibernation wake-up).
601
+ export async function _rpcCpSpawn(self, req) {
602
+ const fpm = self._ensureFacetProcessManager();
603
+ return fpm.spawn(req);
604
+ }
605
+ export async function _rpcCpStdinWrite(self, childPid, data) {
606
+ const fpm = self._ensureFacetProcessManager();
607
+ return fpm.stdinWrite(childPid, data);
608
+ }
609
+ export async function _rpcCpStdinEnd(self, childPid) {
610
+ const fpm = self._ensureFacetProcessManager();
611
+ fpm.stdinEnd(childPid);
612
+ }
613
+ export async function _rpcCpReadOutput(self, childPid, fd, sinceSeq, waitMs) {
614
+ const fpm = self._ensureFacetProcessManager();
615
+ return fpm.readOutput(childPid, fd, sinceSeq, waitMs);
616
+ }
617
+ export async function _rpcCpDrainOutput(self, childPid) {
618
+ const fpm = self._ensureFacetProcessManager();
619
+ return fpm.drainOutput(childPid);
620
+ }
621
+ export async function _rpcCpKill(self, childPid, signal) {
622
+ const fpm = self._ensureFacetProcessManager();
623
+ return fpm.kill(childPid, signal);
624
+ }
625
+ export async function _rpcCpWait(self, childPid, waitMs) {
626
+ const fpm = self._ensureFacetProcessManager();
627
+ return fpm.wait(childPid, waitMs);
628
+ }
629
+ /**
630
+ * arch-gaps gap #1: dispatch a single cp.spawn request inline using the
631
+ * existing pure-builtin / facet-direct logic, returning final stdout/
632
+ * stderr/exitCode rather than streaming via hooks. Called by
633
+ * spawn-facet.ts:runSpawnInIsolate from inside a fresh Worker Loader
634
+ * isolate (the per-spawn fresh-isolate envelope).
635
+ *
636
+ * The fpm exposes a `dispatchInline(req, kind)` that adapts the
637
+ * existing _dispatch path (originally hook-based) into a string-result
638
+ * shape. That adapter is responsible for ensuring stdout/stderr are
639
+ * accumulated inline rather than streamed.
640
+ */
641
+ export async function _rpcCpDispatchInline(self, req, kind) {
642
+ const fpm = self._ensureFacetProcessManager();
643
+ return fpm.dispatchInline(req, kind);
644
+ }
645
+ // ── Legacy VFS RPC Entrypoints (direct method calls) ──────────────────
646
+ // Kept for backward compatibility with direct DO stub callers.
647
+ /** RPC: Read a file from the VFS. Returns ArrayBuffer or null. */
648
+ export function vfsReadFile(self, path) {
649
+ self.ensureSqliteFs();
650
+ try {
651
+ const stripped = path.replace(/^\/+/, '');
652
+ const data = self.sqliteFs.readFile(stripped);
653
+ return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
654
+ }
655
+ catch {
656
+ return null;
657
+ }
658
+ }
659
+ /** RPC: Read a file as string. Returns string or null. */
660
+ export function vfsReadFileString(self, path) {
661
+ self.ensureSqliteFs();
662
+ try {
663
+ const stripped = path.replace(/^\/+/, '');
664
+ return self.sqliteFs.readFileString(stripped);
665
+ }
666
+ catch {
667
+ return null;
668
+ }
669
+ }
670
+ /** RPC: Stat a path. Returns { type, size, mtime, mode } or null. */
671
+ export function vfsStat(self, path) {
672
+ self.ensureSqliteFs();
673
+ try {
674
+ const stripped = path.replace(/^\/+/, '');
675
+ return self.sqliteFs.stat(stripped);
676
+ }
677
+ catch {
678
+ return null;
679
+ }
680
+ }
681
+ /** RPC: Check if path exists. */
682
+ export function vfsExists(self, path) {
683
+ self.ensureSqliteFs();
684
+ const stripped = path.replace(/^\/+/, '');
685
+ return self.sqliteFs.exists(stripped);
686
+ }
687
+ /** RPC: List directory contents. Returns array of { name, type }. */
688
+ export function vfsReaddir(self, path) {
689
+ self.ensureSqliteFs();
690
+ try {
691
+ const stripped = path.replace(/^\/+/, '');
692
+ return self.sqliteFs.readdir(stripped);
693
+ }
694
+ catch {
695
+ return [];
696
+ }
697
+ }
698
+ /** RPC: Write a file to the VFS. */
699
+ export function vfsWriteFile(self, path, data) {
700
+ self.ensureSqliteFs();
701
+ const stripped = path.replace(/^\/+/, '');
702
+ self.sqliteFs.writeFile(stripped, new Uint8Array(data));
703
+ }
704
+ /**
705
+ * RPC: peer-DO execute leg of NimbusFanoutPool's POC B topology.
706
+ *
707
+ * Called by a coordinator NimbusSession DO via
708
+ * `env.NIMBUS_SESSION.idFromName(siblingName).get()._rpcFanoutExecute(...)`.
709
+ * THIS DO instance acts as a peer worker: it runs ONE NimbusLoaderPool
710
+ * over its assigned shard and returns the per-task results.
711
+ *
712
+ * Cap-sidestep mechanic
713
+ * ─────────────────────
714
+ * The supervisor's `submitMany` makes N RPC calls to N peer DOs.
715
+ * Each RPC is a stub.fetch / RPC method invocation, NOT an
716
+ * `env.LOADER.get()` from the supervisor's own method context — so
717
+ * those N calls don't count against the V8 4-loaders-per-method cap.
718
+ * Inside this RPC handler, we run a SINGLE LoaderPool with concurrency
719
+ * matching the shard size — and since the shard arrived via the peer
720
+ * router (capped at MAX_PEER_FANOUT = 32 peers, so each shard is
721
+ * ⌈totalTasks / 32⌉ wide), the in-DO pool stays well under 4.
722
+ *
723
+ * Failure model
724
+ * ─────────────
725
+ * Throws bubble back to the coordinator's RPC promise (rejects on
726
+ * the supervisor side). The coordinator's `submitMany` Promise.all
727
+ * surfaces the first reject; the install path treats it as a hard
728
+ * failure (matching today's single-facet `pool.submit` posture).
729
+ *
730
+ * Bytes-isolation
731
+ * ───────────────
732
+ * The fnSource string is forwarded verbatim into a fresh
733
+ * NimbusLoaderPool, which serializes it into the loader's worker
734
+ * code. No supervisor-side eval. Same trust posture as every other
735
+ * NimbusLoaderPool dispatch.
736
+ */
737
+ export async function _rpcFanoutExecute(self, fnSource, args, poolOpts = {}) {
738
+ if (!Array.isArray(args)) {
739
+ throw new TypeError('_rpcFanoutExecute: args must be an array');
740
+ }
741
+ if (args.length === 0)
742
+ return { results: [] };
743
+ // Concurrency = shard size, capped at 4 (the V8 in-DO ceiling).
744
+ // Shard size on the coordinator side is at most ⌈totalTasks / N⌉
745
+ // where N <= MAX_PEER_FANOUT (32) — for typical 50-pkg installs
746
+ // with N=8 peers, that's 7 tasks per peer, capped to 4 here so
747
+ // each peer DO stays safely below the cap.
748
+ const concurrency = Math.min(args.length, 4);
749
+ const pool = new NimbusLoaderPool(self.env, self.ctx, {
750
+ concurrency,
751
+ timeoutMs: poolOpts.timeoutMs,
752
+ tag: poolOpts.tag ?? 'fanout-peer',
753
+ preamble: poolOpts.preamble,
754
+ wasmModules: poolOpts.wasmModules,
755
+ extraBindings: poolOpts.extraBindings,
756
+ omitSupervisor: poolOpts.omitSupervisor,
757
+ // INSTALL-HONESTY: route SUPERVISOR.* back to the coordinator
758
+ // (the user's session DO), not the peer DO. When undefined
759
+ // (back-compat with non-fanout callers), NimbusLoaderPool falls
760
+ // back to ctx.id.toString() — the legacy behavior, correct for
761
+ // single-DO callers.
762
+ supervisorDoIdOverride: poolOpts.coordinatorDoId,
763
+ });
764
+ try {
765
+ // mapSource accepts the pre-serialized fnSource forwarded by the
766
+ // coordinator (the function was already validated +
767
+ // serialized via serializeFunction on the coordinator side).
768
+ const results = await pool.mapSource(fnSource, args);
769
+ return { results };
770
+ }
771
+ finally {
772
+ try {
773
+ pool.dispose();
774
+ }
775
+ catch { /* best-effort */ }
776
+ }
777
+ }
778
+ // ── Cache-observability stats forward (cache-observability wave) ──────
779
+ //
780
+ // SupervisorRPC handlers run in a SEPARATE isolate from the DO they
781
+ // service (loopback service-binding semantics). When they bump
782
+ // per-tier cache counters via src/_shared/cache-stats.ts, they bump
783
+ // the LOCAL singleton in the SupervisorRPC isolate. /api/_diag/cache
784
+ // reads the DO's singleton — different grid, no visibility.
785
+ //
786
+ // Fix: SupervisorRPC handlers forward the bump via this DO-side RPC.
787
+ // Pattern mirrors recordR2RaceCounters in installer.ts:1168 where the
788
+ // facet returns counters and the supervisor folds them into the DO
789
+ // singleton. Here the loopback boundary is the equivalent of the
790
+ // facet-supervisor boundary.
791
+ //
792
+ // One forward per (tier, kind, isHit, bytes) tuple. Batch via the
793
+ // `events` array so a single supervisor RPC handler can flush multiple
794
+ // bumps in one round-trip.
795
+ import { recordHit as _rpcRecordHit, recordMiss as _rpcRecordMiss } from '../_shared/cache-stats.js';
796
+ export async function _rpcRecordCacheStats(_self, events) {
797
+ // Defensive iteration — caller is in-house (supervisor-rpc.ts) but
798
+ // a malformed event must NOT throw and break the install. Iterate
799
+ // with type-narrowing; an unknown `kind` is silently skipped.
800
+ for (const e of events) {
801
+ if (e.kind === 'hit') {
802
+ _rpcRecordHit(e.tier, e.cacheKind, e.bytes);
803
+ }
804
+ else if (e.kind === 'miss') {
805
+ _rpcRecordMiss(e.tier, e.cacheKind);
806
+ }
807
+ }
808
+ }