@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,210 @@
1
+ /**
2
+ * state-store.ts — DO-SQLite-backed persistence for session state
3
+ * that must survive isolate teardown [Phase 3 Track B'].
4
+ *
5
+ * Why this exists
6
+ * ───────────────
7
+ * Pre-Phase-3 the supervisor's session state lived entirely in
8
+ * isolate memory: the LIFO Shell instance owned cwd + env vars; the
9
+ * LIFO Kernel owned mount points; the WebSocketTerminal had no
10
+ * persistence at all. A wsClose / wsError nulled all three
11
+ * (src/nimbus-session-ws.ts:165-167, :221-223), and the next /ws
12
+ * upgrade rebuilt them from defaults. Result: cwd reset to ~,
13
+ * env vars lost, scrollback gone, MOTD reprinted — the user-
14
+ * visible Bug C symptom.
15
+ *
16
+ * The architectural fix is to move every observable session-state
17
+ * field into DO SQLite. The in-memory fields become CACHES of the
18
+ * SQL row, not the master copy. A wsClose flushes the cache and
19
+ * clears the in-memory copy; a /ws upgrade reads SQL and seeds the
20
+ * fresh Shell/Kernel/Terminal.
21
+ *
22
+ * Schema overview
23
+ * ───────────────
24
+ * Three tables, all keyed by single-row sentinels:
25
+ *
26
+ * nimbus_session_kv (k TEXT PRIMARY KEY, v TEXT)
27
+ * — generic key/value bag for primitives. Today stores 'cwd'
28
+ * and 'env' (the env is JSON-serialised). One row per key.
29
+ *
30
+ * nimbus_kernel_mounts (mount_point TEXT PRIMARY KEY)
31
+ * — explicit mount-point list (B'.2). Empty until B'.2 lands.
32
+ *
33
+ * nimbus_terminal_scrollback (seq INTEGER PRIMARY KEY, ts INTEGER, data TEXT)
34
+ * — bounded ring of recent terminal output (B'.3). Empty until
35
+ * B'.3 lands.
36
+ *
37
+ * Stability contract
38
+ * ──────────────────
39
+ * Every storage key + table name in this module is part of the DO's
40
+ * persistent schema. Renaming any of them is a storage migration —
41
+ * never do it without an explicit migration plan. New tables can be
42
+ * added; existing tables can be ALTER-ADDed columns (schema is
43
+ * forward-compatible if the rehydrate path reads-with-default for
44
+ * missing columns).
45
+ */
46
+ /** Module-level cap on the env-row JSON length. The whole env is one
47
+ * row in nimbus_session_kv; if the user's env explodes (eg every
48
+ * npm-install side-effects 100 vars), we want to surface that as a
49
+ * clear error rather than a silent storage-row-too-long failure.
50
+ *
51
+ * Per docs/research/cf-internal-dossier.md §9 the per-row cap is
52
+ * 2 MB; we set a much tighter 256 KiB ceiling so a misbehaving
53
+ * session can't approach the platform limit. */
54
+ export declare const SESSION_ENV_MAX_BYTES: number;
55
+ /** Module-level cap on the per-session terminal scrollback in DO
56
+ * SQLite. Each WS `output` frame written by WebSocketTerminal is
57
+ * persisted as one row; on every insert we evict the oldest rows
58
+ * until total bytes ≤ this cap.
59
+ *
60
+ * 1 MiB ≈ ~10,000 lines of ANSI-coloured prompt+output text — many
61
+ * multiples of typical xterm.js scrollback default (1000 rows ×
62
+ * ~100B = ~100KB). The headroom matters: real workloads commonly
63
+ * produce a single huge frame (eg `cat package-lock.json` ≈ 200 KiB)
64
+ * followed by many small frames (prompt updates, cd output). With
65
+ * the cap at 256 KiB, the big frame consumes the entire budget and
66
+ * every subsequent prompt update displaces it via eviction. With
67
+ * 1 MiB we have room for the big frame plus the next dozens of
68
+ * command outputs.
69
+ *
70
+ * This is a SOFT cap on persistence. The live terminal still gets
71
+ * every byte the shell writes; only the rehydrate-on-reconnect
72
+ * replay is bounded. A user who exceeds 1 MiB mid-session sees
73
+ * full output live, but on reconnect only the most recent ~1 MiB
74
+ * replays. That's the right trade-off — losing early-session output
75
+ * > losing recent output, and DO storage is cheap relative to a
76
+ * good UX.
77
+ *
78
+ * Per row, individual frames > MAX_FRAME_BYTES are TRUNCATED to
79
+ * their last MAX_FRAME_BYTES — same trade-off applied at the
80
+ * single-frame granularity for pathological multi-MB cat output. */
81
+ export declare const SCROLLBACK_MAX_BYTES: number;
82
+ /** Per-row cap. A single coalesced WS frame larger than this is
83
+ * trimmed to its trailing MAX_FRAME_BYTES bytes before insert. Set
84
+ * smaller than SCROLLBACK_MAX_BYTES so a single huge frame can't
85
+ * consume the whole budget; with this gap, the eviction loop never
86
+ * has to delete the just-inserted row to fit a subsequent small
87
+ * one. 256 KiB per frame is generous (a screenful of dense text +
88
+ * ANSI). */
89
+ export declare const SCROLLBACK_MAX_FRAME_BYTES: number;
90
+ /** Storage key names. Module-scope constants so a future migration
91
+ * can find every site by grep. */
92
+ export declare const KEY_CWD = "cwd";
93
+ export declare const KEY_ENV_JSON = "env";
94
+ export declare const KEY_HYDRATED_AT = "hydrated_at";
95
+ /** A snapshot of the persisted shell state, returned by loadShellState. */
96
+ export interface ShellStateSnapshot {
97
+ cwd: string | null;
98
+ env: Record<string, string> | null;
99
+ hydratedAt: number | null;
100
+ /** True iff at least one of cwd/env was present in SQL. The caller
101
+ * uses this to decide cold-start (no row) vs. rehydrate (row present),
102
+ * which gates one-shot UI like the MOTD. */
103
+ hasPersistedState: boolean;
104
+ }
105
+ /**
106
+ * Idempotent CREATE TABLE. Safe to call on every initSession; the
107
+ * IF NOT EXISTS clause makes repeats free. Inlines all three Track
108
+ * B' tables; B'.2 / B'.3 land their callers, not their schema.
109
+ */
110
+ export declare function ensureSessionStateSchema(ctx: any): void;
111
+ /**
112
+ * Load the persisted shell state. Returns a snapshot with `null`
113
+ * fields when no row exists. Never throws — a corrupt env row
114
+ * (failed JSON parse) returns null env and we treat it as cold;
115
+ * better to start fresh than crash the rehydrate path.
116
+ *
117
+ * Auto-ensures the schema. Calling this from a route handler that
118
+ * runs BEFORE any WS upgrade (e.g. /api/_diag/session on a freshly-
119
+ * minted session) used to fail with SQLITE_ERROR because no prior
120
+ * code path had run CREATE TABLE. The IF NOT EXISTS guarantees the
121
+ * extra ensure is microseconds when tables already exist.
122
+ */
123
+ export declare function loadShellState(ctx: any): ShellStateSnapshot;
124
+ /**
125
+ * Atomically write the shell state. Called from the snapshot
126
+ * mechanism (periodic + on wsClose). Uses INSERT-OR-REPLACE so
127
+ * repeated writes are idempotent.
128
+ *
129
+ * `cwd` and `env` are both required parameters — the caller (the
130
+ * snapshot loop in initSession) reads them from the live Shell
131
+ * BEFORE calling. If either is null, the corresponding row is
132
+ * REMOVED rather than re-written; this keeps the table clean if a
133
+ * future code path explicitly clears state.
134
+ *
135
+ * Throws if the env JSON would exceed SESSION_ENV_MAX_BYTES — that's
136
+ * a session-misuse signal worth surfacing rather than silently
137
+ * truncating.
138
+ */
139
+ export declare function persistShellState(ctx: any, state: {
140
+ cwd: string | null;
141
+ env: Record<string, string> | null;
142
+ }): void;
143
+ /**
144
+ * Stamp the time of the most recent successful hydrate. Used by the
145
+ * /api/_diag/session debug endpoint to show "the last cold-start
146
+ * found a row at <ts>". Cheap; one row write per initSession call.
147
+ */
148
+ export declare function stampHydratedAt(ctx: any, atMs: number): void;
149
+ /**
150
+ * Drop ALL session-state rows. Used by /api/_test/session/reset for
151
+ * test-only flows; never called from prod paths. Equivalent to
152
+ * "this DO has never seen a session" — the next initSession runs
153
+ * the cold-start path.
154
+ */
155
+ export declare function clearSessionState(ctx: any): void;
156
+ /** Count rows in nimbus_session_kv — used by the recovery_event
157
+ * recorder to populate snapshotKeysRehydrated. Cheap; bounded by
158
+ * the small key set above. */
159
+ export declare function countSessionStateKeys(ctx: any): number;
160
+ /**
161
+ * Load the persisted mount-point list. Returns a plain string[] of
162
+ * mount point names (without leading slash — same shape as
163
+ * DEFAULT_MOUNT_POINTS). Empty array when no rows exist.
164
+ */
165
+ export declare function loadKernelMounts(ctx: any): string[];
166
+ /**
167
+ * Persist a mount-point list. Idempotent — replaces the entire
168
+ * nimbus_kernel_mounts contents in a single transaction. Caller
169
+ * provides the full desired set; we don't merge with existing rows.
170
+ *
171
+ * `mounts` should be plain names without leading slash
172
+ * ('bin', 'etc', ...) — same shape DEFAULT_MOUNT_POINTS uses.
173
+ */
174
+ export declare function persistKernelMounts(ctx: any, mounts: string[]): void;
175
+ /**
176
+ * Append one coalesced output frame. Inserts a row, then evicts the
177
+ * oldest rows until total bytes ≤ SCROLLBACK_MAX_BYTES.
178
+ *
179
+ * `data` is the UTF-8 string written to the WS (typically including
180
+ * ANSI escape codes); empty strings are no-ops.
181
+ *
182
+ * Frames larger than SCROLLBACK_MAX_BYTES are TRUNCATED to their
183
+ * last cap bytes before insert. Reasoning: a single shell command
184
+ * (eg `cat huge-file`) can produce ≫ cap bytes in one coalesced WS
185
+ * frame; we want to preserve the most recent portion of that
186
+ * output (the user's "what just happened") rather than dropping it
187
+ * entirely. Truncation of UTF-8 at byte boundaries can split a
188
+ * multi-byte sequence; we accept that minor cosmetic risk vs. the
189
+ * complexity of a code-point-aware slice.
190
+ *
191
+ * Fail-soft: any thrown error is swallowed by the caller — losing
192
+ * scrollback is annoying but not session-fatal.
193
+ */
194
+ export declare function appendScrollback(ctx: any, data: string, atMs: number): void;
195
+ /**
196
+ * Read all scrollback rows in seq (chronological) order and return
197
+ * the concatenated payload. Used by the rehydrate path to emit a
198
+ * single batched replay frame.
199
+ *
200
+ * Returns empty string when the table is empty (cold start, or
201
+ * after explicit reset).
202
+ */
203
+ export declare function loadScrollback(ctx: any): string;
204
+ /** Stats for /api/_diag/session: row count + total bytes + cap. */
205
+ export declare function getScrollbackStats(ctx: any): {
206
+ rows: number;
207
+ bytes: number;
208
+ maxBytes: number;
209
+ };
210
+ //# sourceMappingURL=state-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../../src/session/state-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;;;;;;iDAOiD;AACjD,eAAO,MAAM,qBAAqB,QAAa,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;qEAyBqE;AACrE,eAAO,MAAM,oBAAoB,QAAc,CAAC;AAChD;;;;;;aAMa;AACb,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAErD;mCACmC;AACnC,eAAO,MAAM,OAAO,QAAQ,CAAC;AAC7B,eAAO,MAAM,YAAY,QAAQ,CAAC;AAClC,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACnC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;iDAE6C;IAC7C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAiCvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,kBAAkB,CAqC3D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,GAAG,EACR,KAAK,EAAE;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAA;CAAE,GAChE,IAAI,CA6BN;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAQ5D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAOhD;AAED;;+BAE+B;AAC/B,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAQtD;AAaD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,EAAE,CAWnD;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAcpE;AAwBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA6E3E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAW/C;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG;IAC5C,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;CAC/C,CAaA"}
@@ -0,0 +1,459 @@
1
+ /**
2
+ * state-store.ts — DO-SQLite-backed persistence for session state
3
+ * that must survive isolate teardown [Phase 3 Track B'].
4
+ *
5
+ * Why this exists
6
+ * ───────────────
7
+ * Pre-Phase-3 the supervisor's session state lived entirely in
8
+ * isolate memory: the LIFO Shell instance owned cwd + env vars; the
9
+ * LIFO Kernel owned mount points; the WebSocketTerminal had no
10
+ * persistence at all. A wsClose / wsError nulled all three
11
+ * (src/nimbus-session-ws.ts:165-167, :221-223), and the next /ws
12
+ * upgrade rebuilt them from defaults. Result: cwd reset to ~,
13
+ * env vars lost, scrollback gone, MOTD reprinted — the user-
14
+ * visible Bug C symptom.
15
+ *
16
+ * The architectural fix is to move every observable session-state
17
+ * field into DO SQLite. The in-memory fields become CACHES of the
18
+ * SQL row, not the master copy. A wsClose flushes the cache and
19
+ * clears the in-memory copy; a /ws upgrade reads SQL and seeds the
20
+ * fresh Shell/Kernel/Terminal.
21
+ *
22
+ * Schema overview
23
+ * ───────────────
24
+ * Three tables, all keyed by single-row sentinels:
25
+ *
26
+ * nimbus_session_kv (k TEXT PRIMARY KEY, v TEXT)
27
+ * — generic key/value bag for primitives. Today stores 'cwd'
28
+ * and 'env' (the env is JSON-serialised). One row per key.
29
+ *
30
+ * nimbus_kernel_mounts (mount_point TEXT PRIMARY KEY)
31
+ * — explicit mount-point list (B'.2). Empty until B'.2 lands.
32
+ *
33
+ * nimbus_terminal_scrollback (seq INTEGER PRIMARY KEY, ts INTEGER, data TEXT)
34
+ * — bounded ring of recent terminal output (B'.3). Empty until
35
+ * B'.3 lands.
36
+ *
37
+ * Stability contract
38
+ * ──────────────────
39
+ * Every storage key + table name in this module is part of the DO's
40
+ * persistent schema. Renaming any of them is a storage migration —
41
+ * never do it without an explicit migration plan. New tables can be
42
+ * added; existing tables can be ALTER-ADDed columns (schema is
43
+ * forward-compatible if the rehydrate path reads-with-default for
44
+ * missing columns).
45
+ */
46
+ /** Module-level cap on the env-row JSON length. The whole env is one
47
+ * row in nimbus_session_kv; if the user's env explodes (eg every
48
+ * npm-install side-effects 100 vars), we want to surface that as a
49
+ * clear error rather than a silent storage-row-too-long failure.
50
+ *
51
+ * Per docs/research/cf-internal-dossier.md §9 the per-row cap is
52
+ * 2 MB; we set a much tighter 256 KiB ceiling so a misbehaving
53
+ * session can't approach the platform limit. */
54
+ export const SESSION_ENV_MAX_BYTES = 256 * 1024;
55
+ /** Module-level cap on the per-session terminal scrollback in DO
56
+ * SQLite. Each WS `output` frame written by WebSocketTerminal is
57
+ * persisted as one row; on every insert we evict the oldest rows
58
+ * until total bytes ≤ this cap.
59
+ *
60
+ * 1 MiB ≈ ~10,000 lines of ANSI-coloured prompt+output text — many
61
+ * multiples of typical xterm.js scrollback default (1000 rows ×
62
+ * ~100B = ~100KB). The headroom matters: real workloads commonly
63
+ * produce a single huge frame (eg `cat package-lock.json` ≈ 200 KiB)
64
+ * followed by many small frames (prompt updates, cd output). With
65
+ * the cap at 256 KiB, the big frame consumes the entire budget and
66
+ * every subsequent prompt update displaces it via eviction. With
67
+ * 1 MiB we have room for the big frame plus the next dozens of
68
+ * command outputs.
69
+ *
70
+ * This is a SOFT cap on persistence. The live terminal still gets
71
+ * every byte the shell writes; only the rehydrate-on-reconnect
72
+ * replay is bounded. A user who exceeds 1 MiB mid-session sees
73
+ * full output live, but on reconnect only the most recent ~1 MiB
74
+ * replays. That's the right trade-off — losing early-session output
75
+ * > losing recent output, and DO storage is cheap relative to a
76
+ * good UX.
77
+ *
78
+ * Per row, individual frames > MAX_FRAME_BYTES are TRUNCATED to
79
+ * their last MAX_FRAME_BYTES — same trade-off applied at the
80
+ * single-frame granularity for pathological multi-MB cat output. */
81
+ export const SCROLLBACK_MAX_BYTES = 1024 * 1024;
82
+ /** Per-row cap. A single coalesced WS frame larger than this is
83
+ * trimmed to its trailing MAX_FRAME_BYTES bytes before insert. Set
84
+ * smaller than SCROLLBACK_MAX_BYTES so a single huge frame can't
85
+ * consume the whole budget; with this gap, the eviction loop never
86
+ * has to delete the just-inserted row to fit a subsequent small
87
+ * one. 256 KiB per frame is generous (a screenful of dense text +
88
+ * ANSI). */
89
+ export const SCROLLBACK_MAX_FRAME_BYTES = 256 * 1024;
90
+ /** Storage key names. Module-scope constants so a future migration
91
+ * can find every site by grep. */
92
+ export const KEY_CWD = 'cwd';
93
+ export const KEY_ENV_JSON = 'env';
94
+ export const KEY_HYDRATED_AT = 'hydrated_at';
95
+ /**
96
+ * Idempotent CREATE TABLE. Safe to call on every initSession; the
97
+ * IF NOT EXISTS clause makes repeats free. Inlines all three Track
98
+ * B' tables; B'.2 / B'.3 land their callers, not their schema.
99
+ */
100
+ export function ensureSessionStateSchema(ctx) {
101
+ const sql = ctx?.storage?.sql;
102
+ if (!sql)
103
+ return;
104
+ sql.exec('CREATE TABLE IF NOT EXISTS nimbus_session_kv (' +
105
+ 'k TEXT PRIMARY KEY, ' +
106
+ 'v TEXT NOT NULL)');
107
+ sql.exec('CREATE TABLE IF NOT EXISTS nimbus_kernel_mounts (' +
108
+ 'mount_point TEXT PRIMARY KEY)');
109
+ sql.exec('CREATE TABLE IF NOT EXISTS nimbus_terminal_scrollback (' +
110
+ 'seq INTEGER PRIMARY KEY AUTOINCREMENT, ' +
111
+ 'ts INTEGER NOT NULL, ' +
112
+ 'data TEXT NOT NULL, ' +
113
+ 'bytes INTEGER NOT NULL DEFAULT 0)');
114
+ // [B'.3] Migration guard: B'.1 created the table without a `bytes`
115
+ // column. If a DO already ran B'.1/B'.2 with that schema, the
116
+ // CREATE TABLE IF NOT EXISTS above is a no-op and we'd hit
117
+ // 'no such column: bytes' on the first INSERT. Detect via
118
+ // PRAGMA table_info and ALTER if the column is missing.
119
+ let hasBytes = false;
120
+ for (const row of sql.exec('PRAGMA table_info(nimbus_terminal_scrollback)')) {
121
+ if (String(row.name) === 'bytes') {
122
+ hasBytes = true;
123
+ break;
124
+ }
125
+ }
126
+ if (!hasBytes) {
127
+ try {
128
+ sql.exec('ALTER TABLE nimbus_terminal_scrollback ADD COLUMN bytes INTEGER NOT NULL DEFAULT 0');
129
+ }
130
+ catch { /* race: concurrent ensure already added it */ }
131
+ }
132
+ }
133
+ /**
134
+ * Load the persisted shell state. Returns a snapshot with `null`
135
+ * fields when no row exists. Never throws — a corrupt env row
136
+ * (failed JSON parse) returns null env and we treat it as cold;
137
+ * better to start fresh than crash the rehydrate path.
138
+ *
139
+ * Auto-ensures the schema. Calling this from a route handler that
140
+ * runs BEFORE any WS upgrade (e.g. /api/_diag/session on a freshly-
141
+ * minted session) used to fail with SQLITE_ERROR because no prior
142
+ * code path had run CREATE TABLE. The IF NOT EXISTS guarantees the
143
+ * extra ensure is microseconds when tables already exist.
144
+ */
145
+ export function loadShellState(ctx) {
146
+ const sql = ctx?.storage?.sql;
147
+ const empty = {
148
+ cwd: null, env: null, hydratedAt: null, hasPersistedState: false,
149
+ };
150
+ if (!sql)
151
+ return empty;
152
+ ensureSessionStateSchema(ctx);
153
+ // Single row per key — the table is intentionally tiny so we read
154
+ // all interesting keys in one query.
155
+ let cwd = null;
156
+ let env = null;
157
+ let hydratedAt = null;
158
+ let any = false;
159
+ for (const row of sql.exec('SELECT k, v FROM nimbus_session_kv WHERE k IN (?, ?, ?)', KEY_CWD, KEY_ENV_JSON, KEY_HYDRATED_AT)) {
160
+ any = true;
161
+ if (row.k === KEY_CWD) {
162
+ cwd = String(row.v);
163
+ }
164
+ else if (row.k === KEY_ENV_JSON) {
165
+ try {
166
+ const parsed = JSON.parse(String(row.v));
167
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
168
+ env = parsed;
169
+ }
170
+ }
171
+ catch {
172
+ // Corrupt env JSON → treat as no env (still rehydrates cwd
173
+ // from the cwd row above). Don't throw.
174
+ }
175
+ }
176
+ else if (row.k === KEY_HYDRATED_AT) {
177
+ const n = Number(row.v);
178
+ hydratedAt = Number.isFinite(n) ? n : null;
179
+ }
180
+ }
181
+ return { cwd, env, hydratedAt, hasPersistedState: any };
182
+ }
183
+ /**
184
+ * Atomically write the shell state. Called from the snapshot
185
+ * mechanism (periodic + on wsClose). Uses INSERT-OR-REPLACE so
186
+ * repeated writes are idempotent.
187
+ *
188
+ * `cwd` and `env` are both required parameters — the caller (the
189
+ * snapshot loop in initSession) reads them from the live Shell
190
+ * BEFORE calling. If either is null, the corresponding row is
191
+ * REMOVED rather than re-written; this keeps the table clean if a
192
+ * future code path explicitly clears state.
193
+ *
194
+ * Throws if the env JSON would exceed SESSION_ENV_MAX_BYTES — that's
195
+ * a session-misuse signal worth surfacing rather than silently
196
+ * truncating.
197
+ */
198
+ export function persistShellState(ctx, state) {
199
+ const sql = ctx?.storage?.sql;
200
+ if (!sql)
201
+ return;
202
+ ensureSessionStateSchema(ctx);
203
+ if (state.cwd !== null) {
204
+ sql.exec('INSERT OR REPLACE INTO nimbus_session_kv (k, v) VALUES (?, ?)', KEY_CWD, state.cwd);
205
+ }
206
+ else {
207
+ sql.exec('DELETE FROM nimbus_session_kv WHERE k = ?', KEY_CWD);
208
+ }
209
+ if (state.env !== null) {
210
+ const json = JSON.stringify(state.env);
211
+ if (json.length > SESSION_ENV_MAX_BYTES) {
212
+ throw new Error(`[state-store] env JSON exceeds ${SESSION_ENV_MAX_BYTES} bytes ` +
213
+ `(got ${json.length}); refusing to persist`);
214
+ }
215
+ sql.exec('INSERT OR REPLACE INTO nimbus_session_kv (k, v) VALUES (?, ?)', KEY_ENV_JSON, json);
216
+ }
217
+ else {
218
+ sql.exec('DELETE FROM nimbus_session_kv WHERE k = ?', KEY_ENV_JSON);
219
+ }
220
+ }
221
+ /**
222
+ * Stamp the time of the most recent successful hydrate. Used by the
223
+ * /api/_diag/session debug endpoint to show "the last cold-start
224
+ * found a row at <ts>". Cheap; one row write per initSession call.
225
+ */
226
+ export function stampHydratedAt(ctx, atMs) {
227
+ const sql = ctx?.storage?.sql;
228
+ if (!sql)
229
+ return;
230
+ ensureSessionStateSchema(ctx);
231
+ sql.exec('INSERT OR REPLACE INTO nimbus_session_kv (k, v) VALUES (?, ?)', KEY_HYDRATED_AT, String(atMs));
232
+ }
233
+ /**
234
+ * Drop ALL session-state rows. Used by /api/_test/session/reset for
235
+ * test-only flows; never called from prod paths. Equivalent to
236
+ * "this DO has never seen a session" — the next initSession runs
237
+ * the cold-start path.
238
+ */
239
+ export function clearSessionState(ctx) {
240
+ const sql = ctx?.storage?.sql;
241
+ if (!sql)
242
+ return;
243
+ ensureSessionStateSchema(ctx);
244
+ sql.exec('DELETE FROM nimbus_session_kv');
245
+ sql.exec('DELETE FROM nimbus_kernel_mounts');
246
+ sql.exec('DELETE FROM nimbus_terminal_scrollback');
247
+ }
248
+ /** Count rows in nimbus_session_kv — used by the recovery_event
249
+ * recorder to populate snapshotKeysRehydrated. Cheap; bounded by
250
+ * the small key set above. */
251
+ export function countSessionStateKeys(ctx) {
252
+ const sql = ctx?.storage?.sql;
253
+ if (!sql)
254
+ return 0;
255
+ ensureSessionStateSchema(ctx);
256
+ for (const row of sql.exec('SELECT COUNT(*) AS n FROM nimbus_session_kv')) {
257
+ return Number(row.n) || 0;
258
+ }
259
+ return 0;
260
+ }
261
+ // ── Kernel mount tree [B'.2] ───────────────────────────────────────────
262
+ //
263
+ // The kernel mount list lives in nimbus_kernel_mounts. Today the list
264
+ // is exactly DEFAULT_MOUNT_POINTS (a static constant in src/constants.ts),
265
+ // so persistence is functionally redundant — every initSession would
266
+ // rebuild the same list from the constant. The architectural reason to
267
+ // route mount-list reads through SQL anyway is to give a future
268
+ // custom-mount feature a stable storage surface: when `mount /r2-cache`
269
+ // is added later, it just inserts a row, and the rehydrate path picks
270
+ // it up without any further refactor.
271
+ /**
272
+ * Load the persisted mount-point list. Returns a plain string[] of
273
+ * mount point names (without leading slash — same shape as
274
+ * DEFAULT_MOUNT_POINTS). Empty array when no rows exist.
275
+ */
276
+ export function loadKernelMounts(ctx) {
277
+ const sql = ctx?.storage?.sql;
278
+ if (!sql)
279
+ return [];
280
+ ensureSessionStateSchema(ctx);
281
+ const out = [];
282
+ for (const row of sql.exec('SELECT mount_point FROM nimbus_kernel_mounts ORDER BY mount_point ASC')) {
283
+ out.push(String(row.mount_point));
284
+ }
285
+ return out;
286
+ }
287
+ /**
288
+ * Persist a mount-point list. Idempotent — replaces the entire
289
+ * nimbus_kernel_mounts contents in a single transaction. Caller
290
+ * provides the full desired set; we don't merge with existing rows.
291
+ *
292
+ * `mounts` should be plain names without leading slash
293
+ * ('bin', 'etc', ...) — same shape DEFAULT_MOUNT_POINTS uses.
294
+ */
295
+ export function persistKernelMounts(ctx, mounts) {
296
+ const sql = ctx?.storage?.sql;
297
+ if (!sql)
298
+ return;
299
+ ensureSessionStateSchema(ctx);
300
+ // Replace-all semantics: clear, then insert. The whole table is
301
+ // bounded by O(10) rows so a full rewrite per persist is cheap.
302
+ sql.exec('DELETE FROM nimbus_kernel_mounts');
303
+ for (const mp of mounts) {
304
+ if (typeof mp !== 'string' || mp.length === 0)
305
+ continue;
306
+ sql.exec('INSERT OR REPLACE INTO nimbus_kernel_mounts (mount_point) VALUES (?)', mp);
307
+ }
308
+ }
309
+ // ── Terminal scrollback [B'.3] ─────────────────────────────────────────
310
+ //
311
+ // Every coalesced WS `output` frame (post-flush) is appended as one
312
+ // row in nimbus_terminal_scrollback. On reconnect, the rehydrate path
313
+ // reads all rows in seq order, concatenates the data column, and
314
+ // emits a single replay frame so the user sees their pre-close
315
+ // terminal contents above the fresh prompt.
316
+ //
317
+ // Cap policy: byte-budget eviction. After every append, if total
318
+ // bytes > SCROLLBACK_MAX_BYTES, delete oldest-seq rows until the
319
+ // total fits. Per-row count is unbounded — frames are coalesced at
320
+ // the WebSocketTerminal flush layer (5 ms timer) so a chatty shell
321
+ // produces O(N_frames) rows, not O(N_writes).
322
+ //
323
+ // The byte length of each frame is computed by the caller (cheap
324
+ // TextEncoder().encode().length) and stored in the `bytes` column.
325
+ // Computing per-row length on the read side would also work
326
+ // (length(CAST(data AS BLOB))) but storing it makes the eviction
327
+ // query trivial.
328
+ const _scrollbackEnc = new TextEncoder();
329
+ /**
330
+ * Append one coalesced output frame. Inserts a row, then evicts the
331
+ * oldest rows until total bytes ≤ SCROLLBACK_MAX_BYTES.
332
+ *
333
+ * `data` is the UTF-8 string written to the WS (typically including
334
+ * ANSI escape codes); empty strings are no-ops.
335
+ *
336
+ * Frames larger than SCROLLBACK_MAX_BYTES are TRUNCATED to their
337
+ * last cap bytes before insert. Reasoning: a single shell command
338
+ * (eg `cat huge-file`) can produce ≫ cap bytes in one coalesced WS
339
+ * frame; we want to preserve the most recent portion of that
340
+ * output (the user's "what just happened") rather than dropping it
341
+ * entirely. Truncation of UTF-8 at byte boundaries can split a
342
+ * multi-byte sequence; we accept that minor cosmetic risk vs. the
343
+ * complexity of a code-point-aware slice.
344
+ *
345
+ * Fail-soft: any thrown error is swallowed by the caller — losing
346
+ * scrollback is annoying but not session-fatal.
347
+ */
348
+ export function appendScrollback(ctx, data, atMs) {
349
+ if (!data || data.length === 0)
350
+ return;
351
+ const sql = ctx?.storage?.sql;
352
+ if (!sql)
353
+ return;
354
+ ensureSessionStateSchema(ctx);
355
+ // Per-frame truncation: oversized single frames keep only the
356
+ // trailing MAX_FRAME_BYTES bytes. The "trailing" choice matches
357
+ // user intuition — when scrollback shows a big cat output, the
358
+ // user cares about the END of that output (where the prompt is)
359
+ // not the beginning.
360
+ let payload = data;
361
+ let bytes = _scrollbackEnc.encode(payload).length;
362
+ if (bytes > SCROLLBACK_MAX_FRAME_BYTES) {
363
+ const buf = _scrollbackEnc.encode(payload);
364
+ const start = buf.length - SCROLLBACK_MAX_FRAME_BYTES;
365
+ payload = new TextDecoder().decode(buf.subarray(start));
366
+ bytes = _scrollbackEnc.encode(payload).length;
367
+ }
368
+ let insertedSeq = null;
369
+ try {
370
+ sql.exec('INSERT INTO nimbus_terminal_scrollback (ts, data, bytes) VALUES (?, ?, ?)', atMs, payload, bytes);
371
+ // Capture the seq we just wrote so the eviction loop can avoid
372
+ // deleting it. SQLite's last_insert_rowid() returns the row id of
373
+ // the most recent insert on this connection.
374
+ for (const row of sql.exec('SELECT last_insert_rowid() AS id')) {
375
+ insertedSeq = Number(row.id);
376
+ break;
377
+ }
378
+ }
379
+ catch (e) {
380
+ try {
381
+ console.warn('[B\'.3] scrollback INSERT failed bytes=' + bytes + ' err=' + (e?.message || e));
382
+ }
383
+ catch { }
384
+ return;
385
+ }
386
+ // Eviction. Read total bytes; if over cap, delete oldest-seq rows
387
+ // in a loop. The table is bounded so a select-min/delete loop is
388
+ // O(rows-evicted) and runs only when needed.
389
+ //
390
+ // Invariant: we never delete the row we JUST inserted. With a
391
+ // sensibly-sized MAX_FRAME_BYTES (256 KiB) << MAX_BYTES (1 MiB),
392
+ // a single insert can never single-handedly violate the cap by
393
+ // more than MAX_FRAME_BYTES, and the eviction loop always has
394
+ // older rows to delete first. The "never the new row" guard is
395
+ // a belt-and-suspenders defence against future mis-tuning of the
396
+ // two constants.
397
+ let total = 0;
398
+ for (const row of sql.exec('SELECT COALESCE(SUM(bytes), 0) AS n FROM nimbus_terminal_scrollback')) {
399
+ total = Number(row.n) || 0;
400
+ break;
401
+ }
402
+ if (total <= SCROLLBACK_MAX_BYTES)
403
+ return;
404
+ for (;;) {
405
+ let oldestSeq = null;
406
+ let oldestBytes = 0;
407
+ for (const row of sql.exec('SELECT seq, bytes FROM nimbus_terminal_scrollback ORDER BY seq ASC LIMIT 1')) {
408
+ oldestSeq = Number(row.seq);
409
+ oldestBytes = Number(row.bytes) || 0;
410
+ break;
411
+ }
412
+ if (oldestSeq === null)
413
+ break;
414
+ if (insertedSeq !== null && oldestSeq === insertedSeq) {
415
+ // The row we just inserted is now the only row → can't evict
416
+ // it; cap is briefly exceeded, accept it. With MAX_FRAME_BYTES
417
+ // ≤ MAX_BYTES the over-by amount is bounded.
418
+ break;
419
+ }
420
+ sql.exec('DELETE FROM nimbus_terminal_scrollback WHERE seq = ?', oldestSeq);
421
+ total -= oldestBytes;
422
+ if (total <= SCROLLBACK_MAX_BYTES)
423
+ break;
424
+ }
425
+ }
426
+ /**
427
+ * Read all scrollback rows in seq (chronological) order and return
428
+ * the concatenated payload. Used by the rehydrate path to emit a
429
+ * single batched replay frame.
430
+ *
431
+ * Returns empty string when the table is empty (cold start, or
432
+ * after explicit reset).
433
+ */
434
+ export function loadScrollback(ctx) {
435
+ const sql = ctx?.storage?.sql;
436
+ if (!sql)
437
+ return '';
438
+ ensureSessionStateSchema(ctx);
439
+ const parts = [];
440
+ for (const row of sql.exec('SELECT data FROM nimbus_terminal_scrollback ORDER BY seq ASC')) {
441
+ parts.push(String(row.data));
442
+ }
443
+ return parts.join('');
444
+ }
445
+ /** Stats for /api/_diag/session: row count + total bytes + cap. */
446
+ export function getScrollbackStats(ctx) {
447
+ const sql = ctx?.storage?.sql;
448
+ if (!sql)
449
+ return { rows: 0, bytes: 0, maxBytes: SCROLLBACK_MAX_BYTES };
450
+ ensureSessionStateSchema(ctx);
451
+ let rows = 0;
452
+ let bytes = 0;
453
+ for (const row of sql.exec('SELECT COUNT(*) AS n, COALESCE(SUM(bytes), 0) AS b FROM nimbus_terminal_scrollback')) {
454
+ rows = Number(row.n) || 0;
455
+ bytes = Number(row.b) || 0;
456
+ break;
457
+ }
458
+ return { rows, bytes, maxBytes: SCROLLBACK_MAX_BYTES };
459
+ }