@nimbus-sh/core 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 (1056) hide show
  1. package/dist/_shared/ai-egress.d.ts +73 -0
  2. package/dist/_shared/ai-egress.d.ts.map +1 -0
  3. package/dist/_shared/ai-egress.js +88 -0
  4. package/dist/_shared/byte-stream.d.ts +59 -0
  5. package/dist/_shared/byte-stream.d.ts.map +1 -0
  6. package/dist/_shared/byte-stream.js +77 -0
  7. package/dist/_shared/bytes.d.ts +18 -0
  8. package/dist/_shared/bytes.d.ts.map +1 -0
  9. package/dist/_shared/bytes.js +17 -0
  10. package/dist/_shared/cache-stats.d.ts +145 -0
  11. package/dist/_shared/cache-stats.d.ts.map +1 -0
  12. package/dist/_shared/cache-stats.js +161 -0
  13. package/dist/_shared/crypto.d.ts +17 -0
  14. package/dist/_shared/crypto.d.ts.map +1 -0
  15. package/dist/_shared/crypto.js +131 -0
  16. package/dist/_shared/esbuild-facet-shim.d.ts +21 -0
  17. package/dist/_shared/esbuild-facet-shim.d.ts.map +1 -0
  18. package/dist/_shared/esbuild-facet-shim.js +22 -0
  19. package/dist/_shared/exports-resolver.d.ts +74 -0
  20. package/dist/_shared/exports-resolver.d.ts.map +1 -0
  21. package/dist/_shared/exports-resolver.js +284 -0
  22. package/dist/_shared/facet-vfs-cursor.d.ts +48 -0
  23. package/dist/_shared/facet-vfs-cursor.d.ts.map +1 -0
  24. package/dist/_shared/facet-vfs-cursor.js +51 -0
  25. package/dist/_shared/install-phase.d.ts +47 -0
  26. package/dist/_shared/install-phase.d.ts.map +1 -0
  27. package/dist/_shared/install-phase.js +1 -0
  28. package/dist/_shared/lru-map.d.ts +25 -0
  29. package/dist/_shared/lru-map.d.ts.map +1 -0
  30. package/dist/_shared/lru-map.js +57 -0
  31. package/dist/_shared/real-node-imports.d.ts +43 -0
  32. package/dist/_shared/real-node-imports.d.ts.map +1 -0
  33. package/dist/_shared/real-node-imports.js +52 -0
  34. package/dist/_shared/retry.d.ts +92 -0
  35. package/dist/_shared/retry.d.ts.map +1 -0
  36. package/dist/_shared/retry.js +155 -0
  37. package/dist/_shared/rpc-dispose.d.ts +4 -0
  38. package/dist/_shared/rpc-dispose.d.ts.map +1 -0
  39. package/dist/_shared/rpc-dispose.js +30 -0
  40. package/dist/_shared/terminal.d.ts +2 -0
  41. package/dist/_shared/terminal.d.ts.map +1 -0
  42. package/dist/_shared/terminal.js +3 -0
  43. package/dist/_shared/typescript-specifiers.d.ts +58 -0
  44. package/dist/_shared/typescript-specifiers.d.ts.map +1 -0
  45. package/dist/_shared/typescript-specifiers.js +84 -0
  46. package/dist/_shared/untrusted-request.d.ts +34 -0
  47. package/dist/_shared/untrusted-request.d.ts.map +1 -0
  48. package/dist/_shared/untrusted-request.js +74 -0
  49. package/dist/_shared/vfs-write-ledger.d.ts +3 -0
  50. package/dist/_shared/vfs-write-ledger.d.ts.map +1 -0
  51. package/dist/_shared/vfs-write-ledger.js +439 -0
  52. package/dist/_shared/w7-frame.d.ts +79 -0
  53. package/dist/_shared/w7-frame.d.ts.map +1 -0
  54. package/dist/_shared/w7-frame.js +839 -0
  55. package/dist/_shared/weighted-credit-pool.d.ts +61 -0
  56. package/dist/_shared/weighted-credit-pool.d.ts.map +1 -0
  57. package/dist/_shared/weighted-credit-pool.js +196 -0
  58. package/dist/constants.d.ts +64 -0
  59. package/dist/constants.d.ts.map +1 -0
  60. package/dist/constants.js +264 -0
  61. package/dist/index.d.ts +16 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +13 -0
  64. package/dist/observability/diag-counters.d.ts +236 -0
  65. package/dist/observability/diag-counters.d.ts.map +1 -0
  66. package/dist/observability/diag-counters.js +195 -0
  67. package/dist/observability/heap-estimate.d.ts +225 -0
  68. package/dist/observability/heap-estimate.d.ts.map +1 -0
  69. package/dist/observability/heap-estimate.js +185 -0
  70. package/dist/observability/heavy-alloc-coord.d.ts +93 -0
  71. package/dist/observability/heavy-alloc-coord.d.ts.map +1 -0
  72. package/dist/observability/heavy-alloc-coord.js +181 -0
  73. package/dist/observability/oom-classify.d.ts +138 -0
  74. package/dist/observability/oom-classify.d.ts.map +1 -0
  75. package/dist/observability/oom-classify.js +261 -0
  76. package/dist/observability/oom-discriminator.d.ts +176 -0
  77. package/dist/observability/oom-discriminator.d.ts.map +1 -0
  78. package/dist/observability/oom-discriminator.js +272 -0
  79. package/dist/runtime/assets-loader.d.ts +71 -0
  80. package/dist/runtime/assets-loader.d.ts.map +1 -0
  81. package/dist/runtime/assets-loader.js +139 -0
  82. package/dist/runtime/barrel-detect.d.ts +46 -0
  83. package/dist/runtime/barrel-detect.d.ts.map +1 -0
  84. package/dist/runtime/barrel-detect.js +73 -0
  85. package/dist/runtime/bash/preamble.d.ts +2 -0
  86. package/dist/runtime/bash/preamble.d.ts.map +1 -0
  87. package/dist/runtime/bash/preamble.js +1849 -0
  88. package/dist/runtime/bash/types.d.ts +433 -0
  89. package/dist/runtime/bash/types.d.ts.map +1 -0
  90. package/dist/runtime/bash/types.js +1 -0
  91. package/dist/runtime/bundle-profile.d.ts +14 -0
  92. package/dist/runtime/bundle-profile.d.ts.map +1 -0
  93. package/dist/runtime/bundle-profile.js +20 -0
  94. package/dist/runtime/cirrus-vite-config-rewriter.d.ts +2 -0
  95. package/dist/runtime/cirrus-vite-config-rewriter.d.ts.map +1 -0
  96. package/dist/runtime/cirrus-vite-config-rewriter.js +28 -0
  97. package/dist/runtime/cli-flags.d.ts +2 -0
  98. package/dist/runtime/cli-flags.d.ts.map +1 -0
  99. package/dist/runtime/cli-flags.js +11 -0
  100. package/dist/runtime/comment-strip.d.ts +37 -0
  101. package/dist/runtime/comment-strip.d.ts.map +1 -0
  102. package/dist/runtime/comment-strip.js +74 -0
  103. package/dist/runtime/cpython-preamble.d.ts +32 -0
  104. package/dist/runtime/cpython-preamble.d.ts.map +1 -0
  105. package/dist/runtime/cpython-preamble.js +296 -0
  106. package/dist/runtime/esbuild-service.d.ts +242 -0
  107. package/dist/runtime/esbuild-service.d.ts.map +1 -0
  108. package/dist/runtime/esbuild-service.js +1452 -0
  109. package/dist/runtime/framework-detect.d.ts +70 -0
  110. package/dist/runtime/framework-detect.d.ts.map +1 -0
  111. package/dist/runtime/framework-detect.js +177 -0
  112. package/dist/runtime/import-meta-transform.d.ts +3 -0
  113. package/dist/runtime/import-meta-transform.d.ts.map +1 -0
  114. package/dist/runtime/import-meta-transform.js +15 -0
  115. package/dist/runtime/javascript-ast.d.ts +13 -0
  116. package/dist/runtime/javascript-ast.d.ts.map +1 -0
  117. package/dist/runtime/javascript-ast.js +57 -0
  118. package/dist/runtime/long-running-handle.d.ts +119 -0
  119. package/dist/runtime/long-running-handle.d.ts.map +1 -0
  120. package/dist/runtime/long-running-handle.js +169 -0
  121. package/dist/runtime/module-source-rewriter.d.ts +11 -0
  122. package/dist/runtime/module-source-rewriter.d.ts.map +1 -0
  123. package/dist/runtime/module-source-rewriter.js +61 -0
  124. package/dist/runtime/opentui-wasm-backend.d.ts +160 -0
  125. package/dist/runtime/opentui-wasm-backend.d.ts.map +1 -0
  126. package/dist/runtime/opentui-wasm-backend.js +416 -0
  127. package/dist/runtime/os-contracts.d.ts +436 -0
  128. package/dist/runtime/os-contracts.d.ts.map +1 -0
  129. package/dist/runtime/os-contracts.js +101 -0
  130. package/dist/runtime/port-registry.d.ts +100 -0
  131. package/dist/runtime/port-registry.d.ts.map +1 -0
  132. package/dist/runtime/port-registry.js +265 -0
  133. package/dist/runtime/process-input-routing.d.ts +33 -0
  134. package/dist/runtime/process-input-routing.d.ts.map +1 -0
  135. package/dist/runtime/process-input-routing.js +59 -0
  136. package/dist/runtime/process-input.d.ts +39 -0
  137. package/dist/runtime/process-input.d.ts.map +1 -0
  138. package/dist/runtime/process-input.js +117 -0
  139. package/dist/runtime/process-io-protocol.d.ts +90 -0
  140. package/dist/runtime/process-io-protocol.d.ts.map +1 -0
  141. package/dist/runtime/process-io-protocol.js +81 -0
  142. package/dist/runtime/process-logs.d.ts +352 -0
  143. package/dist/runtime/process-logs.d.ts.map +1 -0
  144. package/dist/runtime/process-logs.js +750 -0
  145. package/dist/runtime/process-table.d.ts +101 -0
  146. package/dist/runtime/process-table.d.ts.map +1 -0
  147. package/dist/runtime/process-table.js +175 -0
  148. package/dist/runtime/project-detect.d.ts +21 -0
  149. package/dist/runtime/project-detect.d.ts.map +1 -0
  150. package/dist/runtime/project-detect.js +46 -0
  151. package/dist/runtime/python-server-adapter.d.ts +33 -0
  152. package/dist/runtime/python-server-adapter.d.ts.map +1 -0
  153. package/dist/runtime/python-server-adapter.js +132 -0
  154. package/dist/runtime/require-resolver.d.ts +44 -0
  155. package/dist/runtime/require-resolver.d.ts.map +1 -0
  156. package/dist/runtime/require-resolver.js +698 -0
  157. package/dist/runtime/router-basename.d.ts +36 -0
  158. package/dist/runtime/router-basename.d.ts.map +1 -0
  159. package/dist/runtime/router-basename.js +310 -0
  160. package/dist/runtime/ruby-green-threads.d.ts +136 -0
  161. package/dist/runtime/ruby-green-threads.d.ts.map +1 -0
  162. package/dist/runtime/ruby-green-threads.js +904 -0
  163. package/dist/runtime/ruby-socket-shim.d.ts +2 -0
  164. package/dist/runtime/ruby-socket-shim.d.ts.map +1 -0
  165. package/dist/runtime/ruby-socket-shim.js +548 -0
  166. package/dist/runtime/session-process-supervisor.d.ts +156 -0
  167. package/dist/runtime/session-process-supervisor.d.ts.map +1 -0
  168. package/dist/runtime/session-process-supervisor.js +238 -0
  169. package/dist/runtime/sqlite-runtime-fs-bridge.d.ts +70 -0
  170. package/dist/runtime/sqlite-runtime-fs-bridge.d.ts.map +1 -0
  171. package/dist/runtime/sqlite-runtime-fs-bridge.js +425 -0
  172. package/dist/runtime/streams.d.ts +13 -0
  173. package/dist/runtime/streams.d.ts.map +1 -0
  174. package/dist/runtime/streams.js +546 -0
  175. package/dist/runtime/undici-shim.d.ts +62 -0
  176. package/dist/runtime/undici-shim.d.ts.map +1 -0
  177. package/dist/runtime/undici-shim.js +516 -0
  178. package/dist/runtime/vfs-manifest.d.ts +63 -0
  179. package/dist/runtime/vfs-manifest.d.ts.map +1 -0
  180. package/dist/runtime/vfs-manifest.js +141 -0
  181. package/dist/runtime/vfs-snapshot.d.ts +75 -0
  182. package/dist/runtime/vfs-snapshot.d.ts.map +1 -0
  183. package/dist/runtime/vfs-snapshot.js +220 -0
  184. package/dist/runtime/virtual-socket-kernel.d.ts +252 -0
  185. package/dist/runtime/virtual-socket-kernel.d.ts.map +1 -0
  186. package/dist/runtime/virtual-socket-kernel.js +1143 -0
  187. package/dist/runtime/vite-config-parser.d.ts +13 -0
  188. package/dist/runtime/vite-config-parser.d.ts.map +1 -0
  189. package/dist/runtime/vite-config-parser.js +258 -0
  190. package/dist/runtime/wasi/types.d.ts +347 -0
  191. package/dist/runtime/wasi/types.d.ts.map +1 -0
  192. package/dist/runtime/wasi/types.js +1 -0
  193. package/dist/runtime/wasi-instance.d.ts +215 -0
  194. package/dist/runtime/wasi-instance.d.ts.map +1 -0
  195. package/dist/runtime/wasi-instance.generated.d.ts +14 -0
  196. package/dist/runtime/wasi-instance.generated.d.ts.map +1 -0
  197. package/dist/runtime/wasi-instance.generated.js +13 -0
  198. package/dist/runtime/wasi-instance.js +179 -0
  199. package/dist/runtime/wasi-threads.d.ts +169 -0
  200. package/dist/runtime/wasi-threads.d.ts.map +1 -0
  201. package/dist/runtime/wasi-threads.js +669 -0
  202. package/dist/runtime/wasm-memory.d.ts +84 -0
  203. package/dist/runtime/wasm-memory.d.ts.map +1 -0
  204. package/dist/runtime/wasm-memory.js +235 -0
  205. package/dist/shell/elevation-commands.d.ts +5 -0
  206. package/dist/shell/elevation-commands.d.ts.map +1 -0
  207. package/dist/shell/elevation-commands.js +109 -0
  208. package/dist/shell/exec-dispatch.d.ts +57 -0
  209. package/dist/shell/exec-dispatch.d.ts.map +1 -0
  210. package/dist/shell/exec-dispatch.js +181 -0
  211. package/dist/shell/features.d.ts +154 -0
  212. package/dist/shell/features.d.ts.map +1 -0
  213. package/dist/shell/features.js +792 -0
  214. package/dist/shell/shell-entrypoints.d.ts +55 -0
  215. package/dist/shell/shell-entrypoints.d.ts.map +1 -0
  216. package/dist/shell/shell-entrypoints.js +230 -0
  217. package/dist/shell/shell-invocation.d.ts +36 -0
  218. package/dist/shell/shell-invocation.d.ts.map +1 -0
  219. package/dist/shell/shell-invocation.js +148 -0
  220. package/dist/shell/unix-accounts.d.ts +27 -0
  221. package/dist/shell/unix-accounts.d.ts.map +1 -0
  222. package/dist/shell/unix-accounts.js +105 -0
  223. package/dist/shell/unix-commands.d.ts +15 -0
  224. package/dist/shell/unix-commands.d.ts.map +1 -0
  225. package/dist/shell/unix-commands.js +4702 -0
  226. package/dist/substrate/lifo/commands/archive/gunzip.d.ts +4 -0
  227. package/dist/substrate/lifo/commands/archive/gunzip.d.ts.map +1 -0
  228. package/dist/substrate/lifo/commands/archive/gunzip.js +58 -0
  229. package/dist/substrate/lifo/commands/archive/gzip.d.ts +4 -0
  230. package/dist/substrate/lifo/commands/archive/gzip.d.ts.map +1 -0
  231. package/dist/substrate/lifo/commands/archive/gzip.js +73 -0
  232. package/dist/substrate/lifo/commands/archive/tar.d.ts +4 -0
  233. package/dist/substrate/lifo/commands/archive/tar.d.ts.map +1 -0
  234. package/dist/substrate/lifo/commands/archive/tar.js +158 -0
  235. package/dist/substrate/lifo/commands/archive/unzip.d.ts +4 -0
  236. package/dist/substrate/lifo/commands/archive/unzip.d.ts.map +1 -0
  237. package/dist/substrate/lifo/commands/archive/unzip.js +114 -0
  238. package/dist/substrate/lifo/commands/archive/zip.d.ts +4 -0
  239. package/dist/substrate/lifo/commands/archive/zip.d.ts.map +1 -0
  240. package/dist/substrate/lifo/commands/archive/zip.js +58 -0
  241. package/dist/substrate/lifo/commands/fs/basename.d.ts +4 -0
  242. package/dist/substrate/lifo/commands/fs/basename.d.ts.map +1 -0
  243. package/dist/substrate/lifo/commands/fs/basename.js +12 -0
  244. package/dist/substrate/lifo/commands/fs/cat.d.ts +4 -0
  245. package/dist/substrate/lifo/commands/fs/cat.d.ts.map +1 -0
  246. package/dist/substrate/lifo/commands/fs/cat.js +52 -0
  247. package/dist/substrate/lifo/commands/fs/chmod.d.ts +25 -0
  248. package/dist/substrate/lifo/commands/fs/chmod.d.ts.map +1 -0
  249. package/dist/substrate/lifo/commands/fs/chmod.js +97 -0
  250. package/dist/substrate/lifo/commands/fs/chown.d.ts +4 -0
  251. package/dist/substrate/lifo/commands/fs/chown.d.ts.map +1 -0
  252. package/dist/substrate/lifo/commands/fs/chown.js +41 -0
  253. package/dist/substrate/lifo/commands/fs/cp.d.ts +4 -0
  254. package/dist/substrate/lifo/commands/fs/cp.d.ts.map +1 -0
  255. package/dist/substrate/lifo/commands/fs/cp.js +29 -0
  256. package/dist/substrate/lifo/commands/fs/df.d.ts +4 -0
  257. package/dist/substrate/lifo/commands/fs/df.d.ts.map +1 -0
  258. package/dist/substrate/lifo/commands/fs/df.js +52 -0
  259. package/dist/substrate/lifo/commands/fs/dirname.d.ts +4 -0
  260. package/dist/substrate/lifo/commands/fs/dirname.d.ts.map +1 -0
  261. package/dist/substrate/lifo/commands/fs/dirname.js +12 -0
  262. package/dist/substrate/lifo/commands/fs/du.d.ts +4 -0
  263. package/dist/substrate/lifo/commands/fs/du.d.ts.map +1 -0
  264. package/dist/substrate/lifo/commands/fs/du.js +104 -0
  265. package/dist/substrate/lifo/commands/fs/file.d.ts +4 -0
  266. package/dist/substrate/lifo/commands/fs/file.d.ts.map +1 -0
  267. package/dist/substrate/lifo/commands/fs/file.js +84 -0
  268. package/dist/substrate/lifo/commands/fs/find.d.ts +4 -0
  269. package/dist/substrate/lifo/commands/fs/find.d.ts.map +1 -0
  270. package/dist/substrate/lifo/commands/fs/find.js +72 -0
  271. package/dist/substrate/lifo/commands/fs/ln.d.ts +4 -0
  272. package/dist/substrate/lifo/commands/fs/ln.d.ts.map +1 -0
  273. package/dist/substrate/lifo/commands/fs/ln.js +15 -0
  274. package/dist/substrate/lifo/commands/fs/ls.d.ts +4 -0
  275. package/dist/substrate/lifo/commands/fs/ls.d.ts.map +1 -0
  276. package/dist/substrate/lifo/commands/fs/ls.js +146 -0
  277. package/dist/substrate/lifo/commands/fs/mkdir.d.ts +4 -0
  278. package/dist/substrate/lifo/commands/fs/mkdir.d.ts.map +1 -0
  279. package/dist/substrate/lifo/commands/fs/mkdir.js +31 -0
  280. package/dist/substrate/lifo/commands/fs/mktemp.d.ts +4 -0
  281. package/dist/substrate/lifo/commands/fs/mktemp.d.ts.map +1 -0
  282. package/dist/substrate/lifo/commands/fs/mktemp.js +48 -0
  283. package/dist/substrate/lifo/commands/fs/mv.d.ts +4 -0
  284. package/dist/substrate/lifo/commands/fs/mv.d.ts.map +1 -0
  285. package/dist/substrate/lifo/commands/fs/mv.js +113 -0
  286. package/dist/substrate/lifo/commands/fs/realpath.d.ts +4 -0
  287. package/dist/substrate/lifo/commands/fs/realpath.d.ts.map +1 -0
  288. package/dist/substrate/lifo/commands/fs/realpath.js +27 -0
  289. package/dist/substrate/lifo/commands/fs/rm.d.ts +4 -0
  290. package/dist/substrate/lifo/commands/fs/rm.d.ts.map +1 -0
  291. package/dist/substrate/lifo/commands/fs/rm.js +48 -0
  292. package/dist/substrate/lifo/commands/fs/rmdir.d.ts +4 -0
  293. package/dist/substrate/lifo/commands/fs/rmdir.d.ts.map +1 -0
  294. package/dist/substrate/lifo/commands/fs/rmdir.js +44 -0
  295. package/dist/substrate/lifo/commands/fs/stat.d.ts +4 -0
  296. package/dist/substrate/lifo/commands/fs/stat.d.ts.map +1 -0
  297. package/dist/substrate/lifo/commands/fs/stat.js +35 -0
  298. package/dist/substrate/lifo/commands/fs/touch.d.ts +4 -0
  299. package/dist/substrate/lifo/commands/fs/touch.d.ts.map +1 -0
  300. package/dist/substrate/lifo/commands/fs/touch.js +26 -0
  301. package/dist/substrate/lifo/commands/fs/tree.d.ts +4 -0
  302. package/dist/substrate/lifo/commands/fs/tree.d.ts.map +1 -0
  303. package/dist/substrate/lifo/commands/fs/tree.js +69 -0
  304. package/dist/substrate/lifo/commands/index.d.ts +3 -0
  305. package/dist/substrate/lifo/commands/index.d.ts.map +1 -0
  306. package/dist/substrate/lifo/commands/index.js +1 -0
  307. package/dist/substrate/lifo/commands/io/dd.d.ts +4 -0
  308. package/dist/substrate/lifo/commands/io/dd.d.ts.map +1 -0
  309. package/dist/substrate/lifo/commands/io/dd.js +256 -0
  310. package/dist/substrate/lifo/commands/io/printf.d.ts +4 -0
  311. package/dist/substrate/lifo/commands/io/printf.d.ts.map +1 -0
  312. package/dist/substrate/lifo/commands/io/printf.js +82 -0
  313. package/dist/substrate/lifo/commands/io/tee.d.ts +4 -0
  314. package/dist/substrate/lifo/commands/io/tee.d.ts.map +1 -0
  315. package/dist/substrate/lifo/commands/io/tee.js +31 -0
  316. package/dist/substrate/lifo/commands/io/xargs.d.ts +4 -0
  317. package/dist/substrate/lifo/commands/io/xargs.d.ts.map +1 -0
  318. package/dist/substrate/lifo/commands/io/xargs.js +44 -0
  319. package/dist/substrate/lifo/commands/io/yes.d.ts +4 -0
  320. package/dist/substrate/lifo/commands/io/yes.d.ts.map +1 -0
  321. package/dist/substrate/lifo/commands/io/yes.js +10 -0
  322. package/dist/substrate/lifo/commands/net/curl.d.ts +6 -0
  323. package/dist/substrate/lifo/commands/net/curl.d.ts.map +1 -0
  324. package/dist/substrate/lifo/commands/net/curl.js +617 -0
  325. package/dist/substrate/lifo/commands/net/dig.d.ts +4 -0
  326. package/dist/substrate/lifo/commands/net/dig.d.ts.map +1 -0
  327. package/dist/substrate/lifo/commands/net/dig.js +77 -0
  328. package/dist/substrate/lifo/commands/net/forward.d.ts +14 -0
  329. package/dist/substrate/lifo/commands/net/forward.d.ts.map +1 -0
  330. package/dist/substrate/lifo/commands/net/forward.js +80 -0
  331. package/dist/substrate/lifo/commands/net/host.d.ts +14 -0
  332. package/dist/substrate/lifo/commands/net/host.d.ts.map +1 -0
  333. package/dist/substrate/lifo/commands/net/host.js +160 -0
  334. package/dist/substrate/lifo/commands/net/ifconfig.d.ts +8 -0
  335. package/dist/substrate/lifo/commands/net/ifconfig.d.ts.map +1 -0
  336. package/dist/substrate/lifo/commands/net/ifconfig.js +120 -0
  337. package/dist/substrate/lifo/commands/net/ip.d.ts +14 -0
  338. package/dist/substrate/lifo/commands/net/ip.d.ts.map +1 -0
  339. package/dist/substrate/lifo/commands/net/ip.js +508 -0
  340. package/dist/substrate/lifo/commands/net/netstat.d.ts +8 -0
  341. package/dist/substrate/lifo/commands/net/netstat.d.ts.map +1 -0
  342. package/dist/substrate/lifo/commands/net/netstat.js +94 -0
  343. package/dist/substrate/lifo/commands/net/ping.d.ts +4 -0
  344. package/dist/substrate/lifo/commands/net/ping.d.ts.map +1 -0
  345. package/dist/substrate/lifo/commands/net/ping.js +64 -0
  346. package/dist/substrate/lifo/commands/net/ports.d.ts +8 -0
  347. package/dist/substrate/lifo/commands/net/ports.d.ts.map +1 -0
  348. package/dist/substrate/lifo/commands/net/ports.js +36 -0
  349. package/dist/substrate/lifo/commands/net/route.d.ts +8 -0
  350. package/dist/substrate/lifo/commands/net/route.d.ts.map +1 -0
  351. package/dist/substrate/lifo/commands/net/route.js +128 -0
  352. package/dist/substrate/lifo/commands/net/tunnel-v2.d.ts +4 -0
  353. package/dist/substrate/lifo/commands/net/tunnel-v2.d.ts.map +1 -0
  354. package/dist/substrate/lifo/commands/net/tunnel-v2.js +141 -0
  355. package/dist/substrate/lifo/commands/net/tunnel.d.ts +6 -0
  356. package/dist/substrate/lifo/commands/net/tunnel.d.ts.map +1 -0
  357. package/dist/substrate/lifo/commands/net/tunnel.js +232 -0
  358. package/dist/substrate/lifo/commands/net/wget.d.ts +4 -0
  359. package/dist/substrate/lifo/commands/net/wget.d.ts.map +1 -0
  360. package/dist/substrate/lifo/commands/net/wget.js +78 -0
  361. package/dist/substrate/lifo/commands/registry.d.ts +15 -0
  362. package/dist/substrate/lifo/commands/registry.d.ts.map +1 -0
  363. package/dist/substrate/lifo/commands/registry.js +120 -0
  364. package/dist/substrate/lifo/commands/signal.d.ts +12 -0
  365. package/dist/substrate/lifo/commands/signal.d.ts.map +1 -0
  366. package/dist/substrate/lifo/commands/signal.js +47 -0
  367. package/dist/substrate/lifo/commands/system/bc.d.ts +4 -0
  368. package/dist/substrate/lifo/commands/system/bc.d.ts.map +1 -0
  369. package/dist/substrate/lifo/commands/system/bc.js +243 -0
  370. package/dist/substrate/lifo/commands/system/cal.d.ts +4 -0
  371. package/dist/substrate/lifo/commands/system/cal.d.ts.map +1 -0
  372. package/dist/substrate/lifo/commands/system/cal.js +81 -0
  373. package/dist/substrate/lifo/commands/system/date.d.ts +4 -0
  374. package/dist/substrate/lifo/commands/system/date.d.ts.map +1 -0
  375. package/dist/substrate/lifo/commands/system/date.js +79 -0
  376. package/dist/substrate/lifo/commands/system/env.d.ts +4 -0
  377. package/dist/substrate/lifo/commands/system/env.d.ts.map +1 -0
  378. package/dist/substrate/lifo/commands/system/env.js +7 -0
  379. package/dist/substrate/lifo/commands/system/fastfetch.d.ts +4 -0
  380. package/dist/substrate/lifo/commands/system/fastfetch.d.ts.map +1 -0
  381. package/dist/substrate/lifo/commands/system/fastfetch.js +385 -0
  382. package/dist/substrate/lifo/commands/system/free.d.ts +4 -0
  383. package/dist/substrate/lifo/commands/system/free.d.ts.map +1 -0
  384. package/dist/substrate/lifo/commands/system/free.js +36 -0
  385. package/dist/substrate/lifo/commands/system/help.d.ts +4 -0
  386. package/dist/substrate/lifo/commands/system/help.d.ts.map +1 -0
  387. package/dist/substrate/lifo/commands/system/help.js +46 -0
  388. package/dist/substrate/lifo/commands/system/hostname.d.ts +4 -0
  389. package/dist/substrate/lifo/commands/system/hostname.d.ts.map +1 -0
  390. package/dist/substrate/lifo/commands/system/hostname.js +6 -0
  391. package/dist/substrate/lifo/commands/system/kill.d.ts +4 -0
  392. package/dist/substrate/lifo/commands/system/kill.d.ts.map +1 -0
  393. package/dist/substrate/lifo/commands/system/kill.js +76 -0
  394. package/dist/substrate/lifo/commands/system/lifo.d.ts +41 -0
  395. package/dist/substrate/lifo/commands/system/lifo.d.ts.map +1 -0
  396. package/dist/substrate/lifo/commands/system/lifo.js +446 -0
  397. package/dist/substrate/lifo/commands/system/logout.d.ts +5 -0
  398. package/dist/substrate/lifo/commands/system/logout.d.ts.map +1 -0
  399. package/dist/substrate/lifo/commands/system/logout.js +15 -0
  400. package/dist/substrate/lifo/commands/system/man.d.ts +4 -0
  401. package/dist/substrate/lifo/commands/system/man.d.ts.map +1 -0
  402. package/dist/substrate/lifo/commands/system/man.js +144 -0
  403. package/dist/substrate/lifo/commands/system/node.d.ts +6 -0
  404. package/dist/substrate/lifo/commands/system/node.d.ts.map +1 -0
  405. package/dist/substrate/lifo/commands/system/node.js +1241 -0
  406. package/dist/substrate/lifo/commands/system/npm.d.ts +26 -0
  407. package/dist/substrate/lifo/commands/system/npm.d.ts.map +1 -0
  408. package/dist/substrate/lifo/commands/system/npm.js +934 -0
  409. package/dist/substrate/lifo/commands/system/pkg.d.ts +4 -0
  410. package/dist/substrate/lifo/commands/system/pkg.d.ts.map +1 -0
  411. package/dist/substrate/lifo/commands/system/pkg.js +97 -0
  412. package/dist/substrate/lifo/commands/system/ps.d.ts +5 -0
  413. package/dist/substrate/lifo/commands/system/ps.d.ts.map +1 -0
  414. package/dist/substrate/lifo/commands/system/ps.js +35 -0
  415. package/dist/substrate/lifo/commands/system/registry-schemas.d.ts +44 -0
  416. package/dist/substrate/lifo/commands/system/registry-schemas.d.ts.map +1 -0
  417. package/dist/substrate/lifo/commands/system/registry-schemas.js +28 -0
  418. package/dist/substrate/lifo/commands/system/sha256sum.d.ts +4 -0
  419. package/dist/substrate/lifo/commands/system/sha256sum.d.ts.map +1 -0
  420. package/dist/substrate/lifo/commands/system/sha256sum.js +86 -0
  421. package/dist/substrate/lifo/commands/system/sl.d.ts +4 -0
  422. package/dist/substrate/lifo/commands/system/sl.d.ts.map +1 -0
  423. package/dist/substrate/lifo/commands/system/sl.js +204 -0
  424. package/dist/substrate/lifo/commands/system/sleep.d.ts +4 -0
  425. package/dist/substrate/lifo/commands/system/sleep.d.ts.map +1 -0
  426. package/dist/substrate/lifo/commands/system/sleep.js +27 -0
  427. package/dist/substrate/lifo/commands/system/stty.d.ts +4 -0
  428. package/dist/substrate/lifo/commands/system/stty.d.ts.map +1 -0
  429. package/dist/substrate/lifo/commands/system/stty.js +61 -0
  430. package/dist/substrate/lifo/commands/system/systemctl.d.ts +4 -0
  431. package/dist/substrate/lifo/commands/system/systemctl.d.ts.map +1 -0
  432. package/dist/substrate/lifo/commands/system/systemctl.js +164 -0
  433. package/dist/substrate/lifo/commands/system/top.d.ts +4 -0
  434. package/dist/substrate/lifo/commands/system/top.d.ts.map +1 -0
  435. package/dist/substrate/lifo/commands/system/top.js +38 -0
  436. package/dist/substrate/lifo/commands/system/uname.d.ts +4 -0
  437. package/dist/substrate/lifo/commands/system/uname.d.ts.map +1 -0
  438. package/dist/substrate/lifo/commands/system/uname.js +55 -0
  439. package/dist/substrate/lifo/commands/system/uptime.d.ts +4 -0
  440. package/dist/substrate/lifo/commands/system/uptime.d.ts.map +1 -0
  441. package/dist/substrate/lifo/commands/system/uptime.js +16 -0
  442. package/dist/substrate/lifo/commands/system/watch.d.ts +4 -0
  443. package/dist/substrate/lifo/commands/system/watch.d.ts.map +1 -0
  444. package/dist/substrate/lifo/commands/system/watch.js +53 -0
  445. package/dist/substrate/lifo/commands/system/which.d.ts +4 -0
  446. package/dist/substrate/lifo/commands/system/which.d.ts.map +1 -0
  447. package/dist/substrate/lifo/commands/system/which.js +45 -0
  448. package/dist/substrate/lifo/commands/system/whoami.d.ts +4 -0
  449. package/dist/substrate/lifo/commands/system/whoami.d.ts.map +1 -0
  450. package/dist/substrate/lifo/commands/system/whoami.js +6 -0
  451. package/dist/substrate/lifo/commands/text/awk.d.ts +4 -0
  452. package/dist/substrate/lifo/commands/text/awk.d.ts.map +1 -0
  453. package/dist/substrate/lifo/commands/text/awk.js +200 -0
  454. package/dist/substrate/lifo/commands/text/base64.d.ts +4 -0
  455. package/dist/substrate/lifo/commands/text/base64.d.ts.map +1 -0
  456. package/dist/substrate/lifo/commands/text/base64.js +102 -0
  457. package/dist/substrate/lifo/commands/text/cut.d.ts +4 -0
  458. package/dist/substrate/lifo/commands/text/cut.d.ts.map +1 -0
  459. package/dist/substrate/lifo/commands/text/cut.js +91 -0
  460. package/dist/substrate/lifo/commands/text/diff.d.ts +4 -0
  461. package/dist/substrate/lifo/commands/text/diff.d.ts.map +1 -0
  462. package/dist/substrate/lifo/commands/text/diff.js +292 -0
  463. package/dist/substrate/lifo/commands/text/grep.d.ts +4 -0
  464. package/dist/substrate/lifo/commands/text/grep.d.ts.map +1 -0
  465. package/dist/substrate/lifo/commands/text/grep.js +189 -0
  466. package/dist/substrate/lifo/commands/text/head.d.ts +4 -0
  467. package/dist/substrate/lifo/commands/text/head.d.ts.map +1 -0
  468. package/dist/substrate/lifo/commands/text/head.js +111 -0
  469. package/dist/substrate/lifo/commands/text/less.d.ts +4 -0
  470. package/dist/substrate/lifo/commands/text/less.d.ts.map +1 -0
  471. package/dist/substrate/lifo/commands/text/less.js +335 -0
  472. package/dist/substrate/lifo/commands/text/nano.d.ts +4 -0
  473. package/dist/substrate/lifo/commands/text/nano.d.ts.map +1 -0
  474. package/dist/substrate/lifo/commands/text/nano.js +510 -0
  475. package/dist/substrate/lifo/commands/text/nl.d.ts +4 -0
  476. package/dist/substrate/lifo/commands/text/nl.d.ts.map +1 -0
  477. package/dist/substrate/lifo/commands/text/nl.js +64 -0
  478. package/dist/substrate/lifo/commands/text/rev.d.ts +4 -0
  479. package/dist/substrate/lifo/commands/text/rev.d.ts.map +1 -0
  480. package/dist/substrate/lifo/commands/text/rev.js +41 -0
  481. package/dist/substrate/lifo/commands/text/sed.d.ts +21 -0
  482. package/dist/substrate/lifo/commands/text/sed.d.ts.map +1 -0
  483. package/dist/substrate/lifo/commands/text/sed.js +248 -0
  484. package/dist/substrate/lifo/commands/text/seq.d.ts +4 -0
  485. package/dist/substrate/lifo/commands/text/seq.d.ts.map +1 -0
  486. package/dist/substrate/lifo/commands/text/seq.js +69 -0
  487. package/dist/substrate/lifo/commands/text/sort.d.ts +4 -0
  488. package/dist/substrate/lifo/commands/text/sort.d.ts.map +1 -0
  489. package/dist/substrate/lifo/commands/text/sort.js +90 -0
  490. package/dist/substrate/lifo/commands/text/strings.d.ts +4 -0
  491. package/dist/substrate/lifo/commands/text/strings.d.ts.map +1 -0
  492. package/dist/substrate/lifo/commands/text/strings.js +69 -0
  493. package/dist/substrate/lifo/commands/text/tac.d.ts +4 -0
  494. package/dist/substrate/lifo/commands/text/tac.d.ts.map +1 -0
  495. package/dist/substrate/lifo/commands/text/tac.js +32 -0
  496. package/dist/substrate/lifo/commands/text/tail.d.ts +4 -0
  497. package/dist/substrate/lifo/commands/text/tail.d.ts.map +1 -0
  498. package/dist/substrate/lifo/commands/text/tail.js +64 -0
  499. package/dist/substrate/lifo/commands/text/tr.d.ts +4 -0
  500. package/dist/substrate/lifo/commands/text/tr.d.ts.map +1 -0
  501. package/dist/substrate/lifo/commands/text/tr.js +180 -0
  502. package/dist/substrate/lifo/commands/text/uniq.d.ts +4 -0
  503. package/dist/substrate/lifo/commands/text/uniq.d.ts.map +1 -0
  504. package/dist/substrate/lifo/commands/text/uniq.js +82 -0
  505. package/dist/substrate/lifo/commands/text/wc.d.ts +4 -0
  506. package/dist/substrate/lifo/commands/text/wc.d.ts.map +1 -0
  507. package/dist/substrate/lifo/commands/text/wc.js +107 -0
  508. package/dist/substrate/lifo/commands/types.d.ts +49 -0
  509. package/dist/substrate/lifo/commands/types.d.ts.map +1 -0
  510. package/dist/substrate/lifo/commands/types.js +1 -0
  511. package/dist/substrate/lifo/index.d.ts +67 -0
  512. package/dist/substrate/lifo/index.d.ts.map +1 -0
  513. package/dist/substrate/lifo/index.js +66 -0
  514. package/dist/substrate/lifo/kernel/ServiceManager.d.ts +51 -0
  515. package/dist/substrate/lifo/kernel/ServiceManager.d.ts.map +1 -0
  516. package/dist/substrate/lifo/kernel/ServiceManager.js +302 -0
  517. package/dist/substrate/lifo/kernel/index.d.ts +40 -0
  518. package/dist/substrate/lifo/kernel/index.d.ts.map +1 -0
  519. package/dist/substrate/lifo/kernel/index.js +170 -0
  520. package/dist/substrate/lifo/kernel/network/Bridge.d.ts +110 -0
  521. package/dist/substrate/lifo/kernel/network/Bridge.d.ts.map +1 -0
  522. package/dist/substrate/lifo/kernel/network/Bridge.js +278 -0
  523. package/dist/substrate/lifo/kernel/network/DNSResolver.d.ts +50 -0
  524. package/dist/substrate/lifo/kernel/network/DNSResolver.d.ts.map +1 -0
  525. package/dist/substrate/lifo/kernel/network/DNSResolver.js +135 -0
  526. package/dist/substrate/lifo/kernel/network/NetworkInterface.d.ts +83 -0
  527. package/dist/substrate/lifo/kernel/network/NetworkInterface.d.ts.map +1 -0
  528. package/dist/substrate/lifo/kernel/network/NetworkInterface.js +183 -0
  529. package/dist/substrate/lifo/kernel/network/NetworkNamespace.d.ts +98 -0
  530. package/dist/substrate/lifo/kernel/network/NetworkNamespace.d.ts.map +1 -0
  531. package/dist/substrate/lifo/kernel/network/NetworkNamespace.js +149 -0
  532. package/dist/substrate/lifo/kernel/network/NetworkStack.d.ts +178 -0
  533. package/dist/substrate/lifo/kernel/network/NetworkStack.d.ts.map +1 -0
  534. package/dist/substrate/lifo/kernel/network/NetworkStack.js +460 -0
  535. package/dist/substrate/lifo/kernel/network/PortBridge.d.ts +44 -0
  536. package/dist/substrate/lifo/kernel/network/PortBridge.d.ts.map +1 -0
  537. package/dist/substrate/lifo/kernel/network/PortBridge.js +158 -0
  538. package/dist/substrate/lifo/kernel/network/RoutingTable.d.ts +55 -0
  539. package/dist/substrate/lifo/kernel/network/RoutingTable.d.ts.map +1 -0
  540. package/dist/substrate/lifo/kernel/network/RoutingTable.js +167 -0
  541. package/dist/substrate/lifo/kernel/network/Socket.d.ts +65 -0
  542. package/dist/substrate/lifo/kernel/network/Socket.d.ts.map +1 -0
  543. package/dist/substrate/lifo/kernel/network/Socket.js +201 -0
  544. package/dist/substrate/lifo/kernel/network/index.d.ts +11 -0
  545. package/dist/substrate/lifo/kernel/network/index.d.ts.map +1 -0
  546. package/dist/substrate/lifo/kernel/network/index.js +9 -0
  547. package/dist/substrate/lifo/kernel/network/tunnel/BaseTunnel.d.ts +55 -0
  548. package/dist/substrate/lifo/kernel/network/tunnel/BaseTunnel.d.ts.map +1 -0
  549. package/dist/substrate/lifo/kernel/network/tunnel/BaseTunnel.js +88 -0
  550. package/dist/substrate/lifo/kernel/network/tunnel/VETHPair.d.ts +71 -0
  551. package/dist/substrate/lifo/kernel/network/tunnel/VETHPair.d.ts.map +1 -0
  552. package/dist/substrate/lifo/kernel/network/tunnel/VETHPair.js +191 -0
  553. package/dist/substrate/lifo/kernel/network/tunnel/WebSocketTunnel.d.ts +89 -0
  554. package/dist/substrate/lifo/kernel/network/tunnel/WebSocketTunnel.d.ts.map +1 -0
  555. package/dist/substrate/lifo/kernel/network/tunnel/WebSocketTunnel.js +324 -0
  556. package/dist/substrate/lifo/kernel/network/types.d.ts +159 -0
  557. package/dist/substrate/lifo/kernel/network/types.d.ts.map +1 -0
  558. package/dist/substrate/lifo/kernel/network/types.js +5 -0
  559. package/dist/substrate/lifo/kernel/persistence/PersistenceManager.d.ts +12 -0
  560. package/dist/substrate/lifo/kernel/persistence/PersistenceManager.d.ts.map +1 -0
  561. package/dist/substrate/lifo/kernel/persistence/PersistenceManager.js +47 -0
  562. package/dist/substrate/lifo/kernel/persistence/backends.d.ts +15 -0
  563. package/dist/substrate/lifo/kernel/persistence/backends.d.ts.map +1 -0
  564. package/dist/substrate/lifo/kernel/persistence/backends.js +18 -0
  565. package/dist/substrate/lifo/kernel/persistence/index.d.ts +6 -0
  566. package/dist/substrate/lifo/kernel/persistence/index.d.ts.map +1 -0
  567. package/dist/substrate/lifo/kernel/persistence/index.js +3 -0
  568. package/dist/substrate/lifo/kernel/persistence/serializer.d.ts +21 -0
  569. package/dist/substrate/lifo/kernel/persistence/serializer.d.ts.map +1 -0
  570. package/dist/substrate/lifo/kernel/persistence/serializer.js +99 -0
  571. package/dist/substrate/lifo/kernel/samples.d.ts +3 -0
  572. package/dist/substrate/lifo/kernel/samples.d.ts.map +1 -0
  573. package/dist/substrate/lifo/kernel/samples.js +930 -0
  574. package/dist/substrate/lifo/kernel/storage/BlobStore.d.ts +22 -0
  575. package/dist/substrate/lifo/kernel/storage/BlobStore.d.ts.map +1 -0
  576. package/dist/substrate/lifo/kernel/storage/BlobStore.js +84 -0
  577. package/dist/substrate/lifo/kernel/storage/ContentStore.d.ts +54 -0
  578. package/dist/substrate/lifo/kernel/storage/ContentStore.d.ts.map +1 -0
  579. package/dist/substrate/lifo/kernel/storage/ContentStore.js +120 -0
  580. package/dist/substrate/lifo/kernel/storage/index.d.ts +6 -0
  581. package/dist/substrate/lifo/kernel/storage/index.d.ts.map +1 -0
  582. package/dist/substrate/lifo/kernel/storage/index.js +3 -0
  583. package/dist/substrate/lifo/kernel/unit-parser.d.ts +22 -0
  584. package/dist/substrate/lifo/kernel/unit-parser.d.ts.map +1 -0
  585. package/dist/substrate/lifo/kernel/unit-parser.js +80 -0
  586. package/dist/substrate/lifo/kernel/vfs/VFS.d.ts +99 -0
  587. package/dist/substrate/lifo/kernel/vfs/VFS.d.ts.map +1 -0
  588. package/dist/substrate/lifo/kernel/vfs/VFS.js +679 -0
  589. package/dist/substrate/lifo/kernel/vfs/index.d.ts +8 -0
  590. package/dist/substrate/lifo/kernel/vfs/index.d.ts.map +1 -0
  591. package/dist/substrate/lifo/kernel/vfs/index.js +5 -0
  592. package/dist/substrate/lifo/kernel/vfs/providers/DevProvider.d.ts +21 -0
  593. package/dist/substrate/lifo/kernel/vfs/providers/DevProvider.d.ts.map +1 -0
  594. package/dist/substrate/lifo/kernel/vfs/providers/DevProvider.js +137 -0
  595. package/dist/substrate/lifo/kernel/vfs/providers/NativeFsProvider.d.ts +63 -0
  596. package/dist/substrate/lifo/kernel/vfs/providers/NativeFsProvider.d.ts.map +1 -0
  597. package/dist/substrate/lifo/kernel/vfs/providers/NativeFsProvider.js +175 -0
  598. package/dist/substrate/lifo/kernel/vfs/providers/ProcProvider.d.ts +14 -0
  599. package/dist/substrate/lifo/kernel/vfs/providers/ProcProvider.d.ts.map +1 -0
  600. package/dist/substrate/lifo/kernel/vfs/providers/ProcProvider.js +126 -0
  601. package/dist/substrate/lifo/kernel/vfs/types.d.ts +117 -0
  602. package/dist/substrate/lifo/kernel/vfs/types.d.ts.map +1 -0
  603. package/dist/substrate/lifo/kernel/vfs/types.js +42 -0
  604. package/dist/substrate/lifo/node-compat/buffer.d.ts +44 -0
  605. package/dist/substrate/lifo/node-compat/buffer.d.ts.map +1 -0
  606. package/dist/substrate/lifo/node-compat/buffer.js +331 -0
  607. package/dist/substrate/lifo/node-compat/child_process.d.ts +10 -0
  608. package/dist/substrate/lifo/node-compat/child_process.d.ts.map +1 -0
  609. package/dist/substrate/lifo/node-compat/child_process.js +42 -0
  610. package/dist/substrate/lifo/node-compat/console.d.ts +21 -0
  611. package/dist/substrate/lifo/node-compat/console.d.ts.map +1 -0
  612. package/dist/substrate/lifo/node-compat/console.js +68 -0
  613. package/dist/substrate/lifo/node-compat/crypto.d.ts +24 -0
  614. package/dist/substrate/lifo/node-compat/crypto.d.ts.map +1 -0
  615. package/dist/substrate/lifo/node-compat/crypto.js +216 -0
  616. package/dist/substrate/lifo/node-compat/dns.d.ts +117 -0
  617. package/dist/substrate/lifo/node-compat/dns.d.ts.map +1 -0
  618. package/dist/substrate/lifo/node-compat/dns.js +144 -0
  619. package/dist/substrate/lifo/node-compat/esbuild.d.ts +10 -0
  620. package/dist/substrate/lifo/node-compat/esbuild.d.ts.map +1 -0
  621. package/dist/substrate/lifo/node-compat/esbuild.js +70 -0
  622. package/dist/substrate/lifo/node-compat/events.d.ts +19 -0
  623. package/dist/substrate/lifo/node-compat/events.d.ts.map +1 -0
  624. package/dist/substrate/lifo/node-compat/events.js +83 -0
  625. package/dist/substrate/lifo/node-compat/fs.d.ts +195 -0
  626. package/dist/substrate/lifo/node-compat/fs.d.ts.map +1 -0
  627. package/dist/substrate/lifo/node-compat/fs.js +624 -0
  628. package/dist/substrate/lifo/node-compat/http.d.ts +133 -0
  629. package/dist/substrate/lifo/node-compat/http.d.ts.map +1 -0
  630. package/dist/substrate/lifo/node-compat/http.js +452 -0
  631. package/dist/substrate/lifo/node-compat/index.d.ts +20 -0
  632. package/dist/substrate/lifo/node-compat/index.d.ts.map +1 -0
  633. package/dist/substrate/lifo/node-compat/index.js +291 -0
  634. package/dist/substrate/lifo/node-compat/module.d.ts +55 -0
  635. package/dist/substrate/lifo/node-compat/module.d.ts.map +1 -0
  636. package/dist/substrate/lifo/node-compat/module.js +124 -0
  637. package/dist/substrate/lifo/node-compat/os.d.ts +39 -0
  638. package/dist/substrate/lifo/node-compat/os.d.ts.map +1 -0
  639. package/dist/substrate/lifo/node-compat/os.js +45 -0
  640. package/dist/substrate/lifo/node-compat/path.d.ts +86 -0
  641. package/dist/substrate/lifo/node-compat/path.d.ts.map +1 -0
  642. package/dist/substrate/lifo/node-compat/path.js +49 -0
  643. package/dist/substrate/lifo/node-compat/process.d.ts +127 -0
  644. package/dist/substrate/lifo/node-compat/process.d.ts.map +1 -0
  645. package/dist/substrate/lifo/node-compat/process.js +173 -0
  646. package/dist/substrate/lifo/node-compat/readline.d.ts +85 -0
  647. package/dist/substrate/lifo/node-compat/readline.d.ts.map +1 -0
  648. package/dist/substrate/lifo/node-compat/readline.js +205 -0
  649. package/dist/substrate/lifo/node-compat/rimraf.d.ts +30 -0
  650. package/dist/substrate/lifo/node-compat/rimraf.d.ts.map +1 -0
  651. package/dist/substrate/lifo/node-compat/rimraf.js +63 -0
  652. package/dist/substrate/lifo/node-compat/stream.d.ts +36 -0
  653. package/dist/substrate/lifo/node-compat/stream.d.ts.map +1 -0
  654. package/dist/substrate/lifo/node-compat/stream.js +90 -0
  655. package/dist/substrate/lifo/node-compat/string_decoder.d.ts +11 -0
  656. package/dist/substrate/lifo/node-compat/string_decoder.d.ts.map +1 -0
  657. package/dist/substrate/lifo/node-compat/string_decoder.js +23 -0
  658. package/dist/substrate/lifo/node-compat/timers.d.ts +16 -0
  659. package/dist/substrate/lifo/node-compat/timers.d.ts.map +1 -0
  660. package/dist/substrate/lifo/node-compat/timers.js +18 -0
  661. package/dist/substrate/lifo/node-compat/tty.d.ts +32 -0
  662. package/dist/substrate/lifo/node-compat/tty.d.ts.map +1 -0
  663. package/dist/substrate/lifo/node-compat/tty.js +76 -0
  664. package/dist/substrate/lifo/node-compat/url.d.ts +37 -0
  665. package/dist/substrate/lifo/node-compat/url.d.ts.map +1 -0
  666. package/dist/substrate/lifo/node-compat/url.js +65 -0
  667. package/dist/substrate/lifo/node-compat/util.d.ts +42 -0
  668. package/dist/substrate/lifo/node-compat/util.d.ts.map +1 -0
  669. package/dist/substrate/lifo/node-compat/util.js +132 -0
  670. package/dist/substrate/lifo/node-compat/zlib.d.ts +66 -0
  671. package/dist/substrate/lifo/node-compat/zlib.d.ts.map +1 -0
  672. package/dist/substrate/lifo/node-compat/zlib.js +80 -0
  673. package/dist/substrate/lifo/pkg/PackageManager.d.ts +19 -0
  674. package/dist/substrate/lifo/pkg/PackageManager.d.ts.map +1 -0
  675. package/dist/substrate/lifo/pkg/PackageManager.js +97 -0
  676. package/dist/substrate/lifo/pkg/lifo-dev.d.ts +38 -0
  677. package/dist/substrate/lifo/pkg/lifo-dev.d.ts.map +1 -0
  678. package/dist/substrate/lifo/pkg/lifo-dev.js +98 -0
  679. package/dist/substrate/lifo/pkg/lifo-runtime.d.ts +44 -0
  680. package/dist/substrate/lifo/pkg/lifo-runtime.d.ts.map +1 -0
  681. package/dist/substrate/lifo/pkg/lifo-runtime.js +372 -0
  682. package/dist/substrate/lifo/pkg/loader.d.ts +4 -0
  683. package/dist/substrate/lifo/pkg/loader.d.ts.map +1 -0
  684. package/dist/substrate/lifo/pkg/loader.js +24 -0
  685. package/dist/substrate/lifo/sandbox/HeadlessTerminal.d.ts +18 -0
  686. package/dist/substrate/lifo/sandbox/HeadlessTerminal.d.ts.map +1 -0
  687. package/dist/substrate/lifo/sandbox/HeadlessTerminal.js +28 -0
  688. package/dist/substrate/lifo/sandbox/Sandbox.d.ts +59 -0
  689. package/dist/substrate/lifo/sandbox/Sandbox.d.ts.map +1 -0
  690. package/dist/substrate/lifo/sandbox/Sandbox.js +234 -0
  691. package/dist/substrate/lifo/sandbox/SandboxCommands.d.ts +18 -0
  692. package/dist/substrate/lifo/sandbox/SandboxCommands.d.ts.map +1 -0
  693. package/dist/substrate/lifo/sandbox/SandboxCommands.js +64 -0
  694. package/dist/substrate/lifo/sandbox/SandboxFs.d.ts +43 -0
  695. package/dist/substrate/lifo/sandbox/SandboxFs.d.ts.map +1 -0
  696. package/dist/substrate/lifo/sandbox/SandboxFs.js +136 -0
  697. package/dist/substrate/lifo/sandbox/index.d.ts +3 -0
  698. package/dist/substrate/lifo/sandbox/index.d.ts.map +1 -0
  699. package/dist/substrate/lifo/sandbox/index.js +1 -0
  700. package/dist/substrate/lifo/sandbox/types.d.ts +116 -0
  701. package/dist/substrate/lifo/sandbox/types.d.ts.map +1 -0
  702. package/dist/substrate/lifo/sandbox/types.js +1 -0
  703. package/dist/substrate/lifo/shell/ProcessRegistry.d.ts +142 -0
  704. package/dist/substrate/lifo/shell/ProcessRegistry.d.ts.map +1 -0
  705. package/dist/substrate/lifo/shell/ProcessRegistry.js +256 -0
  706. package/dist/substrate/lifo/shell/Shell.d.ts +170 -0
  707. package/dist/substrate/lifo/shell/Shell.d.ts.map +1 -0
  708. package/dist/substrate/lifo/shell/Shell.js +1863 -0
  709. package/dist/substrate/lifo/shell/completer.d.ts +19 -0
  710. package/dist/substrate/lifo/shell/completer.d.ts.map +1 -0
  711. package/dist/substrate/lifo/shell/completer.js +164 -0
  712. package/dist/substrate/lifo/shell/default-shell.d.ts +9 -0
  713. package/dist/substrate/lifo/shell/default-shell.d.ts.map +1 -0
  714. package/dist/substrate/lifo/shell/default-shell.js +53 -0
  715. package/dist/substrate/lifo/shell/expander.d.ts +48 -0
  716. package/dist/substrate/lifo/shell/expander.d.ts.map +1 -0
  717. package/dist/substrate/lifo/shell/expander.js +1204 -0
  718. package/dist/substrate/lifo/shell/history.d.ts +22 -0
  719. package/dist/substrate/lifo/shell/history.d.ts.map +1 -0
  720. package/dist/substrate/lifo/shell/history.js +121 -0
  721. package/dist/substrate/lifo/shell/interpreter.d.ts +257 -0
  722. package/dist/substrate/lifo/shell/interpreter.d.ts.map +1 -0
  723. package/dist/substrate/lifo/shell/interpreter.js +1490 -0
  724. package/dist/substrate/lifo/shell/jobs.d.ts +21 -0
  725. package/dist/substrate/lifo/shell/jobs.d.ts.map +1 -0
  726. package/dist/substrate/lifo/shell/jobs.js +48 -0
  727. package/dist/substrate/lifo/shell/lexer.d.ts +13 -0
  728. package/dist/substrate/lifo/shell/lexer.d.ts.map +1 -0
  729. package/dist/substrate/lifo/shell/lexer.js +614 -0
  730. package/dist/substrate/lifo/shell/parser.d.ts +7 -0
  731. package/dist/substrate/lifo/shell/parser.d.ts.map +1 -0
  732. package/dist/substrate/lifo/shell/parser.js +573 -0
  733. package/dist/substrate/lifo/shell/pipe.d.ts +15 -0
  734. package/dist/substrate/lifo/shell/pipe.d.ts.map +1 -0
  735. package/dist/substrate/lifo/shell/pipe.js +86 -0
  736. package/dist/substrate/lifo/shell/signals.d.ts +11 -0
  737. package/dist/substrate/lifo/shell/signals.d.ts.map +1 -0
  738. package/dist/substrate/lifo/shell/signals.js +57 -0
  739. package/dist/substrate/lifo/shell/terminal-stdin.d.ts +28 -0
  740. package/dist/substrate/lifo/shell/terminal-stdin.d.ts.map +1 -0
  741. package/dist/substrate/lifo/shell/terminal-stdin.js +100 -0
  742. package/dist/substrate/lifo/shell/test-builtin.d.ts +16 -0
  743. package/dist/substrate/lifo/shell/test-builtin.d.ts.map +1 -0
  744. package/dist/substrate/lifo/shell/test-builtin.js +237 -0
  745. package/dist/substrate/lifo/shell/types.d.ts +140 -0
  746. package/dist/substrate/lifo/shell/types.d.ts.map +1 -0
  747. package/dist/substrate/lifo/shell/types.js +25 -0
  748. package/dist/substrate/lifo/terminal/ITerminal.d.ts +10 -0
  749. package/dist/substrate/lifo/terminal/ITerminal.d.ts.map +1 -0
  750. package/dist/substrate/lifo/terminal/ITerminal.js +1 -0
  751. package/dist/substrate/lifo/utils/archive.d.ts +28 -0
  752. package/dist/substrate/lifo/utils/archive.d.ts.map +1 -0
  753. package/dist/substrate/lifo/utils/archive.js +323 -0
  754. package/dist/substrate/lifo/utils/args.d.ts +18 -0
  755. package/dist/substrate/lifo/utils/args.d.ts.map +1 -0
  756. package/dist/substrate/lifo/utils/args.js +73 -0
  757. package/dist/substrate/lifo/utils/colors.d.ts +27 -0
  758. package/dist/substrate/lifo/utils/colors.d.ts.map +1 -0
  759. package/dist/substrate/lifo/utils/colors.js +26 -0
  760. package/dist/substrate/lifo/utils/encoding.d.ts +4 -0
  761. package/dist/substrate/lifo/utils/encoding.d.ts.map +1 -0
  762. package/dist/substrate/lifo/utils/encoding.js +18 -0
  763. package/dist/substrate/lifo/utils/glob.d.ts +12 -0
  764. package/dist/substrate/lifo/utils/glob.d.ts.map +1 -0
  765. package/dist/substrate/lifo/utils/glob.js +150 -0
  766. package/dist/substrate/lifo/utils/mime.d.ts +4 -0
  767. package/dist/substrate/lifo/utils/mime.d.ts.map +1 -0
  768. package/dist/substrate/lifo/utils/mime.js +107 -0
  769. package/dist/substrate/lifo/utils/path.d.ts +12 -0
  770. package/dist/substrate/lifo/utils/path.d.ts.map +1 -0
  771. package/dist/substrate/lifo/utils/path.js +82 -0
  772. package/dist/vfs/events.d.ts +51 -0
  773. package/dist/vfs/events.d.ts.map +1 -0
  774. package/dist/vfs/events.js +127 -0
  775. package/dist/vfs/path.d.ts +46 -0
  776. package/dist/vfs/path.d.ts.map +1 -0
  777. package/dist/vfs/path.js +69 -0
  778. package/dist/vfs/seed-project.d.ts +62 -0
  779. package/dist/vfs/seed-project.d.ts.map +1 -0
  780. package/dist/vfs/seed-project.js +1054 -0
  781. package/dist/vfs/sqlite-vfs.d.ts +821 -0
  782. package/dist/vfs/sqlite-vfs.d.ts.map +1 -0
  783. package/dist/vfs/sqlite-vfs.js +4135 -0
  784. package/dist/vfs/symlink-registry.d.ts +60 -0
  785. package/dist/vfs/symlink-registry.d.ts.map +1 -0
  786. package/dist/vfs/symlink-registry.js +162 -0
  787. package/dist/workspace/nimbus-workspace.d.ts +94 -0
  788. package/dist/workspace/nimbus-workspace.d.ts.map +1 -0
  789. package/dist/workspace/nimbus-workspace.js +167 -0
  790. package/package.json +69 -0
  791. package/src/_shared/ai-egress.ts +91 -0
  792. package/src/_shared/byte-stream.ts +97 -0
  793. package/src/_shared/bytes.ts +19 -0
  794. package/src/_shared/cache-stats.ts +231 -0
  795. package/src/_shared/crypto.ts +184 -0
  796. package/src/_shared/esbuild-facet-shim.ts +22 -0
  797. package/src/_shared/exports-resolver.ts +308 -0
  798. package/src/_shared/facet-vfs-cursor.ts +58 -0
  799. package/src/_shared/install-phase.ts +56 -0
  800. package/src/_shared/lru-map.ts +59 -0
  801. package/src/_shared/real-node-imports.ts +53 -0
  802. package/src/_shared/retry.ts +202 -0
  803. package/src/_shared/rpc-dispose.ts +31 -0
  804. package/src/_shared/terminal.ts +3 -0
  805. package/src/_shared/typescript-specifiers.ts +86 -0
  806. package/src/_shared/untrusted-request.ts +75 -0
  807. package/src/_shared/vfs-write-ledger.ts +440 -0
  808. package/src/_shared/w7-frame.ts +1012 -0
  809. package/src/_shared/weighted-credit-pool.ts +244 -0
  810. package/src/constants.ts +285 -0
  811. package/src/index.ts +22 -0
  812. package/src/observability/diag-counters.ts +343 -0
  813. package/src/observability/heap-estimate.ts +331 -0
  814. package/src/observability/heavy-alloc-coord.ts +241 -0
  815. package/src/observability/oom-classify.ts +253 -0
  816. package/src/observability/oom-discriminator.ts +405 -0
  817. package/src/runtime/assets-loader.ts +189 -0
  818. package/src/runtime/barrel-detect.ts +69 -0
  819. package/src/runtime/bash/preamble.ts +1519 -0
  820. package/src/runtime/bash/types.ts +497 -0
  821. package/src/runtime/bundle-profile.ts +32 -0
  822. package/src/runtime/cirrus-vite-config-rewriter.ts +28 -0
  823. package/src/runtime/cli-flags.ts +11 -0
  824. package/src/runtime/comment-strip.ts +73 -0
  825. package/src/runtime/cpython-preamble.ts +298 -0
  826. package/src/runtime/esbuild-service.ts +1470 -0
  827. package/src/runtime/framework-detect.ts +245 -0
  828. package/src/runtime/import-meta-transform.ts +16 -0
  829. package/src/runtime/javascript-ast.ts +66 -0
  830. package/src/runtime/long-running-handle.ts +185 -0
  831. package/src/runtime/module-source-rewriter.ts +95 -0
  832. package/src/runtime/opentui-wasm-backend.ts +608 -0
  833. package/src/runtime/os-contracts.ts +529 -0
  834. package/src/runtime/port-registry.ts +298 -0
  835. package/src/runtime/process-input-routing.ts +92 -0
  836. package/src/runtime/process-input.ts +148 -0
  837. package/src/runtime/process-io-protocol.ts +97 -0
  838. package/src/runtime/process-logs.ts +882 -0
  839. package/src/runtime/process-table.ts +225 -0
  840. package/src/runtime/project-detect.ts +42 -0
  841. package/src/runtime/python-server-adapter.ts +133 -0
  842. package/src/runtime/require-resolver.ts +760 -0
  843. package/src/runtime/router-basename.ts +279 -0
  844. package/src/runtime/ruby-green-threads.ts +904 -0
  845. package/src/runtime/ruby-socket-shim.ts +548 -0
  846. package/src/runtime/session-process-supervisor.ts +323 -0
  847. package/src/runtime/sqlite-runtime-fs-bridge.ts +468 -0
  848. package/src/runtime/streams.ts +547 -0
  849. package/src/runtime/undici-shim.ts +517 -0
  850. package/src/runtime/vfs-manifest.ts +170 -0
  851. package/src/runtime/vfs-snapshot.ts +273 -0
  852. package/src/runtime/virtual-socket-kernel.ts +1370 -0
  853. package/src/runtime/vite-config-parser.ts +273 -0
  854. package/src/runtime/wasi/types.ts +448 -0
  855. package/src/runtime/wasi-instance.generated.ts +14 -0
  856. package/src/runtime/wasi-instance.ts +259 -0
  857. package/src/runtime/wasi-threads.ts +682 -0
  858. package/src/runtime/wasm-memory.ts +261 -0
  859. package/src/shell/elevation-commands.ts +117 -0
  860. package/src/shell/exec-dispatch.ts +201 -0
  861. package/src/shell/features.ts +870 -0
  862. package/src/shell/shell-entrypoints.ts +323 -0
  863. package/src/shell/shell-invocation.ts +181 -0
  864. package/src/shell/unix-accounts.ts +128 -0
  865. package/src/shell/unix-commands.ts +4335 -0
  866. package/src/substrate/lifo/UPSTREAM.md +14 -0
  867. package/src/substrate/lifo/commands/archive/gunzip.ts +63 -0
  868. package/src/substrate/lifo/commands/archive/gzip.ts +76 -0
  869. package/src/substrate/lifo/commands/archive/tar.ts +157 -0
  870. package/src/substrate/lifo/commands/archive/unzip.ts +112 -0
  871. package/src/substrate/lifo/commands/archive/zip.ts +70 -0
  872. package/src/substrate/lifo/commands/fs/basename.ts +16 -0
  873. package/src/substrate/lifo/commands/fs/cat.ts +54 -0
  874. package/src/substrate/lifo/commands/fs/chmod.ts +110 -0
  875. package/src/substrate/lifo/commands/fs/chown.ts +45 -0
  876. package/src/substrate/lifo/commands/fs/cp.ts +33 -0
  877. package/src/substrate/lifo/commands/fs/df.ts +56 -0
  878. package/src/substrate/lifo/commands/fs/dirname.ts +16 -0
  879. package/src/substrate/lifo/commands/fs/du.ts +100 -0
  880. package/src/substrate/lifo/commands/fs/file.ts +90 -0
  881. package/src/substrate/lifo/commands/fs/find.ts +76 -0
  882. package/src/substrate/lifo/commands/fs/ln.ts +19 -0
  883. package/src/substrate/lifo/commands/fs/ls.ts +164 -0
  884. package/src/substrate/lifo/commands/fs/mkdir.ts +37 -0
  885. package/src/substrate/lifo/commands/fs/mktemp.ts +56 -0
  886. package/src/substrate/lifo/commands/fs/mv.ts +111 -0
  887. package/src/substrate/lifo/commands/fs/realpath.ts +31 -0
  888. package/src/substrate/lifo/commands/fs/rm.ts +53 -0
  889. package/src/substrate/lifo/commands/fs/rmdir.ts +50 -0
  890. package/src/substrate/lifo/commands/fs/stat.ts +39 -0
  891. package/src/substrate/lifo/commands/fs/touch.ts +30 -0
  892. package/src/substrate/lifo/commands/fs/tree.ts +76 -0
  893. package/src/substrate/lifo/commands/index.ts +2 -0
  894. package/src/substrate/lifo/commands/io/dd.ts +289 -0
  895. package/src/substrate/lifo/commands/io/printf.ts +78 -0
  896. package/src/substrate/lifo/commands/io/tee.ts +37 -0
  897. package/src/substrate/lifo/commands/io/xargs.ts +49 -0
  898. package/src/substrate/lifo/commands/io/yes.ts +15 -0
  899. package/src/substrate/lifo/commands/net/curl.ts +739 -0
  900. package/src/substrate/lifo/commands/net/dig.ts +99 -0
  901. package/src/substrate/lifo/commands/net/forward.ts +90 -0
  902. package/src/substrate/lifo/commands/net/host.ts +182 -0
  903. package/src/substrate/lifo/commands/net/ifconfig.ts +139 -0
  904. package/src/substrate/lifo/commands/net/ip.ts +633 -0
  905. package/src/substrate/lifo/commands/net/netstat.ts +106 -0
  906. package/src/substrate/lifo/commands/net/ping.ts +74 -0
  907. package/src/substrate/lifo/commands/net/ports.ts +45 -0
  908. package/src/substrate/lifo/commands/net/route.ts +153 -0
  909. package/src/substrate/lifo/commands/net/tunnel-v2.ts +183 -0
  910. package/src/substrate/lifo/commands/net/tunnel.ts +272 -0
  911. package/src/substrate/lifo/commands/net/wget.ts +88 -0
  912. package/src/substrate/lifo/commands/registry.ts +141 -0
  913. package/src/substrate/lifo/commands/signal.ts +65 -0
  914. package/src/substrate/lifo/commands/system/bc.ts +265 -0
  915. package/src/substrate/lifo/commands/system/cal.ts +90 -0
  916. package/src/substrate/lifo/commands/system/date.ts +59 -0
  917. package/src/substrate/lifo/commands/system/env.ts +10 -0
  918. package/src/substrate/lifo/commands/system/fastfetch.ts +428 -0
  919. package/src/substrate/lifo/commands/system/free.ts +38 -0
  920. package/src/substrate/lifo/commands/system/help.ts +53 -0
  921. package/src/substrate/lifo/commands/system/hostname.ts +9 -0
  922. package/src/substrate/lifo/commands/system/kill.ts +89 -0
  923. package/src/substrate/lifo/commands/system/lifo.ts +525 -0
  924. package/src/substrate/lifo/commands/system/logout.ts +17 -0
  925. package/src/substrate/lifo/commands/system/man.ts +167 -0
  926. package/src/substrate/lifo/commands/system/node.ts +1305 -0
  927. package/src/substrate/lifo/commands/system/npm.ts +1078 -0
  928. package/src/substrate/lifo/commands/system/pkg.ts +111 -0
  929. package/src/substrate/lifo/commands/system/ps.ts +46 -0
  930. package/src/substrate/lifo/commands/system/registry-schemas.ts +33 -0
  931. package/src/substrate/lifo/commands/system/sha256sum.ts +89 -0
  932. package/src/substrate/lifo/commands/system/sl.ts +249 -0
  933. package/src/substrate/lifo/commands/system/sleep.ts +36 -0
  934. package/src/substrate/lifo/commands/system/stty.ts +69 -0
  935. package/src/substrate/lifo/commands/system/systemctl.ts +184 -0
  936. package/src/substrate/lifo/commands/system/top.ts +53 -0
  937. package/src/substrate/lifo/commands/system/uname.ts +59 -0
  938. package/src/substrate/lifo/commands/system/uptime.ts +19 -0
  939. package/src/substrate/lifo/commands/system/watch.ts +67 -0
  940. package/src/substrate/lifo/commands/system/which.ts +51 -0
  941. package/src/substrate/lifo/commands/system/whoami.ts +9 -0
  942. package/src/substrate/lifo/commands/text/awk.ts +210 -0
  943. package/src/substrate/lifo/commands/text/base64.ts +102 -0
  944. package/src/substrate/lifo/commands/text/cut.ts +92 -0
  945. package/src/substrate/lifo/commands/text/diff.ts +314 -0
  946. package/src/substrate/lifo/commands/text/grep.ts +170 -0
  947. package/src/substrate/lifo/commands/text/head.ts +95 -0
  948. package/src/substrate/lifo/commands/text/less.ts +335 -0
  949. package/src/substrate/lifo/commands/text/nano.ts +513 -0
  950. package/src/substrate/lifo/commands/text/nl.ts +74 -0
  951. package/src/substrate/lifo/commands/text/rev.ts +46 -0
  952. package/src/substrate/lifo/commands/text/sed.ts +297 -0
  953. package/src/substrate/lifo/commands/text/seq.ts +76 -0
  954. package/src/substrate/lifo/commands/text/sort.ts +88 -0
  955. package/src/substrate/lifo/commands/text/strings.ts +73 -0
  956. package/src/substrate/lifo/commands/text/tac.ts +37 -0
  957. package/src/substrate/lifo/commands/text/tail.ts +63 -0
  958. package/src/substrate/lifo/commands/text/tr.ts +192 -0
  959. package/src/substrate/lifo/commands/text/uniq.ts +77 -0
  960. package/src/substrate/lifo/commands/text/wc.ts +104 -0
  961. package/src/substrate/lifo/commands/types.ts +58 -0
  962. package/src/substrate/lifo/index.ts +173 -0
  963. package/src/substrate/lifo/kernel/ServiceManager.ts +371 -0
  964. package/src/substrate/lifo/kernel/index.ts +209 -0
  965. package/src/substrate/lifo/kernel/network/Bridge.ts +336 -0
  966. package/src/substrate/lifo/kernel/network/DNSResolver.ts +158 -0
  967. package/src/substrate/lifo/kernel/network/NetworkInterface.ts +235 -0
  968. package/src/substrate/lifo/kernel/network/NetworkNamespace.ts +182 -0
  969. package/src/substrate/lifo/kernel/network/NetworkStack.ts +590 -0
  970. package/src/substrate/lifo/kernel/network/PortBridge.ts +182 -0
  971. package/src/substrate/lifo/kernel/network/RoutingTable.ts +209 -0
  972. package/src/substrate/lifo/kernel/network/Socket.ts +245 -0
  973. package/src/substrate/lifo/kernel/network/index.ts +29 -0
  974. package/src/substrate/lifo/kernel/network/tunnel/BaseTunnel.ts +124 -0
  975. package/src/substrate/lifo/kernel/network/tunnel/VETHPair.ts +227 -0
  976. package/src/substrate/lifo/kernel/network/tunnel/WebSocketTunnel.ts +387 -0
  977. package/src/substrate/lifo/kernel/network/types.ts +178 -0
  978. package/src/substrate/lifo/kernel/persistence/PersistenceManager.ts +50 -0
  979. package/src/substrate/lifo/kernel/persistence/backends.ts +36 -0
  980. package/src/substrate/lifo/kernel/persistence/index.ts +5 -0
  981. package/src/substrate/lifo/kernel/persistence/serializer.ts +127 -0
  982. package/src/substrate/lifo/kernel/samples.ts +966 -0
  983. package/src/substrate/lifo/kernel/storage/BlobStore.ts +114 -0
  984. package/src/substrate/lifo/kernel/storage/ContentStore.ts +150 -0
  985. package/src/substrate/lifo/kernel/storage/index.ts +5 -0
  986. package/src/substrate/lifo/kernel/unit-parser.ts +95 -0
  987. package/src/substrate/lifo/kernel/vfs/VFS.ts +768 -0
  988. package/src/substrate/lifo/kernel/vfs/index.ts +9 -0
  989. package/src/substrate/lifo/kernel/vfs/providers/DevProvider.ts +172 -0
  990. package/src/substrate/lifo/kernel/vfs/providers/NativeFsProvider.ts +198 -0
  991. package/src/substrate/lifo/kernel/vfs/providers/ProcProvider.ts +144 -0
  992. package/src/substrate/lifo/kernel/vfs/types.ts +145 -0
  993. package/src/substrate/lifo/node-compat/buffer.ts +357 -0
  994. package/src/substrate/lifo/node-compat/child_process.ts +52 -0
  995. package/src/substrate/lifo/node-compat/console.ts +70 -0
  996. package/src/substrate/lifo/node-compat/crypto.ts +186 -0
  997. package/src/substrate/lifo/node-compat/dns.ts +214 -0
  998. package/src/substrate/lifo/node-compat/esbuild.ts +85 -0
  999. package/src/substrate/lifo/node-compat/events.ts +94 -0
  1000. package/src/substrate/lifo/node-compat/fs.ts +762 -0
  1001. package/src/substrate/lifo/node-compat/http.ts +561 -0
  1002. package/src/substrate/lifo/node-compat/index.ts +300 -0
  1003. package/src/substrate/lifo/node-compat/module.ts +148 -0
  1004. package/src/substrate/lifo/node-compat/os.ts +44 -0
  1005. package/src/substrate/lifo/node-compat/path.ts +74 -0
  1006. package/src/substrate/lifo/node-compat/process.ts +178 -0
  1007. package/src/substrate/lifo/node-compat/readline.ts +244 -0
  1008. package/src/substrate/lifo/node-compat/rimraf.ts +80 -0
  1009. package/src/substrate/lifo/node-compat/stream.ts +98 -0
  1010. package/src/substrate/lifo/node-compat/string_decoder.ts +26 -0
  1011. package/src/substrate/lifo/node-compat/timers.ts +21 -0
  1012. package/src/substrate/lifo/node-compat/tty.ts +83 -0
  1013. package/src/substrate/lifo/node-compat/url.ts +76 -0
  1014. package/src/substrate/lifo/node-compat/util.ts +133 -0
  1015. package/src/substrate/lifo/node-compat/zlib.ts +94 -0
  1016. package/src/substrate/lifo/pkg/PackageManager.ts +105 -0
  1017. package/src/substrate/lifo/pkg/lifo-dev.ts +130 -0
  1018. package/src/substrate/lifo/pkg/lifo-runtime.ts +473 -0
  1019. package/src/substrate/lifo/pkg/loader.ts +33 -0
  1020. package/src/substrate/lifo/platform-globals.d.ts +41 -0
  1021. package/src/substrate/lifo/sandbox/HeadlessTerminal.ts +38 -0
  1022. package/src/substrate/lifo/sandbox/Sandbox.ts +279 -0
  1023. package/src/substrate/lifo/sandbox/SandboxCommands.ts +74 -0
  1024. package/src/substrate/lifo/sandbox/SandboxFs.ts +160 -0
  1025. package/src/substrate/lifo/sandbox/index.ts +8 -0
  1026. package/src/substrate/lifo/sandbox/types.ts +117 -0
  1027. package/src/substrate/lifo/shell/ProcessRegistry.ts +379 -0
  1028. package/src/substrate/lifo/shell/Shell.ts +2048 -0
  1029. package/src/substrate/lifo/shell/completer.ts +212 -0
  1030. package/src/substrate/lifo/shell/default-shell.ts +63 -0
  1031. package/src/substrate/lifo/shell/expander.ts +1349 -0
  1032. package/src/substrate/lifo/shell/history.ts +138 -0
  1033. package/src/substrate/lifo/shell/interpreter.ts +1754 -0
  1034. package/src/substrate/lifo/shell/jobs.ts +64 -0
  1035. package/src/substrate/lifo/shell/lexer.ts +698 -0
  1036. package/src/substrate/lifo/shell/parser.ts +711 -0
  1037. package/src/substrate/lifo/shell/pipe.ts +92 -0
  1038. package/src/substrate/lifo/shell/signals.ts +70 -0
  1039. package/src/substrate/lifo/shell/terminal-stdin.ts +109 -0
  1040. package/src/substrate/lifo/shell/test-builtin.ts +316 -0
  1041. package/src/substrate/lifo/shell/types.ts +166 -0
  1042. package/src/substrate/lifo/terminal/ITerminal.ts +9 -0
  1043. package/src/substrate/lifo/utils/archive.ts +389 -0
  1044. package/src/substrate/lifo/utils/args.ts +89 -0
  1045. package/src/substrate/lifo/utils/colors.ts +29 -0
  1046. package/src/substrate/lifo/utils/encoding.ts +21 -0
  1047. package/src/substrate/lifo/utils/glob.ts +172 -0
  1048. package/src/substrate/lifo/utils/mime.ts +114 -0
  1049. package/src/substrate/lifo/utils/path.ts +83 -0
  1050. package/src/types/assets.d.ts +4 -0
  1051. package/src/vfs/events.ts +134 -0
  1052. package/src/vfs/path.ts +71 -0
  1053. package/src/vfs/seed-project.ts +1094 -0
  1054. package/src/vfs/sqlite-vfs.ts +5035 -0
  1055. package/src/vfs/symlink-registry.ts +172 -0
  1056. package/src/workspace/nimbus-workspace.ts +213 -0
@@ -0,0 +1,1519 @@
1
+ /**
2
+ * bash/preamble.ts — the facet-side bash scheduler, as real TypeScript.
3
+ *
4
+ * This file IS the runner. scripts/bundle-facet-workers.mjs esbuilds it into
5
+ * bash-runner.generated.ts as a self-contained IIFE, and bash-runner.ts re-exports
6
+ * that string as BASH_RUNNER_PREAMBLE — the loader-pool preamble every bash facet
7
+ * evaluates. The same pattern wasi/preamble.ts and virtual-socket-kernel.ts use.
8
+ *
9
+ * Until this move the scheduler lived inside a String.raw template literal, so no
10
+ * type checker had ever read it.
11
+ *
12
+ * Constraints the build imposes on this file:
13
+ * - It is evaluated as a FUNCTION body (new Function(...) in tests, a loader-pool
14
+ * preamble in production), so the emitted string may contain no import, no
15
+ * export and no top-level await. Bundling to an IIFE is what guarantees that.
16
+ * - Nothing may be imported for its value. Type-only imports are erased and are
17
+ * the only kind permitted.
18
+ * - globalThis.__bashBoot and globalThis.__bashFeed are the entry points; every
19
+ * other declaration is reachable only from them, which is why the bundle runs
20
+ * with tree shaking off.
21
+ */
22
+ import type {
23
+ BashBlockTarget,
24
+ BashBootArgs,
25
+ BashByteQueue,
26
+ BashErrno,
27
+ BashExitStatus,
28
+ BashFdEntry,
29
+ BashFdReadiness,
30
+ BashFeedArgs,
31
+ BashFileEntry,
32
+ BashFsSeed,
33
+ BashFsState,
34
+ BashInstance,
35
+ BashIo,
36
+ BashIovs,
37
+ BashPathResolution,
38
+ BashPipe,
39
+ BashPollSub,
40
+ BashProc,
41
+ BashProcImports,
42
+ BashReadWaiter,
43
+ BashSession,
44
+ BashSlice,
45
+ BashUnsupportedImports,
46
+ BashWasiFsImports,
47
+ BashWasiImports,
48
+ } from './types.js';
49
+ import type { WasiFsDiff } from '../vfs-snapshot.js';
50
+
51
+ const PAGE = 65536, te = new TextEncoder(), td = new TextDecoder();
52
+ // Sizing is measurement-grounded (local pre-gate stats): bash's deepest
53
+ // observed asyncify capture is ~25 KiB (full control suite), so 8 MiB
54
+ // main / 256 KiB slots carry 300×/10× margin while keeping a full
55
+ // instance ~17 MiB — several forks fit the ~180-200 MiB facet ceiling.
56
+ const MAIN_SIZE = 8 << 20, SLOT_SIZE = 256 << 10, NSLOT = 32;
57
+ const E = { ACCES: 2, BADF: 8, EXIST: 20, INVAL: 28, ISDIR: 31, LOOP: 32, NOENT: 44, NOSYS: 52, NOTDIR: 54, NOTEMPTY: 55, PERM: 63, SPIPE: 70 } satisfies Record<string, BashErrno>;
58
+ // WASI clock ids. MONOTONIC and the two CPUTIME clocks are answered from a
59
+ // monotonic source; an id outside this set is EINVAL, never a silent realtime
60
+ // reading — a guest that asks for monotonic and receives wall time computes
61
+ // negative durations the first time the wall clock steps backwards.
62
+ const CLOCK_REALTIME = 0, CLOCK_MONOTONIC = 1, CLOCK_PROCESS_CPUTIME = 2, CLOCK_THREAD_CPUTIME = 3;
63
+ function realtimeNs() { return BigInt(Date.now()) * 1000000n; }
64
+ function monotonicNs() {
65
+ const ms = (typeof performance !== 'undefined' && performance.now) ? performance.now() : Date.now();
66
+ return BigInt(Math.floor(ms * 1000)) * 1000n;
67
+ }
68
+ // null for an unknown id, so callers answer EINVAL rather than inventing a time.
69
+ function clockNs(id: number | undefined): bigint | null {
70
+ if (id === CLOCK_REALTIME) return realtimeNs();
71
+ if (id === CLOCK_MONOTONIC || id === CLOCK_PROCESS_CPUTIME || id === CLOCK_THREAD_CPUTIME) return monotonicNs();
72
+ return null;
73
+ }
74
+ class Exit { declare code: number; constructor(c: number) { this.code = c; } }
75
+
76
+ let S: BashSession | null = null; // active session state; persists across submits on the warm isolate
77
+
78
+ function norm(p: string): string {
79
+ const parts = [];
80
+ for (const seg of String(p).split('/')) {
81
+ if (!seg || seg === '.') continue;
82
+ if (seg === '..') { parts.pop(); continue; }
83
+ parts.push(seg);
84
+ }
85
+ return parts.join('/');
86
+ }
87
+
88
+ function b64ToBytes(b64: string): Uint8Array {
89
+ const bin = atob(b64);
90
+ const out = new Uint8Array(bin.length);
91
+ for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);
92
+ return out;
93
+ }
94
+ function bytesToB64(bytes: Uint8Array): string {
95
+ let bin = '';
96
+ const CH = 0x8000;
97
+ for (let i = 0; i < bytes.length; i += CH) bin += String.fromCharCode.apply(null, bytes.subarray(i, i + CH) as unknown as number[]);
98
+ return btoa(bin);
99
+ }
100
+
101
+ function newSession(args: BashBootArgs): BashSession {
102
+ const wasmTable = globalThis.__NIMBUS_WASM || {};
103
+ const mod = wasmTable['bash.async.wasm'];
104
+ if (!mod) throw new Error('bash.async.wasm missing from __NIMBUS_WASM');
105
+ const coreutils = new Map();
106
+ for (const key of Object.keys(wasmTable)) {
107
+ if (key.startsWith('cu_') && key.endsWith('.wasm')) coreutils.set(key.slice(3, -5), wasmTable[key]);
108
+ }
109
+ // Applet aliasing: ONE staged busybox module answers to every applet
110
+ // name (busybox dispatches on argv[0]), so bash's PATH lookup finds
111
+ // ls/cat/grep/... as executables in /bin.
112
+ const busybox = wasmTable['cu_busybox.wasm'];
113
+ if (busybox) for (const name of args.busyboxApplets || []) coreutils.set(name, busybox);
114
+
115
+ const fs: BashFsState = {
116
+ files: new Map(), dirs: new Set(), modes: new Map(),
117
+ written: new Set(), deleted: new Set(),
118
+ dirsCreated: new Set(), dirsDeleted: new Set(), modesChanged: new Map(),
119
+ // vfsPath → mtime ns. The snapshot carries no times, so an inode the
120
+ // session did not touch reports sessionNs: older than anything written
121
+ // here, which is what makes 'is the target newer than its source' — the
122
+ // question make(1) and every incremental build asks — answerable.
123
+ times: new Map(), sessionNs: realtimeNs(),
124
+ // vfsPath → target string, stored verbatim per POSIX: a symlink is a dumb
125
+ // string resolved at lookup time, not a pointer to an inode.
126
+ symlinks: new Map(), symlinksCreated: new Map(),
127
+ };
128
+ const snap: BashFsSeed = args.fsSnapshot || { files: {}, dirs: [], modes: {} };
129
+ for (const [path, b64] of Object.entries(snap.files || {})) fs.files.set(norm(path), { bytes: b64ToBytes(b64) });
130
+ for (const d of snap.dirs || []) fs.dirs.add(norm(d));
131
+ // The snapshot's modes are the S2a projection: effective rwx per path
132
+ // for the invoking credential. Enforced by the WASI layer below.
133
+ for (const [path, m] of Object.entries(snap.modes || {})) fs.modes.set(norm(path), Number(m) & 7);
134
+ for (const seed of ['etc', 'dev', 'bin', 'usr', 'usr/bin']) {
135
+ fs.dirs.add(seed);
136
+ if (!fs.modes.has(seed)) fs.modes.set(seed, 5);
137
+ }
138
+ // Startup rc: chdir to the session cwd (wasi-libc cwd starts at '/').
139
+ // BASH_ENV points here for non-interactive shells; interactive shells
140
+ // read ~/.bashrc, which is seeded to source this file when absent.
141
+ if (!fs.files.has('etc/nimbus.bashrc')) {
142
+ fs.files.set('etc/nimbus.bashrc', { bytes: te.encode('command cd "$' + '{NIMBUS_PWD:-/}" 2>/dev/null\n') });
143
+ fs.modes.set('etc/nimbus.bashrc', 4);
144
+ }
145
+ const home = norm((args.environ.find((e) => e.startsWith('HOME=')) || 'HOME=/home/user').slice(5));
146
+ if (args.stdinTty && home && !fs.files.has(home + '/.bashrc')) {
147
+ fs.files.set(home + '/.bashrc', { bytes: te.encode('. /etc/nimbus.bashrc\n') });
148
+ if (!fs.modes.has(home + '/.bashrc')) fs.modes.set(home + '/.bashrc', 6);
149
+ }
150
+
151
+ const cwd = norm((args.environ.find((e) => e.startsWith('NIMBUS_PWD=')) || 'NIMBUS_PWD=/').slice(11));
152
+ return {
153
+ mod, coreutils, fs, cwd,
154
+ argv: args.argv, environ: args.environ,
155
+ stdinTty: !!args.stdinTty,
156
+ stdin: { chunks: args.stdinData ? [te.encode(args.stdinData)] : [], queued: 0, closed: !!args.stdinClosed, waiters: [] },
157
+ procs: new Map(), pipes: new Map(), runnable: [], exitStatus: new Map(), waiters: [],
158
+ pidNext: 100, pipeNext: 1, rootPid: 0, rootExit: null, steps: 0,
159
+ out: '', err: '',
160
+ missingWasi: new Set(),
161
+ stats: { instances: 0, memPeak: 0, mainHi: 0, slotHi: 0 },
162
+ error: null,
163
+ };
164
+ }
165
+ function initStdinQueued(s: BashSession): void { s.stdin.queued = s.stdin.chunks.reduce((a, c) => a + c.length, 0); }
166
+
167
+ function newPipe(s: BashSession): number { const id = s.pipeNext++; s.pipes.set(id, { chunks: [], queued: 0, readers: 1, writers: 1, readW: [] }); return id; }
168
+ // fd 3 is the wasi-libc '/' preopen. It lives in the fd table as a
169
+ // real 'preopen' entry: wasi-libc's path ops fd_fdstat_get the dirfd
170
+ // to compute inherited rights, so it must answer (not EBADF), and
171
+ // lowestFd must never re-issue it for a regular file.
172
+ function lowestFd(proc: BashProc): number { let fd = 0; while (proc.fds.has(fd) || fd === 3) fd++; return fd; }
173
+ function bumpPipe(s: BashSession, e: { pipeId: number; end: 'r' | 'w' }, d: number): void { const pp = s.pipes.get(e.pipeId) as BashPipe; if (e.end === 'r') pp.readers += d; else pp.writers += d; }
174
+ function closeFd(s: BashSession, proc: BashProc, fd: number): void {
175
+ const e = proc.fds.get(fd);
176
+ if (!e) return;
177
+ proc.fds.delete(fd);
178
+ if (e.kind === 'pipe') { bumpPipe(s, e, -1); wakePipe(s, s.pipes.get(e.pipeId) as BashPipe); }
179
+ }
180
+ function takeUpTo(src: BashByteQueue, max: number): Uint8Array {
181
+ let need = max; const parts = [];
182
+ while (need > 0 && src.chunks.length) {
183
+ const ch = src.chunks[0];
184
+ if (ch.length <= need) { parts.push(ch); need -= ch.length; src.chunks.shift(); }
185
+ else { parts.push(ch.subarray(0, need)); src.chunks[0] = ch.subarray(need); need = 0; }
186
+ }
187
+ const total = max - need; src.queued -= total;
188
+ const o = new Uint8Array(total); let x = 0;
189
+ for (const p of parts) { o.set(p, x); x += p.length; }
190
+ return o;
191
+ }
192
+ // POSIX readv is ONE read of up to the summed length, scattered across the
193
+ // buffers in order — not a read of the first buffer. Zero-length entries are
194
+ // dropped so they never terminate the scatter early.
195
+ // A poll park has no destination buffer — it resumes into a fresh poll call.
196
+ const EMPTY_IOV: BashIovs = { list: [], total: 0 };
197
+ function readIovs(dv: DataView, iovs: number, n: number): BashIovs {
198
+ const list = [];
199
+ let total = 0;
200
+ for (let i = 0; i < n; i++) {
201
+ const ptr = dv.getUint32(iovs + i * 8, true), len = dv.getUint32(iovs + i * 8 + 4, true);
202
+ if (len > 0) { list.push({ ptr, len }); total += len; }
203
+ }
204
+ return { list, total };
205
+ }
206
+ function scatter(u8: Uint8Array, iov: BashIovs, bytes: Uint8Array): number {
207
+ let off = 0;
208
+ for (const b of iov.list) {
209
+ if (off >= bytes.length) break;
210
+ const n = Math.min(b.len, bytes.length - off);
211
+ u8.set(bytes.subarray(off, off + n), b.ptr);
212
+ off += n;
213
+ }
214
+ return off;
215
+ }
216
+ function wakePipe(s: BashSession, pp: BashPipe): void {
217
+ while (pp.readW.length && (pp.queued > 0 || pp.writers === 0)) {
218
+ const w = pp.readW.shift() as BashReadWaiter; const proc = w.proc; const req = proc.ctx.pipeReq;
219
+ const bytes = pp.queued > 0 ? takeUpTo(pp, req.iov.total) : new Uint8Array(0);
220
+ proc.pendingRead = { iov: req.iov, bytes, nreadPtr: req.nreadPtr, pollUserdata: req.pollUserdata };
221
+ resumeProc(proc);
222
+ }
223
+ }
224
+ function wakeStdin(s: BashSession): void {
225
+ const st = s.stdin;
226
+ while (st.waiters.length && (st.queued > 0 || st.closed)) {
227
+ const w = st.waiters.shift() as BashReadWaiter; const proc = w.proc; const req = proc.ctx.pipeReq;
228
+ const bytes = st.queued > 0 ? takeUpTo(st, req.iov.total) : new Uint8Array(0);
229
+ proc.pendingRead = { iov: req.iov, bytes, nreadPtr: req.nreadPtr, pollUserdata: req.pollUserdata };
230
+ resumeProc(proc);
231
+ }
232
+ }
233
+
234
+ // ── file layer ────────────────────────────────────────────────────────
235
+ function fileLookup(s: BashSession, path: string): BashFileEntry | null { return s.fs.files.get(path) || null; }
236
+ function isDir(s: BashSession, path: string): boolean { return path === '' || s.fs.dirs.has(path); }
237
+ function isCoreutil(s: BashSession, path: string): boolean {
238
+ if (!path.startsWith('bin/') && !path.startsWith('usr/bin/')) return false;
239
+ return s.coreutils.has(path.split('/').pop() as string);
240
+ }
241
+ // A modes-only inode is a file the snapshot could not read (S2a): it
242
+ // exists, its bytes are absent, and access answers with the real bits.
243
+ function fileExists(s: BashSession, path: string): boolean {
244
+ return s.fs.files.has(path) || (s.fs.modes.has(path) && !s.fs.dirs.has(path));
245
+ }
246
+ function inodeExists(s: BashSession, path: string): boolean {
247
+ return s.fs.files.has(path) || s.fs.dirs.has(path) || s.fs.modes.has(path);
248
+ }
249
+ // S2a effective-mode policy (mirrors the JSPI shim): a mapped mode wins;
250
+ // an inode that exists without one is denied; an absent path is free to
251
+ // create (the durable flush re-checks as the credential).
252
+ function effMode(s: BashSession, path: string): number {
253
+ if (path === '') return 7;
254
+ const m = s.fs.modes.get(path);
255
+ if (m !== undefined) return m;
256
+ if (isCoreutil(s, path)) return 5;
257
+ return inodeExists(s, path) ? 0 : 7;
258
+ }
259
+ function parentOf(path: string): string { const i = path.lastIndexOf('/'); return i < 0 ? '' : path.slice(0, i); }
260
+ // Rewrite the leftmost symlink on the path and repeat, so both intermediate
261
+ // components and a terminal link resolve. A target starting with '/' is
262
+ // root-anchored; anything else is relative to the link's own directory.
263
+ // SYMLOOP_MAX bounds it — a cycle answers ELOOP rather than hanging.
264
+ function followPath(s: BashSession, path: string): BashPathResolution {
265
+ let cur = path;
266
+ for (let hops = 0; hops < 32; hops++) {
267
+ if (!s.fs.symlinks.size) return { path: cur, errno: 0 };
268
+ const parts = cur.split('/');
269
+ let prefix = '';
270
+ let rewrote = false;
271
+ for (let i = 0; i < parts.length; i++) {
272
+ prefix = prefix ? prefix + '/' + parts[i] : parts[i];
273
+ const target = s.fs.symlinks.get(prefix);
274
+ if (target === undefined) continue;
275
+ const base = target.startsWith('/') ? norm(target) : norm(parentOf(prefix) + '/' + target);
276
+ const rest = parts.slice(i + 1).join('/');
277
+ cur = rest ? norm(base + '/' + rest) : base;
278
+ rewrote = true;
279
+ break;
280
+ }
281
+ if (!rewrote) return { path: cur, errno: 0 };
282
+ }
283
+ return { path: cur, errno: E.LOOP };
284
+ }
285
+ // Resolve only the directories leading to the final component. This is what
286
+ // the mutating ops want: rm dir/link must delete the link, not its target,
287
+ // while dir itself may still be reached through a link.
288
+ function followParents(s: BashSession, path: string): BashPathResolution {
289
+ const parent = parentOf(path);
290
+ if (!parent) return { path, errno: 0 };
291
+ const r = followPath(s, parent);
292
+ if (r.errno) return r;
293
+ const name = path.slice(parent.length + 1);
294
+ return { path: r.path ? r.path + '/' + name : name, errno: 0 };
295
+ }
296
+ // Every ancestor dir on the way to the target needs the search (x) bit.
297
+ function checkTraversal(s: BashSession, path: string): BashErrno {
298
+ const parts = path.split('/');
299
+ let anc = '';
300
+ for (let i = 0; i < parts.length - 1; i++) {
301
+ anc = anc ? anc + '/' + parts[i] : parts[i];
302
+ if (!isDir(s, anc)) return inodeExists(s, anc) ? E.NOTDIR : E.NOENT;
303
+ if ((effMode(s, anc) & 1) === 0) return E.ACCES;
304
+ }
305
+ return 0;
306
+ }
307
+ function checkParentWritable(s: BashSession, path: string): BashErrno {
308
+ const parent = parentOf(path);
309
+ if (parent && (effMode(s, parent) & 3) !== 3) return E.ACCES;
310
+ return 0;
311
+ }
312
+ function recordDirAdded(s: BashSession, path: string): void {
313
+ s.fs.dirs.add(path); s.fs.dirsDeleted.delete(path); s.fs.dirsCreated.add(path);
314
+ if (!s.fs.modes.has(path)) s.fs.modes.set(path, 7);
315
+ touchPath(s, path);
316
+ }
317
+ function recordDirRemoved(s: BashSession, path: string): void {
318
+ s.fs.dirs.delete(path); s.fs.modes.delete(path); s.fs.times.delete(path);
319
+ if (s.fs.dirsCreated.has(path)) s.fs.dirsCreated.delete(path);
320
+ else s.fs.dirsDeleted.add(path);
321
+ }
322
+ function recordFileRemoved(s: BashSession, path: string): void {
323
+ s.fs.files.delete(path); s.fs.written.delete(path); s.fs.modes.delete(path);
324
+ s.fs.times.delete(path); s.fs.symlinks.delete(path); s.fs.symlinksCreated.delete(path);
325
+ s.fs.deleted.add(path);
326
+ }
327
+ function markWritten(s: BashSession, path: string): void {
328
+ s.fs.written.add(path); s.fs.deleted.delete(path);
329
+ if (!s.fs.modes.has(path)) s.fs.modes.set(path, 6);
330
+ touchPath(s, path);
331
+ const parts = path.split('/');
332
+ for (let i = 1; i < parts.length; i++) {
333
+ const dir = parts.slice(0, i).join('/');
334
+ if (!s.fs.dirs.has(dir)) recordDirAdded(s, dir);
335
+ }
336
+ }
337
+ function fileWrite(s: BashSession, entry: BashFileEntry, path: string, pos: number, bytes: Uint8Array): void {
338
+ const need = pos + bytes.length;
339
+ if (need > entry.bytes.length) {
340
+ const grown = new Uint8Array(need);
341
+ grown.set(entry.bytes); entry.bytes = grown;
342
+ }
343
+ entry.bytes.set(bytes, pos);
344
+ markWritten(s, path);
345
+ }
346
+ function mtimeNs(s: BashSession, path: string): bigint {
347
+ const t = s.fs.times.get(path);
348
+ return t === undefined ? s.fs.sessionNs : t;
349
+ }
350
+ function touchPath(s: BashSession, path: string): void { s.fs.times.set(path, realtimeNs()); }
351
+ function statBuf(dv: DataView, u8: Uint8Array, buf: number, filetype: number, size: number, timeNs: bigint): void {
352
+ u8.fill(0, buf, buf + 64);
353
+ dv.setUint8(buf + 16, filetype);
354
+ dv.setBigUint64(buf + 24, 1n, true);
355
+ dv.setBigUint64(buf + 32, BigInt(size), true);
356
+ dv.setBigUint64(buf + 40, timeNs, true);
357
+ dv.setBigUint64(buf + 48, timeNs, true);
358
+ dv.setBigUint64(buf + 56, timeNs, true);
359
+ }
360
+
361
+ // Shared WASI surface over the process fd table + file layer. The io
362
+ // argument abstracts the blocking discipline: bash instances
363
+ // asyncify-park, exec'd plain-WASI tools synchronously pump the scheduler.
364
+ //
365
+ // pathBase (exec'd coreutils only) emulates the child's inherited cwd. An
366
+ // exec'd tool's wasi-libc has cwd '/', so it absolutizes BOTH its own
367
+ // relative args and absolute args against '/' — they reach path_open
368
+ // IDENTICALLY un-prefixed (e.g. 'ls tmp' and 'ls /tmp' both arrive 'tmp';
369
+ // 'ls' and 'ls /' both arrive ''). The lost absolute-vs-relative bit is
370
+ // recovered from absRoots: the normalized set of absolute argv paths bash
371
+ // passed the tool. A path that IS (or descends from) one of those is
372
+ // absolute-origin — the arriving string is already the correct
373
+ // root-relative target, so it is NEVER re-anchored. Everything else is
374
+ // relative-origin (a relative arg, or a child name synthesized while
375
+ // listing a directory): re-anchor against the inherited cwd, preferring
376
+ // the cwd-joined path, then the bare one, then whichever parent dir
377
+ // exists (touch newfile in the session cwd vs a '/'-listing's children).
378
+ function isUnderAbsRoot(p: string, absRoots: Set<string> | undefined): boolean {
379
+ if (!absRoots) return false;
380
+ for (const a of absRoots) {
381
+ if (p === a) return true;
382
+ if (a !== '' && p.startsWith(a + '/')) return true;
383
+ }
384
+ return false;
385
+ }
386
+ function makeResolve(s: BashSession, pathBase?: string, absRoots?: Set<string>): (raw: string) => string {
387
+ return (raw) => {
388
+ const p = norm(raw);
389
+ if (!pathBase) return p;
390
+ if (isUnderAbsRoot(p, absRoots)) return p;
391
+ const joined = norm(pathBase + '/' + p);
392
+ if (inodeExists(s, joined)) return joined;
393
+ if (inodeExists(s, p)) return p;
394
+ if (isDir(s, parentOf(joined))) return joined;
395
+ if (isDir(s, parentOf(p))) return p;
396
+ return joined;
397
+ };
398
+ }
399
+ // The rest of the preview1 surface. These are NOT stubs that claim success:
400
+ // each one either is genuinely a no-op on an in-memory filesystem, or answers
401
+ // ENOSYS. The old blanket fallback returned ESUCCESS for all of them without
402
+ // writing their out-params, so a guest read uninitialised memory and believed
403
+ // the call had worked — silent wrong data, the worst failure available.
404
+ function makeUnsupported(s: BashSession): BashUnsupportedImports {
405
+ const nosys = (name: string) => (): BashErrno => { s.missingWasi.add(name); return E.NOSYS; };
406
+ return {
407
+ // Every write is already durable in the session's own heap, so there is
408
+ // nothing to flush and success is the honest answer.
409
+ fd_sync: () => 0,
410
+ fd_datasync: () => 0,
411
+ fd_advise: () => 0,
412
+ // One process runs at a time under this scheduler; a yield has nothing to
413
+ // yield to that the caller has not already reached.
414
+ sched_yield: () => 0,
415
+ fd_pread: nosys('fd_pread'),
416
+ fd_pwrite: nosys('fd_pwrite'),
417
+ fd_allocate: nosys('fd_allocate'),
418
+ fd_filestat_set_size: nosys('fd_filestat_set_size'),
419
+ fd_filestat_set_times: nosys('fd_filestat_set_times'),
420
+ fd_fdstat_set_rights: nosys('fd_fdstat_set_rights'),
421
+ proc_raise: nosys('proc_raise'),
422
+ sock_send: nosys('sock_send'),
423
+ sock_recv: nosys('sock_recv'),
424
+ sock_shutdown: nosys('sock_shutdown'),
425
+ };
426
+ }
427
+ function makeWasiFs(
428
+ s: BashSession, proc: BashProc, DV: () => DataView, U8: () => Uint8Array,
429
+ io: BashIo, pathBase?: string, absRoots?: Set<string>,
430
+ ): BashWasiFsImports {
431
+ const resolve = makeResolve(s, pathBase, absRoots);
432
+ return {
433
+ ...makeUnsupported(s),
434
+ fd_prestat_get: (fd, buf) => { if (fd === 3) { DV().setUint8(buf, 0); DV().setUint32(buf + 4, 1, true); return 0; } return E.BADF; },
435
+ // The buffer length is a contract, not decoration: fd_prestat_get reports
436
+ // the name is 1 byte, and a guest that offers less must not be written to.
437
+ fd_prestat_dir_name: (fd, path, plen) => {
438
+ if (fd !== 3) return E.BADF;
439
+ if (plen < 1) return E.INVAL;
440
+ U8()[path] = 0x2f;
441
+ return 0;
442
+ },
443
+ path_open: (dirfd, dirflags, pathPtr, pathLen, oflags, rightsBase, _ri, fdflags, retPtr) => {
444
+ const raw = resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
445
+ // SYMLINK_FOLLOW (lookupflags bit 0). Without it only the leading
446
+ // directories resolve, so O_NOFOLLOW opens the link itself.
447
+ const r = (dirflags & 1) !== 0 ? followPath(s, raw) : followParents(s, raw);
448
+ if (r.errno) return r.errno;
449
+ const path = r.path;
450
+ const dv = DV();
451
+ if (path === 'dev/null' || path === 'dev/tty') {
452
+ const fd = lowestFd(proc); proc.fds.set(fd, { kind: path === 'dev/tty' ? 'tty' : 'null' });
453
+ dv.setUint32(retPtr, fd, true); return 0;
454
+ }
455
+ const trav = checkTraversal(s, path);
456
+ if (trav) return trav;
457
+ const wantDir = (oflags & 2) !== 0;
458
+ if (isDir(s, path)) {
459
+ if ((effMode(s, path) & 1) === 0) return E.ACCES;
460
+ const fd = lowestFd(proc); proc.fds.set(fd, { kind: 'dir', path });
461
+ dv.setUint32(retPtr, fd, true); return 0;
462
+ }
463
+ if (wantDir) return fileExists(s, path) ? E.NOTDIR : E.NOENT;
464
+ // wasi-libc encodes the open intent in the rights: fd_read is bit 1,
465
+ // fd_write bit 6. Enforce the S2a effective mode accordingly.
466
+ const rights = typeof rightsBase === 'bigint' ? rightsBase : BigInt(rightsBase >>> 0);
467
+ let need = 0;
468
+ if ((rights & 2n) !== 0n) need |= 4;
469
+ if ((rights & 64n) !== 0n) need |= 2;
470
+ if ((oflags & 8) !== 0) need |= 2; // O_TRUNC implies write
471
+ let entry = fileLookup(s, path);
472
+ const exists = entry !== null || fileExists(s, path);
473
+ if (exists && (oflags & 4)) return E.EXIST; // O_EXCL
474
+ if (!exists) {
475
+ if (!(oflags & 1)) return E.NOENT; // no O_CREAT
476
+ const denied = checkParentWritable(s, path);
477
+ if (denied) return denied;
478
+ entry = { bytes: new Uint8Array(0) };
479
+ s.fs.files.set(path, entry); markWritten(s, path);
480
+ } else {
481
+ if (need && (effMode(s, path) & need) !== need) return E.ACCES;
482
+ if (!entry) {
483
+ // Exists per the mode map but bytes were not snapshotted
484
+ // (write-only). Start from empty content.
485
+ entry = { bytes: new Uint8Array(0) };
486
+ s.fs.files.set(path, entry);
487
+ }
488
+ if (oflags & 8) { // O_TRUNC
489
+ entry.bytes = new Uint8Array(0); markWritten(s, path);
490
+ }
491
+ }
492
+ const fd = lowestFd(proc);
493
+ proc.fds.set(fd, { kind: 'file', path, pos: 0, append: (fdflags & 1) !== 0 });
494
+ dv.setUint32(retPtr, fd, true);
495
+ return 0;
496
+ },
497
+ fd_filestat_get: (fd, buf) => {
498
+ const e = proc.fds.get(fd);
499
+ if (!e) return E.BADF;
500
+ if (e.kind === 'file') { const f = fileLookup(s, e.path); statBuf(DV(), U8(), buf, 4, f ? f.bytes.length : 0, mtimeNs(s, e.path)); return 0; }
501
+ if (e && (e.kind === 'dir' || e.kind === 'preopen')) { statBuf(DV(), U8(), buf, 3, 0, mtimeNs(s, e.kind === 'preopen' ? '' : e.path)); return 0; }
502
+ statBuf(DV(), U8(), buf, e && (e.kind === 'stdin' || e.kind === 'stdout' || e.kind === 'stderr' || e.kind === 'tty') ? 2 : 0, 0, realtimeNs());
503
+ return 0;
504
+ },
505
+ path_filestat_get: (dirfd, flags, pathPtr, pathLen, buf) => {
506
+ const raw = resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
507
+ if (raw === 'dev/null' || raw === 'dev/tty') { statBuf(DV(), U8(), buf, 2, 0, realtimeNs()); return 0; }
508
+ // SYMLINK_FOLLOW (bit 0) distinguishes stat from lstat: without it the
509
+ // link itself is the subject, which is how 'test -L' and 'ls -l' tell a
510
+ // symlink apart from what it points at.
511
+ const follow = (flags & 1) !== 0;
512
+ if (!follow && s.fs.symlinks.has(raw)) {
513
+ statBuf(DV(), U8(), buf, 7, te.encode(s.fs.symlinks.get(raw) as string).length, mtimeNs(s, raw));
514
+ return 0;
515
+ }
516
+ const r = followPath(s, raw);
517
+ if (r.errno) return r.errno;
518
+ const path = r.path;
519
+ const trav = checkTraversal(s, path);
520
+ if (trav) return trav;
521
+ const f = fileLookup(s, path);
522
+ if (f) { statBuf(DV(), U8(), buf, 4, f.bytes.length, mtimeNs(s, path)); return 0; }
523
+ if (isCoreutil(s, path)) { statBuf(DV(), U8(), buf, 4, 1024, mtimeNs(s, path)); return 0; }
524
+ if (isDir(s, path)) { statBuf(DV(), U8(), buf, 3, 0, mtimeNs(s, path)); return 0; }
525
+ if (fileExists(s, path)) { statBuf(DV(), U8(), buf, 4, 0, mtimeNs(s, path)); return 0; } // unreadable: size unknown
526
+ return E.NOENT;
527
+ },
528
+ // fstflags: ATIM=1, ATIM_NOW=2, MTIM=4, MTIM_NOW=8. Only the mtime half is
529
+ // recorded — this layer keeps one timestamp per inode, and mtime is the
530
+ // one every build tool reads.
531
+ path_filestat_set_times: (dirfd, _flags, pathPtr, pathLen, _atim, mtim, fstflags) => {
532
+ const path = resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
533
+ if (!inodeExists(s, path) && !s.fs.symlinks.has(path)) return E.NOENT;
534
+ if (fstflags & 8) s.fs.times.set(path, realtimeNs());
535
+ else if (fstflags & 4) s.fs.times.set(path, typeof mtim === 'bigint' ? mtim : BigInt(mtim >>> 0));
536
+ return 0;
537
+ },
538
+ path_unlink_file: (dirfd, pathPtr, pathLen) => {
539
+ // unlink removes the link, never what it points at.
540
+ const r = followParents(s, resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen))));
541
+ if (r.errno) return r.errno;
542
+ const path = r.path;
543
+ const trav = checkTraversal(s, path);
544
+ if (trav) return trav;
545
+ if (isDir(s, path)) return E.ISDIR;
546
+ if (!fileExists(s, path) && !s.fs.symlinks.has(path)) return E.NOENT;
547
+ const denied = checkParentWritable(s, path);
548
+ if (denied) return denied;
549
+ recordFileRemoved(s, path);
550
+ return 0;
551
+ },
552
+ path_rename: (fd1, oldPtr, oldLen, fd2, newPtr, newLen) => {
553
+ const from = resolve(td.decode(U8().subarray(oldPtr, oldPtr + oldLen)));
554
+ const to = resolve(td.decode(U8().subarray(newPtr, newPtr + newLen)));
555
+ let trav = checkTraversal(s, from);
556
+ if (trav) return trav;
557
+ trav = checkTraversal(s, to);
558
+ if (trav) return trav;
559
+ const fromIsDir = from !== '' && isDir(s, from);
560
+ const f = fileLookup(s, from);
561
+ if (!fromIsDir && !f && !fileExists(s, from)) return E.NOENT;
562
+ if (from === to) return 0;
563
+ let denied = checkParentWritable(s, from);
564
+ if (!denied) denied = checkParentWritable(s, to);
565
+ if (denied) return denied;
566
+ const moveMode = (a: string, b: string) => {
567
+ const m = s.fs.modes.get(a); s.fs.modes.delete(a);
568
+ if (m !== undefined) s.fs.modes.set(b, m);
569
+ };
570
+ // Atomic-overwrite destination of the matching kind.
571
+ if (isDir(s, to)) {
572
+ if (!fromIsDir) return E.ISDIR;
573
+ const prefix = to + '/';
574
+ for (const p of s.fs.files.keys()) if (p.startsWith(prefix)) return E.NOTEMPTY;
575
+ for (const p of s.fs.dirs) if (p.startsWith(prefix)) return E.NOTEMPTY;
576
+ recordDirRemoved(s, to);
577
+ } else if (fileExists(s, to)) {
578
+ if (fromIsDir) return E.NOTDIR;
579
+ recordFileRemoved(s, to);
580
+ }
581
+ if (fromIsDir) {
582
+ const mode = s.fs.modes.get(from);
583
+ recordDirRemoved(s, from);
584
+ recordDirAdded(s, to);
585
+ if (mode !== undefined) s.fs.modes.set(to, mode);
586
+ const prefix = from + '/';
587
+ const rebase = (key: string) => to + '/' + key.slice(prefix.length);
588
+ for (const key of [...s.fs.files.keys()]) {
589
+ if (!key.startsWith(prefix)) continue;
590
+ const nk = rebase(key);
591
+ const entry = s.fs.files.get(key) as BashFileEntry;
592
+ recordFileRemoved(s, key);
593
+ moveMode(key, nk);
594
+ s.fs.files.set(nk, entry);
595
+ s.fs.written.add(nk); s.fs.deleted.delete(nk);
596
+ if (!s.fs.modes.has(nk)) s.fs.modes.set(nk, 6);
597
+ }
598
+ for (const key of [...s.fs.dirs]) {
599
+ if (!key.startsWith(prefix)) continue;
600
+ const nk = rebase(key);
601
+ const mode2 = s.fs.modes.get(key);
602
+ recordDirRemoved(s, key);
603
+ recordDirAdded(s, nk);
604
+ if (mode2 !== undefined) s.fs.modes.set(nk, mode2);
605
+ }
606
+ return 0;
607
+ }
608
+ const entry = f || { bytes: new Uint8Array(0) };
609
+ const mode = s.fs.modes.get(from);
610
+ recordFileRemoved(s, from);
611
+ s.fs.files.set(to, entry); markWritten(s, to);
612
+ if (mode !== undefined) s.fs.modes.set(to, mode);
613
+ return 0;
614
+ },
615
+ path_create_directory: (dirfd, pathPtr, pathLen) => {
616
+ const path = resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
617
+ const trav = checkTraversal(s, path);
618
+ if (trav) return trav;
619
+ if (isDir(s, path) || fileExists(s, path)) return E.EXIST;
620
+ const denied = checkParentWritable(s, path);
621
+ if (denied) return denied;
622
+ recordDirAdded(s, path);
623
+ return 0;
624
+ },
625
+ // path_readlink(fd, path, path_len, buf, buf_len, *bufused). Never follows
626
+ // the last component — reading a link is the one op that is about the link.
627
+ path_readlink: (dirfd, pathPtr, pathLen, bufPtr, bufLen, bufUsedPtr) => {
628
+ const r = followParents(s, resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen))));
629
+ if (r.errno) return r.errno;
630
+ const target = s.fs.symlinks.get(r.path);
631
+ if (target === undefined) return inodeExists(s, r.path) ? E.INVAL : E.NOENT;
632
+ const bytes = te.encode(target);
633
+ const n = Math.min(bytes.length, bufLen);
634
+ U8().set(bytes.subarray(0, n), bufPtr);
635
+ DV().setUint32(bufUsedPtr, n, true);
636
+ return 0;
637
+ },
638
+ // path_symlink(old_path, old_path_len, fd, new_path, new_path_len) — the
639
+ // target comes FIRST and is not a path in this filesystem: it is stored
640
+ // verbatim and may dangle, exactly as ln -s allows.
641
+ path_symlink: (oldPtr, oldLen, newFd, newPtr, newLen) => {
642
+ const target = td.decode(U8().subarray(oldPtr, oldPtr + oldLen));
643
+ const r = followParents(s, resolve(td.decode(U8().subarray(newPtr, newPtr + newLen))));
644
+ if (r.errno) return r.errno;
645
+ const link = r.path;
646
+ const trav = checkTraversal(s, link);
647
+ if (trav) return trav;
648
+ if (inodeExists(s, link) || s.fs.symlinks.has(link)) return E.EXIST;
649
+ const denied = checkParentWritable(s, link);
650
+ if (denied) return denied;
651
+ s.fs.symlinks.set(link, target);
652
+ s.fs.symlinksCreated.set(link, target);
653
+ s.fs.modes.set(link, 7);
654
+ s.fs.deleted.delete(link);
655
+ touchPath(s, link);
656
+ return 0;
657
+ },
658
+ path_link: (fd1, _lookupFlags, oldPtr, oldLen, fd2, newPtr, newLen) => {
659
+ const from = resolve(td.decode(U8().subarray(oldPtr, oldPtr + oldLen)));
660
+ const to = resolve(td.decode(U8().subarray(newPtr, newPtr + newLen)));
661
+ let trav = checkTraversal(s, from);
662
+ if (trav) return trav;
663
+ trav = checkTraversal(s, to);
664
+ if (trav) return trav;
665
+ if (isDir(s, from)) return E.PERM;
666
+ const f = fileLookup(s, from);
667
+ if (!f) return fileExists(s, from) ? E.ACCES : E.NOENT;
668
+ if (fileExists(s, to) || isDir(s, to)) return E.EXIST;
669
+ const denied = checkParentWritable(s, to);
670
+ if (denied) return denied;
671
+ // Both names share ONE entry object — writes through either alias
672
+ // mutate the same bytes, which is real hard-link semantics here.
673
+ s.fs.files.set(to, f); markWritten(s, to);
674
+ s.fs.modes.set(to, effMode(s, from));
675
+ return 0;
676
+ },
677
+ path_remove_directory: (dirfd, pathPtr, pathLen) => {
678
+ const path = resolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
679
+ const trav = checkTraversal(s, path);
680
+ if (trav) return trav;
681
+ if (path === '' || path === 'etc' || path === 'dev' || path === 'bin' || path === 'usr' || path === 'usr/bin') return E.ACCES;
682
+ if (!isDir(s, path)) return fileExists(s, path) ? E.NOTDIR : E.NOENT;
683
+ const denied = checkParentWritable(s, path);
684
+ if (denied) return denied;
685
+ const prefix = path + '/';
686
+ for (const p of s.fs.files.keys()) if (p.startsWith(prefix)) return E.NOTEMPTY;
687
+ for (const p of s.fs.dirs) if (p.startsWith(prefix)) return E.NOTEMPTY;
688
+ for (const p of s.fs.modes.keys()) if (p.startsWith(prefix)) return E.NOTEMPTY;
689
+ recordDirRemoved(s, path);
690
+ return 0;
691
+ },
692
+ fd_renumber: (from, to) => {
693
+ const e = proc.fds.get(from);
694
+ if (!e) return E.BADF;
695
+ if (from !== to) {
696
+ closeFd(s, proc, to);
697
+ proc.fds.set(to, e);
698
+ proc.fds.delete(from);
699
+ }
700
+ return 0;
701
+ },
702
+ fd_readdir: (fd, buf, bufLen, cookie, retPtr) => {
703
+ const e = proc.fds.get(fd);
704
+ if (!e || (e.kind !== 'dir' && e.kind !== 'preopen')) return E.BADF;
705
+ const dir = e.kind === 'preopen' ? '' : e.path;
706
+ if ((effMode(s, dir) & 4) === 0) return E.ACCES;
707
+ const prefix = dir ? dir + '/' : '';
708
+ const seen = new Set(['.', '..']);
709
+ const children: Array<{ name: string; type: number }> = [];
710
+ const push = (name: string, type: number) => { if (!seen.has(name)) { seen.add(name); children.push({ name, type }); } };
711
+ for (const p of s.fs.dirs) {
712
+ if (p !== dir && p.startsWith(prefix) && !p.slice(prefix.length).includes('/')) push(p.slice(prefix.length), 3);
713
+ }
714
+ for (const p of s.fs.files.keys()) {
715
+ if (p.startsWith(prefix) && !p.slice(prefix.length).includes('/')) push(p.slice(prefix.length), 4);
716
+ }
717
+ for (const p of s.fs.symlinks.keys()) {
718
+ if (p.startsWith(prefix) && !p.slice(prefix.length).includes('/')) push(p.slice(prefix.length), 7);
719
+ }
720
+ for (const p of s.fs.modes.keys()) { // modes-only inodes (unreadable files)
721
+ if (p !== dir && p.startsWith(prefix) && !p.slice(prefix.length).includes('/') && !s.fs.dirs.has(p)) push(p.slice(prefix.length), 4);
722
+ }
723
+ if (dir === 'bin' || dir === 'usr/bin') for (const name of s.coreutils.keys()) push(name, 4);
724
+ children.sort((a, b) => (a.name < b.name ? -1 : 1));
725
+ const entries = [{ name: '.', type: 3 }, { name: '..', type: 3 }, ...children];
726
+ const dv = DV(), u8 = U8();
727
+ let off = 0;
728
+ for (let i = Number(cookie); i < entries.length; i++) {
729
+ const nb = te.encode(entries[i].name);
730
+ const need = 24 + nb.length;
731
+ const record = new Uint8Array(need);
732
+ const rdv = new DataView(record.buffer);
733
+ rdv.setBigUint64(0, BigInt(i + 1), true); // d_next: cookie of the next entry
734
+ rdv.setBigUint64(8, 1n, true); // d_ino
735
+ rdv.setUint32(16, nb.length, true); // d_namlen
736
+ record[20] = entries[i].type; // d_type
737
+ record.set(nb, 24);
738
+ const room = bufLen - off;
739
+ if (need > room) { // truncated tail: "more remain"
740
+ u8.set(record.subarray(0, room), buf + off);
741
+ off = bufLen;
742
+ break;
743
+ }
744
+ u8.set(record, buf + off);
745
+ off += need;
746
+ }
747
+ dv.setUint32(retPtr, off, true);
748
+ return 0;
749
+ },
750
+ // An fd that was never opened is EBADF everywhere below. It used to be
751
+ // ESPIPE from fd_seek and plain SUCCESS from fd_tell and fd_filestat_get,
752
+ // while fd_close, fd_fdstat_get and fd_write in this same table already
753
+ // answered EBADF — one descriptor table, five different opinions about what
754
+ // a closed descriptor is. ESPIPE in particular is a yes: it means "open, and
755
+ // not seekable", so a caller using lseek to test validity read it as valid.
756
+ fd_seek: (fd, offset, whence, retPtr) => {
757
+ const e = proc.fds.get(fd);
758
+ if (!e) return E.BADF;
759
+ if (e.kind === 'file') {
760
+ const f = fileLookup(s, e.path); const len = f ? f.bytes.length : 0;
761
+ const off = Number(offset);
762
+ const next = whence === 0 ? off : whence === 1 ? e.pos + off : len + off;
763
+ if (next < 0) return E.INVAL;
764
+ e.pos = next;
765
+ DV().setBigUint64(retPtr, BigInt(next), true);
766
+ return 0;
767
+ }
768
+ DV().setBigUint64(retPtr, 0n, true);
769
+ return E.SPIPE;
770
+ },
771
+ fd_tell: (fd, retPtr) => {
772
+ const e = proc.fds.get(fd);
773
+ if (!e) return E.BADF;
774
+ DV().setBigUint64(retPtr, BigInt(e.kind === 'file' ? e.pos : 0), true);
775
+ return 0;
776
+ },
777
+ fd_close: (fd) => {
778
+ if (!proc.fds.has(fd)) return E.BADF;
779
+ closeFd(s, proc, fd);
780
+ return 0;
781
+ },
782
+ fd_fdstat_get: (fd, st) => {
783
+ const dv = DV(); const e = proc.fds.get(fd);
784
+ let ft = 4;
785
+ if (e && e.kind === 'pipe') ft = 0;
786
+ else if (e && (e.kind === 'stdin' || e.kind === 'stdout' || e.kind === 'stderr')) ft = s.stdinTty || fd !== 0 ? 2 : 0;
787
+ else if (e && e.kind === 'tty') ft = 2;
788
+ else if (e && (e.kind === 'dir' || e.kind === 'preopen')) ft = 3;
789
+ else if (!e) return E.BADF;
790
+ dv.setUint8(st, ft);
791
+ dv.setUint16(st + 2, 0, true);
792
+ dv.setBigUint64(st + 8, 0xffffffffffffffffn, true);
793
+ dv.setBigUint64(st + 16, 0xffffffffffffffffn, true);
794
+ return 0;
795
+ },
796
+ fd_fdstat_set_flags: () => 0,
797
+ fd_read: (fd, iovs, n, nread) => io.read(fd, readIovs(DV(), iovs, n), nread),
798
+ fd_write: (fd, iovs, n, nw) => {
799
+ if (!proc.fds.has(fd)) return E.BADF;
800
+ const dv = DV(), u8 = U8(); let w = 0;
801
+ for (let i = 0; i < n; i++) {
802
+ const p = dv.getUint32(iovs + i * 8, true), l = dv.getUint32(iovs + i * 8 + 4, true);
803
+ const n2 = io.write(fd, u8.subarray(p, p + l));
804
+ if (n2 === null) return E.BADF;
805
+ w += n2;
806
+ }
807
+ dv.setUint32(nw, w, true);
808
+ return 0;
809
+ },
810
+ poll_oneoff: (inPtr, outPtr, nsubs, retPtr) => io.poll(inPtr, outPtr, nsubs, retPtr),
811
+ clock_time_get: (id, _pr, t) => {
812
+ const ns = clockNs(id);
813
+ if (ns === null) return E.INVAL;
814
+ DV().setBigUint64(t, ns, true);
815
+ return 0;
816
+ },
817
+ clock_res_get: (id, r) => {
818
+ if (clockNs(id) === null) return E.INVAL;
819
+ DV().setBigUint64(r, id === CLOCK_REALTIME ? 1000000n : 1000n, true);
820
+ return 0;
821
+ },
822
+ // getRandomValues caps at 65536 bytes per call; a guest asking for more
823
+ // gets the same CSPRNG, chunked, never a weaker one.
824
+ random_get: (b, l) => {
825
+ const u = U8();
826
+ for (let off = 0; off < l; off += 65536) {
827
+ crypto.getRandomValues(u.subarray(b + off, b + off + Math.min(l - off, 65536)));
828
+ }
829
+ return 0;
830
+ },
831
+ proc_exit: (code) => { throw new Exit(code); },
832
+ };
833
+ }
834
+
835
+ // Route a write through the process fd table. The caller has already rejected
836
+ // an fd the table does not hold, so every branch here answers a real entry —
837
+ // an unknown fd must never land in the user's terminal.
838
+ function writeThroughFd(s: BashSession, proc: BashProc, fd: number, bytes: Uint8Array): number | null {
839
+ const e = proc.fds.get(fd);
840
+ if (e && e.kind === 'pipe') {
841
+ // A pipe descriptor has a direction, and it was recorded and never read.
842
+ // Writing to the READ end used to push bytes into the pipe and report them
843
+ // written, so `exec 3< …; echo x >&3` fed the reader its own output — data
844
+ // appearing from nowhere, attributed to the wrong writer, with no error
845
+ // anywhere. POSIX makes the direction part of the descriptor: EBADF.
846
+ if (e.end === 'r') return null;
847
+ const pp = s.pipes.get(e.pipeId) as BashPipe;
848
+ pp.chunks.push(bytes.slice()); pp.queued += bytes.length;
849
+ wakePipe(s, pp);
850
+ return bytes.length;
851
+ }
852
+ if (e && e.kind === 'file') {
853
+ const f = fileLookup(s, e.path) || { bytes: new Uint8Array(0) };
854
+ if (!s.fs.files.has(e.path)) s.fs.files.set(e.path, f);
855
+ const pos = e.append ? f.bytes.length : e.pos;
856
+ fileWrite(s, f, e.path, pos, bytes);
857
+ e.pos = pos + bytes.length;
858
+ return bytes.length;
859
+ }
860
+ if (e && (e.kind === 'null' || e.kind === 'tty')) return bytes.length;
861
+ const text = td.decode(bytes);
862
+ if ((e as BashFdEntry).kind === 'stderr') s.err += text;
863
+ else s.out += text;
864
+ return bytes.length;
865
+ }
866
+
867
+ // Synchronous read for non-parking consumers (files, buffered pipes).
868
+ // Returns {errno} or null when the source would block.
869
+ function tryReadFd(
870
+ s: BashSession, proc: BashProc, fd: number, dv: DataView, u8: Uint8Array,
871
+ iov: BashIovs, nreadPtr: number,
872
+ ): { errno: BashErrno } | null {
873
+ const e = proc.fds.get(fd);
874
+ const deliver = (bytes: Uint8Array): { errno: BashErrno } => { dv.setUint32(nreadPtr, scatter(u8, iov, bytes), true); return { errno: 0 }; };
875
+ if (e && e.kind === 'file') {
876
+ const f = fileLookup(s, e.path);
877
+ const bytes = f ? f.bytes.subarray(e.pos, e.pos + iov.total) : new Uint8Array(0);
878
+ e.pos += bytes.length;
879
+ return deliver(bytes);
880
+ }
881
+ if (e && (e.kind === 'null' || e.kind === 'tty')) { dv.setUint32(nreadPtr, 0, true); return { errno: 0 }; }
882
+ if (e && e.kind === 'pipe') {
883
+ const pp = s.pipes.get(e.pipeId) as BashPipe;
884
+ if (pp.queued > 0) return deliver(takeUpTo(pp, iov.total));
885
+ if (pp.writers === 0) { dv.setUint32(nreadPtr, 0, true); return { errno: 0 }; }
886
+ return null;
887
+ }
888
+ if (e && e.kind === 'stdin') {
889
+ const st = s.stdin;
890
+ if (st.queued > 0) return deliver(takeUpTo(st, iov.total));
891
+ if (st.closed) { dv.setUint32(nreadPtr, 0, true); return { errno: 0 }; }
892
+ return null;
893
+ }
894
+ if (e) { dv.setUint32(nreadPtr, 0, true); return { errno: 0 }; }
895
+ return { errno: E.BADF };
896
+ }
897
+
898
+ // Subscription record: 48B, userdata u64 at +0, tag u8 at +8. A CLOCK carries
899
+ // id u32 at +16, timeout u64 at +24, flags u16 at +40 (bit 0 = ABSTIME); an
900
+ // FD_READ/FD_WRITE carries the fd u32 at +16.
901
+ function readSubs(dv: DataView, inPtr: number, nsubs: number): BashPollSub[] {
902
+ const subs: BashPollSub[] = [];
903
+ for (let i = 0; i < nsubs; i++) {
904
+ const base = inPtr + i * 48;
905
+ const userdata = dv.getBigUint64(base, true);
906
+ const tag = dv.getUint8(base + 8);
907
+ if (tag === 0) {
908
+ const id = dv.getUint32(base + 16, true);
909
+ const timeout = dv.getBigUint64(base + 24, true);
910
+ const abs = (dv.getUint16(base + 40, true) & 1) !== 0;
911
+ const now = clockNs(id);
912
+ // An unknown clock id cannot produce a deadline; the event reports
913
+ // EINVAL rather than firing.
914
+ subs.push(now === null
915
+ ? { tag, userdata, id, bad: true }
916
+ : { tag, userdata, id, deadline: abs ? timeout : now + timeout });
917
+ } else {
918
+ subs.push({ tag, userdata, fd: dv.getUint32(base + 16, true) });
919
+ }
920
+ }
921
+ return subs;
922
+ }
923
+ function clockExpired(sub: BashPollSub): boolean {
924
+ const now = clockNs(sub.id);
925
+ return now !== null && now >= (sub.deadline as bigint);
926
+ }
927
+ function writeEvent(dv: DataView, outPtr: number, slot: number, sub: BashPollSub, errno: BashErrno, nbytes: number): void {
928
+ const ev = outPtr + slot * 32;
929
+ dv.setBigUint64(ev, sub.userdata, true);
930
+ dv.setUint16(ev + 8, errno, true);
931
+ dv.setUint8(ev + 10, sub.tag);
932
+ dv.setBigUint64(ev + 16, BigInt(nbytes), true);
933
+ dv.setUint16(ev + 24, 0, true);
934
+ }
935
+ // Readiness of an FD_READ subscription. FD_WRITE and anything on an fd this
936
+ // table does not hold are handled by the caller.
937
+ function fdReadReady(s: BashSession, proc: BashProc, fd: number | undefined): BashFdReadiness | null {
938
+ const e = proc.fds.get(fd as number);
939
+ if (!e) return null;
940
+ if (e.kind === 'pipe') { const pp = s.pipes.get(e.pipeId) as BashPipe; return { ready: pp.queued > 0 || pp.writers === 0, avail: pp.queued }; }
941
+ if (e.kind === 'stdin') return { ready: s.stdin.queued > 0 || s.stdin.closed, avail: s.stdin.queued };
942
+ return { ready: true, avail: 0 };
943
+ }
944
+ // Emit every subscription that is ready right now. Returns the event count.
945
+ function emitReady(s: BashSession, proc: BashProc, dv: DataView, outPtr: number, subs: BashPollSub[]): number {
946
+ let n = 0;
947
+ for (const sub of subs) {
948
+ if (sub.tag === 0) {
949
+ if (sub.bad) { writeEvent(dv, outPtr, n++, sub, E.INVAL, 0); continue; }
950
+ if (clockExpired(sub)) writeEvent(dv, outPtr, n++, sub, 0, 0);
951
+ continue;
952
+ }
953
+ const st = fdReadReady(s, proc, sub.fd);
954
+ if (!st) { writeEvent(dv, outPtr, n++, sub, E.BADF, 0); continue; }
955
+ // FD_WRITE (tag 2) never blocks here: pipes and the output buffers accept
956
+ // whatever is handed to them.
957
+ if (sub.tag === 2 || st.ready) writeEvent(dv, outPtr, n++, sub, 0, st.avail);
958
+ }
959
+ return n;
960
+ }
961
+ // Spend a clock subscription's interval by running whatever else is runnable.
962
+ //
963
+ // It cannot be spent waiting. This facet's clock does not advance during
964
+ // synchronous execution — 50M spin iterations move both Date.now() and
965
+ // performance.now() by exactly 0ms, which is the platform's timing-attack
966
+ // mitigation rather than a quirk. A busy-wait therefore never terminates, and
967
+ // a poll that returns no events leaves the guest spinning on the same frozen
968
+ // clock. Running the scheduler is the only progress available; past that the
969
+ // deadline is reported as reached. A host whose clock does advance gets a real
970
+ // wait, and honouring one in-facet needs poll_oneoff to become async — that is
971
+ // the migration onto runtime/wasi-instance.ts, not something a synchronous
972
+ // implementation can express.
973
+ // FROZEN_PROBE is a measurement, not a timeout: if the clock has not moved by
974
+ // a single nanosecond after this many iterations, it is not going to.
975
+ const FROZEN_PROBE = 200000;
976
+ function waitForDeadline(s: BashSession, proc: BashProc, subs: BashPollSub[]): void {
977
+ const clocks = subs.filter((x) => x.tag === 0 && !x.bad);
978
+ if (!clocks.length) return;
979
+ const startedNs = realtimeNs();
980
+ let spins = 0;
981
+ while (!clocks.some(clockExpired)) {
982
+ if (s.rootExit !== null) return;
983
+ if (subs.some((x) => x.tag === 1 && (fdReadReady(s, proc, x.fd) || { ready: true }).ready)) return;
984
+ if (s.runnable.length) { pumpOne(s); continue; }
985
+ if (++spins > FROZEN_PROBE && realtimeNs() === startedNs) return;
986
+ }
987
+ }
988
+ // Report every live clock subscription as fired. Reached only once the wait
989
+ // above can make no further progress: the alternative is an eventless success,
990
+ // which poll_oneoff may not return and which a guest cannot act on.
991
+ function emitClocks(dv: DataView, outPtr: number, subs: BashPollSub[]): number {
992
+ let n = 0;
993
+ for (const sub of subs) if (sub.tag === 0 && !sub.bad) writeEvent(dv, outPtr, n++, sub, 0, 0);
994
+ return n;
995
+ }
996
+
997
+ function blockTarget(s: BashSession, proc: BashProc, fd: number | undefined): BashBlockTarget | null {
998
+ const e = proc.fds.get(fd as number);
999
+ if (e && e.kind === 'pipe') return { list: (s.pipes.get(e.pipeId) as BashPipe).readW, wake: () => wakePipe(s, s.pipes.get(e.pipeId) as BashPipe) };
1000
+ if (e && e.kind === 'stdin') return { list: s.stdin.waiters, wake: () => wakeStdin(s) };
1001
+ return null;
1002
+ }
1003
+
1004
+ // ── per-process bash instance ─────────────────────────────────────────
1005
+ function makeProc(s: BashSession, pid: number, ppid: number, fds: Map<number, BashFdEntry>): BashProc {
1006
+ const proc = {
1007
+ pid, ppid, fds, inst: null, __s: s,
1008
+ ctx: { reason: null, rewinding: false, captureEnv: 0, ljEnv: 0, ljVal: 0, nextSlot: 0, resume: 0 },
1009
+ MAIN_BUF: 0, SLOT0: 0, pendingRead: null,
1010
+ slotByEnv: new Map(), freeSlots: [],
1011
+ } as unknown as BashProc;
1012
+ const DV = () => new DataView(proc.inst.exports.memory.buffer);
1013
+ const U8 = () => new Uint8Array(proc.inst.exports.memory.buffer);
1014
+ proc.DV = DV; proc.U8 = U8;
1015
+ const slotAddr = (i: number) => proc.SLOT0 + i * SLOT_SIZE;
1016
+ proc.slotAddr = slotAddr;
1017
+ const initHdr = (a: number, sz: number) => { const dv = DV(); dv.setUint32(a, a + 8, true); dv.setUint32(a + 4, a + sz, true); };
1018
+ proc.initHdr = initHdr;
1019
+ const wstr = (p: number, str: string) => { const b = te.encode(str); U8().set(b, p); return b.length; };
1020
+ const c = proc.ctx;
1021
+
1022
+ const io: BashIo = {
1023
+ read: (fd, iov, nread) => {
1024
+ if (proc.pendingRead) {
1025
+ proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false;
1026
+ const pr = proc.pendingRead; proc.pendingRead = null;
1027
+ DV().setUint32(pr.nreadPtr, scatter(U8(), pr.iov, pr.bytes), true);
1028
+ return 0;
1029
+ }
1030
+ const dv = DV();
1031
+ const sync = tryReadFd(s, proc, fd, dv, U8(), iov, nread);
1032
+ if (sync) return sync.errno;
1033
+ // would block: asyncify-park until bytes/EOF arrive
1034
+ dv.setUint32(nread, 0, true);
1035
+ c.reason = 'blockread';
1036
+ c.pipeReq = { fd, iov, nreadPtr: nread };
1037
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1038
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1039
+ return 0;
1040
+ },
1041
+ write: (fd, bytes) => writeThroughFd(s, proc, fd, bytes),
1042
+ poll: (inPtr, outPtr, nsubs, retPtr) => {
1043
+ if (proc.pendingRead) { // poll resume: report the fd readable
1044
+ proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false;
1045
+ const pr = proc.pendingRead; proc.pendingRead = null;
1046
+ const dv = DV();
1047
+ dv.setBigUint64(outPtr, pr.pollUserdata ?? 0n, true);
1048
+ dv.setUint16(outPtr + 8, 0, true);
1049
+ dv.setUint8(outPtr + 10, 1); // eventtype fd_read
1050
+ dv.setBigUint64(outPtr + 16, BigInt(pr.bytes.length), true);
1051
+ dv.setUint16(outPtr + 24, 0, true);
1052
+ dv.setUint32(retPtr, 1, true);
1053
+ return 0;
1054
+ }
1055
+ const dv = DV();
1056
+ const subs = readSubs(dv, inPtr, nsubs);
1057
+ let emitted = emitReady(s, proc, dv, outPtr, subs);
1058
+ if (emitted > 0) { dv.setUint32(retPtr, emitted, true); return 0; }
1059
+ // Nothing ready. A blockable fd-read subscription parks the process so
1060
+ // the host can supply input; a clock-only wait has no such source and is
1061
+ // spent in-facet.
1062
+ const blockSub = subs.find((x) => x.tag === 1 && blockTarget(s, proc, x.fd));
1063
+ if (!blockSub) {
1064
+ waitForDeadline(s, proc, subs);
1065
+ emitted = emitReady(s, proc, dv, outPtr, subs) || emitClocks(dv, outPtr, subs);
1066
+ dv.setUint32(retPtr, emitted, true);
1067
+ return 0;
1068
+ }
1069
+ dv.setUint32(retPtr, 0, true);
1070
+ c.reason = 'blockread';
1071
+ c.pipeReq = { fd: blockSub.fd as number, iov: EMPTY_IOV, nreadPtr: 0, pollUserdata: blockSub.userdata };
1072
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1073
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1074
+ return 0;
1075
+ },
1076
+ };
1077
+
1078
+ const wasiBase = makeWasiFs(s, proc, DV, U8, io);
1079
+ const wasi: BashWasiImports = {
1080
+ ...wasiBase,
1081
+ args_sizes_get: (a, b) => { const dv = DV(); dv.setUint32(a, s.argv.length, true); dv.setUint32(b, s.argv.reduce((x, v) => x + te.encode(v).length + 1, 0), true); return 0; },
1082
+ args_get: (ptrs, buf) => { const dv = DV(); let p = buf; for (const a of s.argv) { dv.setUint32(ptrs, p, true); ptrs += 4; p += wstr(p, a); U8()[p++] = 0; } return 0; },
1083
+ environ_sizes_get: (a, b) => { const dv = DV(); dv.setUint32(a, s.environ.length, true); dv.setUint32(b, s.environ.reduce((x, v) => x + te.encode(v).length + 1, 0), true); return 0; },
1084
+ environ_get: (ptrs, buf) => { const dv = DV(); let p = buf; for (const v of s.environ) { dv.setUint32(ptrs, p, true); ptrs += 4; p += wstr(p, v); U8()[p++] = 0; } return 0; },
1085
+ };
1086
+
1087
+ // Slot allocator. Each setjmp captures into a FRESH physical slot
1088
+ // (overwriting a slot in place while its snapshot is still a live
1089
+ // longjmp target corrupts the asyncify rewind — the exit-builtin's
1090
+ // jump_to_top_level recursion proved this). Correct recycling: a
1091
+ // re-setjmp of the SAME jmp_buf makes that buf's previous slot a dead
1092
+ // target (POSIX: only the most recent setjmp per buf is live), so we
1093
+ // return it to a FIFO free-list — reused only after other allocations
1094
+ // cycle through, never the just-freed address. This bounds slot use
1095
+ // for long interactive sessions (bash re-setjmps top_level per
1096
+ // command) without the in-place-overwrite hazard.
1097
+ const allocSlot = (env: number): number => {
1098
+ const prev = proc.slotByEnv.get(env);
1099
+ if (prev !== undefined) { proc.slotByEnv.delete(env); proc.freeSlots.push(prev); }
1100
+ let idx: number | undefined;
1101
+ if (proc.freeSlots.length > 1) idx = proc.freeSlots.shift();
1102
+ else if (c.nextSlot < NSLOT) idx = c.nextSlot++;
1103
+ else idx = proc.freeSlots.shift();
1104
+ if (idx === undefined) throw new Error('bash-runner: setjmp slot budget exceeded (' + NSLOT + ')');
1105
+ proc.slotByEnv.set(env, idx);
1106
+ return idx;
1107
+ };
1108
+
1109
+ const nimbus_proc: BashProcImports = {
1110
+ setjmp: (env) => {
1111
+ if (c.rewinding) { proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false; return; }
1112
+ c.reason = 'capture'; c.captureEnv = env;
1113
+ const idx = allocSlot(env);
1114
+ const dv = DV(); dv.setInt32(env, idx, true); dv.setInt32(env + 4, 0, true);
1115
+ initHdr(slotAddr(idx), SLOT_SIZE);
1116
+ proc.inst.exports.asyncify_start_unwind(slotAddr(idx));
1117
+ },
1118
+ longjmp: (env, val) => {
1119
+ if (c.rewinding) { proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false; return; }
1120
+ c.reason = 'longjmp'; c.ljEnv = env; c.ljVal = val;
1121
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1122
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1123
+ },
1124
+ fork: () => {
1125
+ if (c.rewinding) { proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false; return c.resume; }
1126
+ c.reason = 'fork';
1127
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1128
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1129
+ return 0;
1130
+ },
1131
+ vfork: () => nimbus_proc.fork(),
1132
+ waitpid: (pid, statusPtr, _opt) => {
1133
+ if (c.rewinding) {
1134
+ proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false;
1135
+ if (c.waitStatusPtr != null) DV().setInt32(c.waitStatusPtr, c.resumeStatus, true);
1136
+ return c.resume;
1137
+ }
1138
+ c.reason = 'waitpid'; c.waitTarget = pid; c.waitStatusPtr = statusPtr;
1139
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1140
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1141
+ return 0;
1142
+ },
1143
+ execve: (pathPtr, argvFlatPtr, argvLen, envFlatPtr, envLen) => {
1144
+ if (c.rewinding) { proc.inst.exports.asyncify_stop_rewind(); c.rewinding = false; return c.resume; }
1145
+ const u8 = U8();
1146
+ let e = pathPtr; while (u8[e]) e++;
1147
+ c.reason = 'exec';
1148
+ c.execPath = td.decode(u8.subarray(pathPtr, e));
1149
+ c.execArgv = td.decode(u8.subarray(argvFlatPtr, argvFlatPtr + argvLen)).split('\0').filter((x) => x.length);
1150
+ // The child's REAL environment (bash's export set at exec time —
1151
+ // PWD tracks the shell's cd, unlike the boot-time s.environ).
1152
+ c.execEnv = td.decode(u8.subarray(envFlatPtr, envFlatPtr + envLen)).split('\0').filter((x) => x.length);
1153
+ initHdr(proc.MAIN_BUF, MAIN_SIZE);
1154
+ proc.inst.exports.asyncify_start_unwind(proc.MAIN_BUF);
1155
+ return 0;
1156
+ },
1157
+ pipe: (fdsPtr) => {
1158
+ const id = newPipe(s);
1159
+ const rfd = lowestFd(proc); proc.fds.set(rfd, { kind: 'pipe', pipeId: id, end: 'r' });
1160
+ const wfd = lowestFd(proc); proc.fds.set(wfd, { kind: 'pipe', pipeId: id, end: 'w' });
1161
+ const dv = DV(); dv.setInt32(fdsPtr, rfd, true); dv.setInt32(fdsPtr + 4, wfd, true);
1162
+ return 0;
1163
+ },
1164
+ dup: (o) => {
1165
+ const e = proc.fds.get(o); if (!e) return -E.BADF;
1166
+ const nf = lowestFd(proc); proc.fds.set(nf, { ...e });
1167
+ if (e.kind === 'pipe') bumpPipe(s, e, 1);
1168
+ return nf;
1169
+ },
1170
+ dup2: (o, n) => {
1171
+ const e = proc.fds.get(o); if (!e) return -E.BADF;
1172
+ if (o === n) return n;
1173
+ if (proc.fds.has(n)) closeFd(s, proc, n);
1174
+ proc.fds.set(n, { ...e });
1175
+ if (e.kind === 'pipe') bumpPipe(s, e, 1);
1176
+ return n;
1177
+ },
1178
+ kill: () => 0, setpgid: () => 0, getpgid: () => proc.pid, getppid: () => proc.ppid,
1179
+ tcsetpgrp: () => 0, tcgetpgrp: () => proc.pid, tcgetattr: () => -1, tcsetattr: () => 0,
1180
+ };
1181
+ const envImports = {
1182
+ getpid: () => proc.pid, getuid: () => 0, geteuid: () => 0, getgid: () => 0, getegid: () => 0,
1183
+ setuid: () => 0, setgid: () => 0, umask: () => 0o22,
1184
+ gethostname: (p: number, _l: number) => { U8().set(te.encode('nimbus'), p); return 0; },
1185
+ dlopen: () => 0, dlsym: () => 0, dlclose: () => 0, dlerror: () => 0,
1186
+ };
1187
+ proc.inst = new WebAssembly.Instance(s.mod, { wasi_snapshot_preview1: wasi, nimbus_proc, env: envImports }) as BashInstance;
1188
+ s.stats.instances++;
1189
+ s.procs.set(pid, proc);
1190
+ return proc;
1191
+ }
1192
+
1193
+ function setupArena(proc: BashProc): void {
1194
+ const base = proc.inst.exports.memory.buffer.byteLength;
1195
+ const need = MAIN_SIZE + NSLOT * SLOT_SIZE;
1196
+ proc.inst.exports.memory.grow(Math.ceil(need / PAGE));
1197
+ proc.MAIN_BUF = base;
1198
+ proc.SLOT0 = proc.MAIN_BUF + MAIN_SIZE;
1199
+ }
1200
+
1201
+ // ── scheduler ─────────────────────────────────────────────────────────
1202
+ function resumeProc(proc: BashProc): void {
1203
+ proc.ctx.rewinding = true;
1204
+ proc.inst.exports.asyncify_start_rewind(proc.MAIN_BUF);
1205
+ proc.__s.runnable.push(proc);
1206
+ }
1207
+
1208
+ function trackArena(s: BashSession, proc: BashProc, bufAddr: number, size: number, isSlot: boolean): void {
1209
+ const used = proc.DV().getUint32(bufAddr, true) - (bufAddr + 8);
1210
+ if (isSlot) { if (used > s.stats.slotHi) s.stats.slotHi = used; }
1211
+ else if (used > s.stats.mainHi) s.stats.mainHi = used;
1212
+ }
1213
+
1214
+ function step(s: BashSession, proc: BashProc): void {
1215
+ const c = proc.ctx, ex = proc.inst.exports;
1216
+ try { ex._start(); }
1217
+ catch (e) {
1218
+ if (e instanceof Exit) { finishProc(s, proc, e.code); return; }
1219
+ throw e;
1220
+ }
1221
+ if (c.reason === null) { finishProc(s, proc, 0); return; }
1222
+ ex.asyncify_stop_unwind();
1223
+ const r = c.reason; c.reason = null;
1224
+ const dv = proc.DV();
1225
+ const mem = proc.inst.exports.memory.buffer.byteLength;
1226
+ if (mem > s.stats.memPeak) s.stats.memPeak = mem;
1227
+ if (r === 'capture') {
1228
+ const idx = dv.getInt32(c.captureEnv, true);
1229
+ trackArena(s, proc, proc.slotAddr(idx), SLOT_SIZE, true);
1230
+ dv.setUint32(c.captureEnv + 8, dv.getUint32(proc.slotAddr(idx), true), true);
1231
+ c.rewinding = true;
1232
+ ex.asyncify_start_rewind(proc.slotAddr(idx));
1233
+ s.runnable.push(proc);
1234
+ } else if (r === 'longjmp') {
1235
+ trackArena(s, proc, proc.MAIN_BUF, MAIN_SIZE, false);
1236
+ const idx = dv.getInt32(c.ljEnv, true), hw = dv.getUint32(c.ljEnv + 8, true);
1237
+ dv.setInt32(c.ljEnv + 4, c.ljVal, true);
1238
+ dv.setUint32(proc.slotAddr(idx), hw, true);
1239
+ c.rewinding = true;
1240
+ ex.asyncify_start_rewind(proc.slotAddr(idx));
1241
+ s.runnable.push(proc);
1242
+ } else if (r === 'fork') {
1243
+ trackArena(s, proc, proc.MAIN_BUF, MAIN_SIZE, false);
1244
+ doFork(s, proc);
1245
+ } else if (r === 'waitpid') {
1246
+ trackArena(s, proc, proc.MAIN_BUF, MAIN_SIZE, false);
1247
+ doWait(s, proc);
1248
+ } else if (r === 'blockread') {
1249
+ trackArena(s, proc, proc.MAIN_BUF, MAIN_SIZE, false);
1250
+ const target = blockTarget(s, proc, c.pipeReq.fd);
1251
+ if (!target) { // fd closed under us: deliver EOF
1252
+ proc.pendingRead = { iov: c.pipeReq.iov, bytes: new Uint8Array(0), nreadPtr: c.pipeReq.nreadPtr, pollUserdata: c.pipeReq.pollUserdata };
1253
+ resumeProc(proc);
1254
+ } else {
1255
+ target.list.push({ proc });
1256
+ target.wake();
1257
+ }
1258
+ } else if (r === 'exec') {
1259
+ trackArena(s, proc, proc.MAIN_BUF, MAIN_SIZE, false);
1260
+ doExec(s, proc);
1261
+ } else {
1262
+ throw new Error('bash-runner: unknown unwind reason ' + r);
1263
+ }
1264
+ }
1265
+
1266
+ function pumpOne(s: BashSession): boolean {
1267
+ if (!s.runnable.length) return false;
1268
+ step(s, s.runnable.shift() as BashProc);
1269
+ return true;
1270
+ }
1271
+
1272
+ // exec re-homes the forked child onto a staged plain-WASI coreutil
1273
+ // bound to the process fd table (M2 exec-into-runner, in-facet). The
1274
+ // tool's blocking pipe reads synchronously pump the writer procs.
1275
+ function doExec(s: BashSession, proc: BashProc): void {
1276
+ const name = proc.ctx.execPath.split('/').pop() as string;
1277
+ // The child inherits bash's LIVE cwd: bash keeps the exported PWD
1278
+ // current across cd, and the execve import threads the child env.
1279
+ const env = proc.ctx.execEnv && proc.ctx.execEnv.length ? proc.ctx.execEnv : s.environ;
1280
+ const pwdVar = env.find((x) => x.startsWith('PWD='));
1281
+ const childCwd = pwdVar ? norm(pwdVar.slice(4)) : s.cwd;
1282
+ const path = makeResolve(s, childCwd)(proc.ctx.execPath);
1283
+ // Applets dispatch only from the PATH dirs they are staged in — a user
1284
+ // file that happens to share an applet's name (./ls) is NOT the applet.
1285
+ const viaPath = path.startsWith('bin/') || path.startsWith('usr/bin/');
1286
+ const m = viaPath ? s.coreutils.get(name) : null;
1287
+ if (!m) {
1288
+ // wasi-libc errno numbering: EACCES=2, ENOENT=44, ENOEXEC=45. An
1289
+ // existing non-wasm file gets ENOEXEC so bash falls back to running
1290
+ // it as a shell script (execute_disk_command's ENOEXEC path); an
1291
+ // unreadable one gets EACCES.
1292
+ proc.ctx.resume = fileLookup(s, path) ? -45 : (fileExists(s, path) ? -2 : -44);
1293
+ proc.ctx.rewinding = true;
1294
+ proc.inst.exports.asyncify_start_rewind(proc.MAIN_BUF);
1295
+ s.runnable.push(proc);
1296
+ return;
1297
+ }
1298
+ let inst2: BashInstance;
1299
+ const DV = () => new DataView(inst2.exports.memory.buffer);
1300
+ const U8 = () => new Uint8Array(inst2.exports.memory.buffer);
1301
+ const tv = proc.ctx.execArgv;
1302
+ // Absolute argv paths (leading '/'), normalized to root-relative keys.
1303
+ // These recover the absolute-vs-relative bit the tool's wasi-libc drops
1304
+ // (see makeResolve): a path under one of these is never re-anchored.
1305
+ const absRoots = new Set<string>();
1306
+ for (let i = 1; i < tv.length; i++) if (tv[i].startsWith('/')) absRoots.add(norm(tv[i]));
1307
+ const wstr = (p: number, str: string) => { const b = te.encode(str); U8().set(b, p); return b.length; };
1308
+ let code = 0;
1309
+ const io: BashIo = {
1310
+ read: (fd, iov, nread) => {
1311
+ const dv = DV();
1312
+ for (;;) {
1313
+ const sync = tryReadFd(s, proc, fd, dv, U8(), iov, nread);
1314
+ if (sync) return sync.errno;
1315
+ // Would block: pump the scheduler so writer procs make progress.
1316
+ // When nothing is runnable the source can't produce more
1317
+ // synchronously (interactive stdin mid-exec) — deliver EOF.
1318
+ if (!pumpOne(s)) { dv.setUint32(nread, 0, true); return 0; }
1319
+ }
1320
+ },
1321
+ write: (fd, bytes) => writeThroughFd(s, proc, fd, bytes),
1322
+ // An exec'd tool cannot park, so a wait it cannot satisfy locally is spent
1323
+ // pumping the scheduler — the same discipline its blocking reads use.
1324
+ poll: (inPtr, outPtr, nsubs, retPtr) => {
1325
+ const dv = DV();
1326
+ const subs = readSubs(dv, inPtr, nsubs);
1327
+ let emitted = emitReady(s, proc, dv, outPtr, subs);
1328
+ if (emitted === 0) {
1329
+ waitForDeadline(s, proc, subs);
1330
+ emitted = emitReady(s, proc, dv, outPtr, subs) || emitClocks(dv, outPtr, subs);
1331
+ }
1332
+ dv.setUint32(retPtr, emitted, true);
1333
+ return 0;
1334
+ },
1335
+ };
1336
+ const base = makeWasiFs(s, proc, DV, U8, io, childCwd, absRoots);
1337
+ const w: BashWasiImports = {
1338
+ ...base,
1339
+ args_sizes_get: (a, b) => { const dv = DV(); dv.setUint32(a, tv.length, true); dv.setUint32(b, tv.reduce((x, v) => x + te.encode(v).length + 1, 0), true); return 0; },
1340
+ args_get: (ptrs, buf) => { const dv = DV(); let p = buf; for (const a of tv) { dv.setUint32(ptrs, p, true); ptrs += 4; p += wstr(p, a); U8()[p++] = 0; } return 0; },
1341
+ // POSIX environment inheritance: the child env bash passed to execve.
1342
+ environ_sizes_get: (a, b) => { const dv = DV(); dv.setUint32(a, env.length, true); dv.setUint32(b, env.reduce((x, v) => x + te.encode(v).length + 1, 0), true); return 0; },
1343
+ environ_get: (ptrs, buf) => { const dv = DV(); let p = buf; for (const v of env) { dv.setUint32(ptrs, p, true); ptrs += 4; p += wstr(p, v); U8()[p++] = 0; } return 0; },
1344
+ proc_exit: (ec) => { code = ec; throw new Exit(ec); },
1345
+ };
1346
+ // nimbus_proc.chmod: WASI preview1 has no mode syscall, so busybox's
1347
+ // chmod threads through this import. In-facet the effective-mode table
1348
+ // updates immediately (chmod +x → ./script runs); the durable, S2a
1349
+ // ownership-checked chmod happens at fsDiff flush.
1350
+ const chmodResolve = makeResolve(s, childCwd, absRoots);
1351
+ const nimbus_proc = {
1352
+ chmod: (pathPtr: number, pathLen: number, mode: number) => {
1353
+ const p = chmodResolve(td.decode(U8().subarray(pathPtr, pathPtr + pathLen)));
1354
+ const trav = checkTraversal(s, p);
1355
+ if (trav) return trav;
1356
+ if (!inodeExists(s, p) && !(p !== '' && isDir(s, p))) return E.NOENT;
1357
+ const bits = mode & 0o777;
1358
+ s.fs.modes.set(p, (bits >> 6) & 7);
1359
+ s.fs.modesChanged.set(p, bits);
1360
+ return 0;
1361
+ },
1362
+ };
1363
+ inst2 = new WebAssembly.Instance(m, { wasi_snapshot_preview1: w, nimbus_proc }) as BashInstance;
1364
+ s.stats.instances++;
1365
+ const mem2 = inst2.exports.memory.buffer.byteLength;
1366
+ if (mem2 > s.stats.memPeak) s.stats.memPeak = mem2;
1367
+ try { inst2.exports._start(); }
1368
+ catch (e) { if (e instanceof Exit) code = e.code; else throw e; }
1369
+ finishProc(s, proc, code);
1370
+ }
1371
+
1372
+ function doFork(s: BashSession, parent: BashProc): void {
1373
+ const childPid = s.pidNext++;
1374
+ const childFds = new Map();
1375
+ for (const [fd, e] of parent.fds) { childFds.set(fd, { ...e }); if (e.kind === 'pipe') bumpPipe(s, e, 1); }
1376
+ const child = makeProc(s, childPid, parent.pid, childFds);
1377
+ const pmem = parent.inst.exports.memory, cmem = child.inst.exports.memory;
1378
+ if (cmem.buffer.byteLength < pmem.buffer.byteLength) cmem.grow((pmem.buffer.byteLength - cmem.buffer.byteLength) / PAGE);
1379
+ new Uint8Array(cmem.buffer).set(new Uint8Array(pmem.buffer));
1380
+ for (const [k, v] of Object.entries(parent.inst.exports)) if (v instanceof WebAssembly.Global) (child.inst.exports[k] as WebAssembly.Global).value = v.value;
1381
+ child.MAIN_BUF = parent.MAIN_BUF; child.SLOT0 = parent.SLOT0;
1382
+ child.ctx.nextSlot = parent.ctx.nextSlot;
1383
+ child.slotByEnv = new Map(parent.slotByEnv);
1384
+ child.freeSlots = parent.freeSlots.slice();
1385
+ const total = s.procs.size;
1386
+ if (total * cmem.buffer.byteLength > s.stats.memPeak) s.stats.memPeak = total * cmem.buffer.byteLength;
1387
+ child.ctx.resume = 0; child.ctx.rewinding = true;
1388
+ child.inst.exports.asyncify_start_rewind(child.MAIN_BUF);
1389
+ s.runnable.push(child);
1390
+ parent.ctx.resume = childPid; parent.ctx.rewinding = true;
1391
+ parent.inst.exports.asyncify_start_rewind(parent.MAIN_BUF);
1392
+ s.runnable.push(parent);
1393
+ }
1394
+
1395
+ function doWait(s: BashSession, proc: BashProc): void {
1396
+ const t = proc.ctx.waitTarget;
1397
+ let pid: number | null = null;
1398
+ if (t > 0) {
1399
+ // A named target still has to be this process's child; reaping another
1400
+ // process's child by pid is the same error, just harder to reach.
1401
+ const e = s.exitStatus.get(t);
1402
+ if (e && e.ppid === proc.pid) pid = t;
1403
+ } else {
1404
+ // `wait` with no target reaps one of MY children. This used to take the
1405
+ // first entry in the map regardless of parentage, so with two subshells
1406
+ // each having had a child exit, one could consume the other's status —
1407
+ // and then block forever waiting for a child already reaped elsewhere.
1408
+ for (const [p, e] of s.exitStatus) { if (e.ppid === proc.pid) { pid = p; break; } }
1409
+ }
1410
+ if (pid != null) {
1411
+ const st = (s.exitStatus.get(pid) as BashExitStatus).status; s.exitStatus.delete(pid);
1412
+ proc.ctx.resume = pid; proc.ctx.resumeStatus = st;
1413
+ resumeProc(proc);
1414
+ } else {
1415
+ s.waiters.push({ proc, targetPid: t });
1416
+ }
1417
+ }
1418
+
1419
+ function finishProc(s: BashSession, proc: BashProc, code: number): void {
1420
+ const st = (code & 0xff) << 8;
1421
+ s.procs.delete(proc.pid);
1422
+ for (const fd of [...proc.fds.keys()]) closeFd(s, proc, fd);
1423
+ if (proc.ppid === 0) s.rootExit = code;
1424
+ s.exitStatus.set(proc.pid, { status: st, ppid: proc.ppid });
1425
+ for (let i = 0; i < s.waiters.length; i++) {
1426
+ const w = s.waiters[i];
1427
+ // Only the parent may be woken by this exit — a waiter in another subshell
1428
+ // is not waiting for this child, and waking it hands over a status that was
1429
+ // never its to claim.
1430
+ if (w.proc.pid === proc.ppid && (w.targetPid === proc.pid || w.targetPid <= 0)) {
1431
+ s.waiters.splice(i, 1);
1432
+ w.proc.ctx.resume = proc.pid; w.proc.ctx.resumeStatus = st;
1433
+ s.exitStatus.delete(proc.pid);
1434
+ resumeProc(w.proc);
1435
+ break;
1436
+ }
1437
+ }
1438
+ }
1439
+
1440
+ function composeFsDiff(s: BashSession): WasiFsDiff {
1441
+ const filesWritten: Record<string, string> = {};
1442
+ for (const path of s.fs.written) {
1443
+ if (path.startsWith('etc/nimbus.bashrc')) continue;
1444
+ const f = s.fs.files.get(path);
1445
+ if (f) filesWritten[path] = bytesToB64(f.bytes);
1446
+ }
1447
+ return {
1448
+ filesWritten,
1449
+ filesDeleted: [...s.fs.deleted],
1450
+ dirsCreated: [...s.fs.dirsCreated],
1451
+ // Deepest-first so the flush rmdirs children before their parents.
1452
+ dirsDeleted: [...s.fs.dirsDeleted].sort((a, b) => b.length - a.length),
1453
+ modesChanged: Object.fromEntries(s.fs.modesChanged),
1454
+ symlinksCreated: Object.fromEntries(s.fs.symlinksCreated),
1455
+ };
1456
+ }
1457
+
1458
+ function pump(s: BashSession): BashSlice {
1459
+ try {
1460
+ while (s.runnable.length) {
1461
+ if (++s.steps > 5_000_000) throw new Error('bash-runner: runaway scheduler (>5M steps)');
1462
+ step(s, s.runnable.shift() as BashProc);
1463
+ if (s.rootExit !== null) break;
1464
+ }
1465
+ } catch (e) {
1466
+ s.error = String(e && (e as Error).stack || e && (e as Error).message || e);
1467
+ }
1468
+ const out = s.out, err = s.err;
1469
+ s.out = ''; s.err = '';
1470
+ const stats = { ...s.stats, steps: s.steps, missingWasi: [...s.missingWasi] };
1471
+ if (s.error) {
1472
+ S = null;
1473
+ return { state: 'error', exitCode: 1, stdout: out, stderr: err, error: s.error, stats };
1474
+ }
1475
+ if (s.rootExit !== null || s.procs.size === 0) {
1476
+ const code = s.rootExit === null ? 0 : s.rootExit;
1477
+ const fsDiff = composeFsDiff(s);
1478
+ S = null;
1479
+ return { state: 'exited', exitCode: code, stdout: out, stderr: err, fsDiff, stats };
1480
+ }
1481
+ if (s.stdin.waiters.length > 0) {
1482
+ return { state: 'need-input', exitCode: 0, stdout: out, stderr: err, stats };
1483
+ }
1484
+ S = null;
1485
+ return { state: 'error', exitCode: 1, stdout: out, stderr: err, error: 'bash-runner: deadlock — live procs with empty run queue', stats };
1486
+ }
1487
+
1488
+ globalThis.__bashBoot = function __bashBoot(args: BashBootArgs): BashSlice {
1489
+ try {
1490
+ S = newSession(args);
1491
+ initStdinQueued(S);
1492
+ const root = makeProc(S, S.pidNext++, 0, new Map([
1493
+ [0, { kind: 'stdin' }], [1, { kind: 'stdout' }], [2, { kind: 'stderr' }],
1494
+ [3, { kind: 'preopen' }],
1495
+ ]));
1496
+ S.rootPid = root.pid;
1497
+ setupArena(root);
1498
+ S.runnable.push(root);
1499
+ return pump(S);
1500
+ } catch (e) {
1501
+ S = null;
1502
+ return { state: 'error', exitCode: 1, stdout: '', stderr: '', error: 'boot failed: ' + String(e && (e as Error).message || e) };
1503
+ }
1504
+ };
1505
+
1506
+ globalThis.__bashFeed = function __bashFeed(args: BashFeedArgs): BashSlice {
1507
+ if (!S) {
1508
+ return { state: 'error', exitCode: 1, stdout: '', stderr: '', error: 'bash facet has no active session (warm isolate recycled?)' };
1509
+ }
1510
+ try {
1511
+ if (args.data) { const b = te.encode(args.data); S.stdin.chunks.push(b); S.stdin.queued += b.length; }
1512
+ if (args.eof) S.stdin.closed = true;
1513
+ wakeStdin(S);
1514
+ return pump(S);
1515
+ } catch (e) {
1516
+ const s = S; S = null;
1517
+ return { state: 'error', exitCode: 1, stdout: s ? s.out : '', stderr: s ? s.err : '', error: 'feed failed: ' + String(e && (e as Error).message || e) };
1518
+ }
1519
+ };