@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,2048 @@
1
+ import type { ITerminal } from '../terminal/ITerminal.js';
2
+ import type { VFS } from '../kernel/vfs/index.js';
3
+ import type { CommandRegistry } from '../commands/registry.js';
4
+ import type { CommandInputStream, CommandOutputStream } from '../commands/types.js';
5
+ import type { CommandContext, CommandRunAsHost } from '../commands/types.js';
6
+ import type { VfsCred } from '../../../runtime/os-contracts.js';
7
+ import type { TerminalInputStream } from '../commands/types.js';
8
+ import { resolve } from '../utils/path.js';
9
+ import { BOLD, GREEN, BLUE, RESET } from '../utils/colors.js';
10
+ import { VFSError } from '../kernel/vfs/index.js';
11
+ import {
12
+ ExitSignal,
13
+ Interpreter,
14
+ type BuiltinExecutionContext,
15
+ type BuiltinFn,
16
+ type InterpreterConfig,
17
+ type ShellOptions,
18
+ type TerminalFdState,
19
+ assignScalar,
20
+ } from './interpreter.js';
21
+ import { lex } from './lexer.js';
22
+ import { TokenKind } from './types.js';
23
+ import { HistoryManager } from './history.js';
24
+ import { JobTable } from './jobs.js';
25
+ import { ProcessRegistry } from './ProcessRegistry.js';
26
+ import { signalAbortReason } from './signals.js';
27
+ import { complete, type CompletionContext } from './completer.js';
28
+ import { evaluateTest } from './test-builtin.js';
29
+ import { TerminalStdin } from './terminal-stdin.js';
30
+ import { normalizeTerminalNewlines } from '../../../_shared/terminal.js';
31
+ import { readDefaultShell } from './default-shell.js';
32
+
33
+ function shellPromptParts(env: Record<string, string>, cwd: string): {
34
+ displayPath: string;
35
+ user: string;
36
+ host: string;
37
+ } {
38
+ const home = env['HOME'] ?? '/home/user';
39
+ let displayPath = cwd;
40
+ if (cwd === home) {
41
+ displayPath = '~';
42
+ } else if (cwd.startsWith(home + '/')) {
43
+ displayPath = '~' + cwd.slice(home.length);
44
+ }
45
+ return {
46
+ displayPath,
47
+ user: env['USER'] ?? 'user',
48
+ host: env['HOSTNAME'] ?? 'lifo',
49
+ };
50
+ }
51
+
52
+ export function formatShellPrompt(env: Record<string, string>, cwd: string): string {
53
+ const { displayPath, user, host } = shellPromptParts(env, cwd);
54
+ return `${BOLD}${GREEN}${user}@${host}${RESET}:${BOLD}${BLUE}${displayPath}${RESET}$ `;
55
+ }
56
+
57
+ export interface ExecuteOptions {
58
+ cwd?: string;
59
+ env?: Record<string, string>;
60
+ onStdout?: (data: string) => void;
61
+ onStderr?: (data: string) => void;
62
+ stdin?: string;
63
+ terminalStdin?: TerminalInputStream;
64
+ signal?: AbortSignal;
65
+ runExitTrap?: boolean;
66
+ isolateShellState?: boolean;
67
+ shellOptions?: Partial<ShellOptions>;
68
+ scriptMode?: boolean;
69
+ terminalFds?: TerminalFdState;
70
+ /**
71
+ * Host-supplied fields merged into the `CommandContext` of every command in
72
+ * this execution. The shell substrate treats them as opaque; Nimbus runtime
73
+ * commands read `__nimbusBinSpawn`/bundle hints off the context. Used to hand
74
+ * a long-running registry command (vite/wrangler/serve) the wrapper pid the
75
+ * caller already allocated instead of letting it spawn a second one.
76
+ */
77
+ commandContext?: Record<string, unknown>;
78
+ runAs?: CommandRunAsHost;
79
+ }
80
+
81
+ export interface ShellCommandIdentity {
82
+ pid: number;
83
+ cred: VfsCred;
84
+ setUmask(mask: number): void;
85
+ runAs?: CommandRunAsHost;
86
+ }
87
+
88
+ export class Shell {
89
+ private terminal: ITerminal;
90
+ private vfs: VFS;
91
+ private registry: CommandRegistry;
92
+ cwd: string;
93
+ env: Record<string, string>;
94
+
95
+ // Alias map
96
+ private aliases = new Map<string, string>();
97
+
98
+ // Line editing state
99
+ lineBuffer: string = '';
100
+ cursorPos: number = 0;
101
+ screenCursorRow: number = 0; // tracks the actual terminal row (relative to prompt start)
102
+
103
+ // History (legacy array kept for backward compat with tests)
104
+ history: string[] = [];
105
+ historyIndex: number = -1;
106
+ private savedLine: string = '';
107
+
108
+ // Running command
109
+ running: boolean = false;
110
+ private abortController: AbortController | null = null;
111
+ private terminalStdin: TerminalStdin | null = null;
112
+ private stdinLineBuffer: string = '';
113
+ private stdinCursorPos: number = 0;
114
+
115
+ // New Sprint 2 components
116
+ private interpreter: Interpreter;
117
+ private interpreterConfig: InterpreterConfig;
118
+ private historyManager: HistoryManager;
119
+ private jobTable: JobTable;
120
+ private processRegistry: ProcessRegistry;
121
+ private builtins: Map<string, BuiltinFn>;
122
+ private shellOptions: ShellOptions = {
123
+ errexit: false,
124
+ nounset: false,
125
+ pipefail: false,
126
+ };
127
+ private traps = new Map<string, string>();
128
+ private readonlyNames = new Set<string>();
129
+ /** Indexed arrays; `env` holds the scalars. A name lives in exactly one. */
130
+ private arrays = new Map<string, (string | undefined)[]>();
131
+ private commandIdentity: ShellCommandIdentity;
132
+
133
+ // Tab completion state
134
+ private tabCount: number = 0;
135
+
136
+ // Paste queue for multiline paste support
137
+ pasteQueue: string[] = [];
138
+
139
+ /**
140
+ * Keystrokes that arrived while a foreground command owned the terminal and
141
+ * nothing was reading stdin. A tty buffers type-ahead and hands it to the
142
+ * shell when the job exits; dropping it loses whatever the user typed, and
143
+ * when a dispatch never settles it leaves that connection with no feedback
144
+ * whatsoever. Held as whole chunks so a multi-byte escape sequence replays
145
+ * as one keystroke rather than three.
146
+ */
147
+ typeAhead: string[] = [];
148
+
149
+ constructor(
150
+ terminal: ITerminal,
151
+ vfs: VFS,
152
+ registry: CommandRegistry,
153
+ env: Record<string, string>,
154
+ processRegistry: ProcessRegistry,
155
+ commandIdentity?: ShellCommandIdentity,
156
+ ) {
157
+ this.terminal = terminal;
158
+ this.vfs = vfs;
159
+ this.registry = registry;
160
+ this.cwd = env['HOME'] ?? '/home/user';
161
+ this.env = { ...env };
162
+ if (!this.env['0']) this.env['0'] = 'nimbus-sh';
163
+ if (!this.env['$']) this.env['$'] = String(processRegistry.registerShell(this.cwd, this.env));
164
+ let defaultCred: VfsCred = { uid: 1000, gid: 1000, groups: [1000], umask: 0o022 };
165
+ this.commandIdentity = commandIdentity ?? {
166
+ pid: Number(this.env['$']),
167
+ get cred() { return defaultCred; },
168
+ setUmask: (mask) => {
169
+ defaultCred = { ...defaultCred, umask: mask };
170
+ },
171
+ };
172
+
173
+ // Initialize builtins
174
+ this.builtins = new Map<string, BuiltinFn>();
175
+ this.registerBuiltins();
176
+
177
+ // Initialize job table (legacy - still used for backward compat)
178
+ this.jobTable = new JobTable();
179
+
180
+ // Use shared process registry from Kernel
181
+ this.processRegistry = processRegistry;
182
+
183
+ // Initialize history manager
184
+ this.historyManager = new HistoryManager(vfs);
185
+ this.historyManager.load();
186
+
187
+ // Initialize interpreter
188
+ this.interpreterConfig = {
189
+ env: this.env,
190
+ arrays: this.arrays,
191
+ getCwd: () => this.cwd,
192
+ setCwd: (cwd: string) => { this.cwd = cwd; },
193
+ vfs: this.vfs,
194
+ registry: this.registry,
195
+ builtins: this.builtins,
196
+ jobTable: this.jobTable,
197
+ processRegistry: this.processRegistry,
198
+ writeToTerminal: (text: string) => this.writeToTerminal(text),
199
+ aliases: this.aliases,
200
+ getAbortSignal: () => this.abortController?.signal ?? new AbortController().signal,
201
+ options: this.shellOptions,
202
+ traps: this.traps,
203
+ readonlyNames: this.readonlyNames,
204
+ };
205
+ this.interpreter = new Interpreter(this.interpreterConfig);
206
+ }
207
+
208
+ private registerBuiltins(): void {
209
+ this.builtins.set('cd', (args, _stdout, stderr) => this.builtinCd(args, stderr));
210
+ this.builtins.set('pwd', (_args, stdout) => this.builtinPwd(stdout));
211
+ this.builtins.set('echo', (args, stdout) => this.builtinEcho(args, stdout));
212
+ this.builtins.set('clear', () => this.builtinClear());
213
+ this.builtins.set('export', (args, _stdout, stderr) => this.builtinExport(args, stderr));
214
+ this.builtins.set('exit', (args, _stdout, stderr) => this.builtinExit(args, stderr));
215
+ this.builtins.set('true', () => Promise.resolve(0));
216
+ this.builtins.set('false', () => Promise.resolve(1));
217
+ this.builtins.set(':', () => Promise.resolve(0));
218
+ this.builtins.set('set', (args, stdout, stderr, _stdin, context) => this.builtinSet(args, stdout, stderr, context));
219
+ this.builtins.set('shift', (args, _stdout, stderr, _stdin, context) => this.builtinShift(args, stderr, context));
220
+ this.builtins.set('trap', (args, stdout, stderr) => this.builtinTrap(args, stdout, stderr));
221
+ this.builtins.set('hash', (args, stdout, stderr) => this.builtinHash(args, stdout, stderr));
222
+ this.builtins.set('readonly', (args, stdout, stderr) => this.builtinReadonly(args, stdout, stderr));
223
+ this.builtins.set('read', (args, _stdout, stderr, stdin, context) => this.builtinRead(args, stdin, stderr, context));
224
+ this.builtins.set('wait', (args, _stdout, stderr) => this.builtinWait(args, stderr));
225
+ this.builtins.set('unset', (args, _stdout, stderr) => this.builtinUnset(args, stderr));
226
+ this.builtins.set('local', (args, _stdout, stderr, _stdin, context) =>
227
+ this.builtinDeclare('local', args, stderr, context));
228
+ this.builtins.set('declare', (args, _stdout, stderr, _stdin, context) =>
229
+ this.builtinDeclare('declare', args, stderr, context));
230
+ this.builtins.set('typeset', (args, _stdout, stderr, _stdin, context) =>
231
+ this.builtinDeclare('typeset', args, stderr, context));
232
+ this.builtins.set('jobs', (_args, stdout) => this.builtinJobs(stdout));
233
+ this.builtins.set('fg', (args, stdout, stderr) => this.builtinFg(args, stdout, stderr));
234
+ this.builtins.set('bg', (args, stdout, stderr) => this.builtinBg(args, stdout, stderr));
235
+ this.builtins.set('history', (_args, stdout) => this.builtinHistory(stdout));
236
+ this.builtins.set('source', (args, stdout, stderr, _stdin, context) => this.builtinSource(args, stdout, stderr, context));
237
+ this.builtins.set('.', (args, stdout, stderr, _stdin, context) => this.builtinSource(args, stdout, stderr, context));
238
+ this.builtins.set('alias', (args, stdout) => this.builtinAlias(args, stdout));
239
+ this.builtins.set('unalias', (args, _stdout, stderr) => this.builtinUnalias(args, stderr));
240
+ this.builtins.set('test', (args, _stdout, stderr, _stdin, context) =>
241
+ evaluateTest(args, context?.vfs ?? this.vfs, stderr, context));
242
+ this.builtins.set('[', (args, _stdout, stderr, _stdin, context) =>
243
+ evaluateTest(args, context?.vfs ?? this.vfs, stderr, context));
244
+ }
245
+
246
+ getJobTable(): JobTable {
247
+ return this.jobTable;
248
+ }
249
+
250
+ getProcessRegistry(): ProcessRegistry {
251
+ return this.processRegistry;
252
+ }
253
+
254
+ getCwd(): string {
255
+ return this.cwd;
256
+ }
257
+
258
+ setCwd(cwd: string): void {
259
+ this.cwd = cwd;
260
+ }
261
+
262
+ getEnv(): Record<string, string> {
263
+ return this.env;
264
+ }
265
+
266
+ getVfs(): VFS {
267
+ return this.vfs;
268
+ }
269
+
270
+ getRegistry(): CommandRegistry {
271
+ return this.registry;
272
+ }
273
+
274
+ /**
275
+ * Programmatic command execution with captured stdout/stderr.
276
+ * Used by Sandbox.commands.run() for headless mode.
277
+ */
278
+ private _executeDepth = 0;
279
+
280
+ async execute(
281
+ cmd: string,
282
+ options?: ExecuteOptions,
283
+ ): Promise<{ stdout: string; stderr: string; exitCode: number }> {
284
+ this._executeDepth++;
285
+ if (this._executeDepth > 10) {
286
+ this._executeDepth--;
287
+ const msg = `shell.execute: recursion depth exceeded (cmd="${cmd}")\n`;
288
+ options?.onStderr?.(msg);
289
+ return { stdout: '', stderr: msg, exitCode: 1 };
290
+ }
291
+ let stdoutBuf = '';
292
+ let stderrBuf = '';
293
+
294
+ const stdoutStream: CommandOutputStream = {
295
+ write: (text: string) => {
296
+ stdoutBuf += text;
297
+ options?.onStdout?.(text);
298
+ },
299
+ };
300
+ const stderrStream: CommandOutputStream = {
301
+ write: (text: string) => {
302
+ stderrBuf += text;
303
+ options?.onStderr?.(text);
304
+ },
305
+ };
306
+
307
+ // Save current state
308
+ const prevCwd = options?.cwd ? this.cwd : undefined;
309
+ const savedShellState = options?.isolateShellState ? this.snapshotShellState() : null;
310
+ const envOverrideSnapshot = !savedShellState && options?.env
311
+ ? snapshotEnvKeys(this.env, Object.keys(options.env))
312
+ : null;
313
+ const optionSnapshot = !savedShellState && options?.shellOptions ? { ...this.shellOptions } : null;
314
+ const abortController = new AbortController();
315
+ const abortFromCaller = () => abortController.abort(options?.signal?.reason);
316
+ if (options?.signal) {
317
+ if (options.signal.aborted) abortFromCaller();
318
+ else options.signal.addEventListener('abort', abortFromCaller, { once: true });
319
+ }
320
+ // Per-execution capture sink for shell-level direct-terminal writes
321
+ // (`/dev/tty`, command-stdout fallback). Threaded through `executeLine`
322
+ // options so a nested `execute` never mutates shared interpreter config the
323
+ // parent command's late-bound closures read.
324
+ const writeToTerminal = (text: string) => {
325
+ stderrBuf += text;
326
+ options?.onStderr?.(text);
327
+ };
328
+
329
+ // Apply per-call overrides
330
+ if (options?.cwd) {
331
+ this.cwd = options.cwd;
332
+ }
333
+ if (options?.env) {
334
+ Object.assign(this.env, options.env);
335
+ }
336
+ if (options?.shellOptions) {
337
+ Object.assign(this.shellOptions, options.shellOptions);
338
+ }
339
+
340
+ let stdinStream: CommandInputStream | undefined;
341
+ if (options?.stdin !== undefined) {
342
+ const fixedStdin = new TerminalStdin();
343
+ fixedStdin.feed(options.stdin);
344
+ fixedStdin.close();
345
+ stdinStream = fixedStdin;
346
+ }
347
+
348
+ try {
349
+ const exitCode = await this.interpreter.executeLine(
350
+ cmd,
351
+ options?.terminalStdin,
352
+ {
353
+ runExitTrap: options?.runExitTrap === true,
354
+ stdin: stdinStream,
355
+ stdout: stdoutStream,
356
+ stderr: stderrStream,
357
+ writeToTerminal,
358
+ terminalFds: options?.terminalFds,
359
+ scriptMode: options?.scriptMode === true,
360
+ commandContext: options?.commandContext,
361
+ commandIdentity: this.resolveCommandIdentity(options?.commandContext),
362
+ runAs: options?.runAs ?? this.commandIdentity.runAs,
363
+ signal: abortController.signal,
364
+ },
365
+ );
366
+ return { stdout: stdoutBuf, stderr: stderrBuf, exitCode };
367
+ } catch (e) {
368
+ const msg = e instanceof Error ? (e.stack || e.message) : String(e);
369
+ stderrBuf += msg + '\n';
370
+ options?.onStderr?.(msg + '\n');
371
+ return { stdout: stdoutBuf, stderr: stderrBuf, exitCode: 1 };
372
+ } finally {
373
+ this._executeDepth--;
374
+ // Restore state
375
+ if (options?.signal) {
376
+ options.signal.removeEventListener('abort', abortFromCaller);
377
+ }
378
+ if (savedShellState) {
379
+ this.restoreShellState(savedShellState);
380
+ } else {
381
+ if (envOverrideSnapshot) restoreEnvKeys(this.env, envOverrideSnapshot);
382
+ if (optionSnapshot) restoreShellOptions(this.shellOptions, optionSnapshot);
383
+ }
384
+ if (prevCwd !== undefined) {
385
+ this.cwd = prevCwd;
386
+ }
387
+ }
388
+ }
389
+
390
+ private resolveCommandIdentity(overrides: Record<string, unknown> | undefined): ShellCommandIdentity {
391
+ const pid = overrides?.['pid'];
392
+ const cred = overrides?.['cred'];
393
+ const setUmask = overrides?.['setUmask'];
394
+ return {
395
+ pid: typeof pid === 'number' ? pid : this.commandIdentity.pid,
396
+ cred: isVfsCred(cred) ? cred : this.commandIdentity.cred,
397
+ setUmask: typeof setUmask === 'function'
398
+ ? (mask) => setUmask(mask)
399
+ : this.commandIdentity.setUmask,
400
+ runAs: this.commandIdentity.runAs,
401
+ };
402
+ }
403
+
404
+ start(): void {
405
+ // Register this shell instance as a process
406
+ // First shell gets PID 1, subsequent shells get PID 2, 3, etc.
407
+ const pid = this.processRegistry.registerShell(this.cwd, this.env);
408
+ this.env['$'] = String(pid);
409
+
410
+ this.terminal.onData((data) => this.handleInput(data));
411
+
412
+ // Source rc files on startup (like bash/zsh)
413
+ this.sourceRcFiles().then(async () => {
414
+ const home = this.env['HOME'] ?? '/home/user';
415
+ if (readDefaultShell(this.vfs, home) === 'bash') {
416
+ await this.executeLine('bash -i');
417
+ } else {
418
+ this.printPrompt();
419
+ }
420
+ });
421
+ }
422
+
423
+ private async sourceRcFiles(): Promise<void> {
424
+ const home = this.env['HOME'] ?? '/home/user';
425
+
426
+ // Source system-wide profile first
427
+ await this.sourceFile('/etc/profile');
428
+
429
+ // Then user rc files (first one found wins, like bash)
430
+ const rcFiles = [
431
+ `${home}/.liforc`,
432
+ `${home}/.bashrc`,
433
+ `${home}/.profile`,
434
+ ];
435
+
436
+ for (const rc of rcFiles) {
437
+ if (this.vfs.exists(rc)) {
438
+ await this.sourceFile(rc);
439
+ break;
440
+ }
441
+ }
442
+ }
443
+
444
+ printPrompt(): void {
445
+ // Report finished background jobs from JobTable (legacy)
446
+ const doneJobs = this.jobTable.collectDone();
447
+ for (const job of doneJobs) {
448
+ this.writeToTerminal(`[${job.id}] Done ${job.command}\n`);
449
+ }
450
+
451
+ // Collect and reap zombie processes from ProcessRegistry
452
+ this.processRegistry.collectZombies();
453
+ // Zombies are already logged by JobTable above, so no need to log again
454
+
455
+ this.terminal.write(formatShellPrompt(this.env, this.cwd));
456
+ }
457
+
458
+ handleInput(data: string): void {
459
+ // Raw mode: bypass all shell line editing, deliver keypresses directly
460
+ if (this.running && this.terminalStdin?.rawMode) {
461
+ this.terminalStdin.feed(data);
462
+ return;
463
+ }
464
+
465
+ // Multiline paste detection: if data contains newlines and has multiple chars,
466
+ // split into lines and execute them sequentially via the paste queue
467
+ if (!this.running && data.length > 1 && /[\r\n]/.test(data)) {
468
+ const lines = data.split(/\r\n|\r|\n/);
469
+ for (let i = 0; i < lines.length; i++) {
470
+ const segment = lines[i];
471
+ if (i === 0) {
472
+ // First segment: append to current lineBuffer and execute
473
+ if (segment) {
474
+ this.lineBuffer = this.lineBuffer.slice(0, this.cursorPos) + segment + this.lineBuffer.slice(this.cursorPos);
475
+ this.cursorPos += segment.length;
476
+ }
477
+ if (i < lines.length - 1) {
478
+ // There's a newline after this segment, execute it
479
+ this.redrawLine();
480
+ this.terminal.write('\r\n');
481
+ const line = this.lineBuffer.trim();
482
+ this.lineBuffer = '';
483
+ this.cursorPos = 0;
484
+ this.historyIndex = -1;
485
+ if (line) {
486
+ this.history.push(line);
487
+ // Queue remaining lines before executing
488
+ for (let j = 1; j < lines.length - 1; j++) {
489
+ if (lines[j]) this.pasteQueue.push(lines[j]);
490
+ }
491
+ // Last segment (after final newline) goes into lineBuffer without executing
492
+ const lastSegment = lines[lines.length - 1];
493
+ if (lastSegment) {
494
+ this.pasteQueue.push(lastSegment);
495
+ }
496
+ this.executeLine(line);
497
+ return;
498
+ } else {
499
+ // Empty first line, queue the rest
500
+ for (let j = 1; j < lines.length - 1; j++) {
501
+ if (lines[j]) this.pasteQueue.push(lines[j]);
502
+ }
503
+ const lastSegment = lines[lines.length - 1];
504
+ if (lastSegment) {
505
+ this.pasteQueue.push(lastSegment);
506
+ }
507
+ this.drainPasteQueue();
508
+ return;
509
+ }
510
+ }
511
+ }
512
+ }
513
+ // If we get here, data had newlines but only one segment (shouldn't happen)
514
+ // Fall through to normal handling
515
+ if (this.lineBuffer) this.redrawLine();
516
+ return;
517
+ }
518
+
519
+ // ESC sequences. Cursor motion and history are line EDITING, so they only
520
+ // belong to a shell that owns the line. While a command runs they must
521
+ // fall through: to the stdin reader that has its own cursor (and its own
522
+ // handlers for these very sequences), or to the type-ahead buffer.
523
+ if (!this.running) {
524
+ if (data === '\x1b[D') { this.moveCursorLeft(); return; }
525
+ if (data === '\x1b[C') { this.moveCursorRight(); return; }
526
+ if (data === '\x1b[A') { this.historyUp(); return; }
527
+ if (data === '\x1b[B') { this.historyDown(); return; }
528
+ if (data === '\x1b[H' || data === '\x01') { this.moveCursorHome(); return; } // Home / Ctrl+A
529
+ if (data === '\x1b[F' || data === '\x05') { this.moveCursorEnd(); return; } // End / Ctrl+E
530
+ }
531
+
532
+ // Ctrl+C (SIGINT) and Ctrl+\ (SIGQUIT) — the terminal's two signal keys.
533
+ // Both go to the foreground command; with no foreground job, Ctrl+C
534
+ // cancels the line and Ctrl+\ is absorbed, as readline does.
535
+ if (data === '\x03' || data === '\x1c') {
536
+ const signal = data === '\x03' ? 'INT' : 'QUIT';
537
+ if (this.running && this.abortController) {
538
+ this.terminalStdin?.close();
539
+ this.stdinLineBuffer = '';
540
+ this.stdinCursorPos = 0;
541
+ this.abortController.abort(signalAbortReason(signal));
542
+ } else if (signal === 'INT') {
543
+ this.terminal.write('^C\r\n');
544
+ this.lineBuffer = '';
545
+ this.cursorPos = 0;
546
+ this.screenCursorRow = 0;
547
+ this.printPrompt();
548
+ }
549
+ return;
550
+ }
551
+
552
+ // Ctrl+D (EOF)
553
+ if (data === '\x04') {
554
+ if (this.running && this.terminalStdin && this.stdinLineBuffer.length === 0) {
555
+ this.terminalStdin.close();
556
+ return;
557
+ }
558
+ // When not running, Ctrl+D on empty line does nothing (or could exit)
559
+ return;
560
+ }
561
+
562
+ // Ctrl+U -- clear line
563
+ if (data === '\x15') {
564
+ if (this.running && this.terminalStdin?.isWaiting) {
565
+ // Clear the stdin line buffer
566
+ if (this.stdinCursorPos > 0) {
567
+ this.terminal.write(`\x1b[${this.stdinCursorPos}D`);
568
+ }
569
+ this.terminal.write('\x1b[K');
570
+ this.stdinLineBuffer = '';
571
+ this.stdinCursorPos = 0;
572
+ return;
573
+ }
574
+ // Use redrawLine to clear wrapped content, then reset
575
+ this.lineBuffer = '';
576
+ this.cursorPos = 0;
577
+ this.redrawLine();
578
+ return;
579
+ }
580
+
581
+ // When a command is running and waiting for stdin, forward input
582
+ if (this.running && this.terminalStdin?.isWaiting) {
583
+ this.handleStdinInput(data);
584
+ return;
585
+ }
586
+
587
+ // A foreground command owns the line editor and nothing is reading stdin,
588
+ // so this is type-ahead. Echo it — that is what a tty does, and it is the
589
+ // only sign of life a wedged dispatch can give — then hold it for replay.
590
+ if (this.running) {
591
+ this.typeAhead.push(data);
592
+ if (data === '\r') this.terminal.write('\r\n');
593
+ else if (data >= ' ' && data !== '\x7f') this.terminal.write(normalizeTerminalNewlines(data));
594
+ return;
595
+ }
596
+
597
+ // Tab completion
598
+ if (data === '\t') {
599
+ this.handleTab();
600
+ return;
601
+ }
602
+
603
+ // Reset tab state on any non-tab input
604
+ this.tabCount = 0;
605
+
606
+ // Enter
607
+ if (data === '\r') {
608
+ this.terminal.write('\r\n');
609
+ const line = this.lineBuffer.trim();
610
+ this.lineBuffer = '';
611
+ this.cursorPos = 0;
612
+ this.screenCursorRow = 0;
613
+ this.historyIndex = -1;
614
+
615
+ if (line) {
616
+ this.history.push(line);
617
+ this.executeLine(line);
618
+ } else {
619
+ this.printPrompt();
620
+ }
621
+ return;
622
+ }
623
+
624
+ // Backspace
625
+ if (data === '\x7f' || data === '\b') {
626
+ if (this.cursorPos > 0) {
627
+ const before = this.lineBuffer.slice(0, this.cursorPos - 1);
628
+ const after = this.lineBuffer.slice(this.cursorPos);
629
+ this.lineBuffer = before + after;
630
+ this.cursorPos--;
631
+ this.redrawLine();
632
+ }
633
+ return;
634
+ }
635
+
636
+ // Delete
637
+ if (data === '\x1b[3~') {
638
+ if (this.cursorPos < this.lineBuffer.length) {
639
+ const before = this.lineBuffer.slice(0, this.cursorPos);
640
+ const after = this.lineBuffer.slice(this.cursorPos + 1);
641
+ this.lineBuffer = before + after;
642
+ this.redrawLine();
643
+ }
644
+ return;
645
+ }
646
+
647
+ // Printable characters
648
+ if (data >= ' ') {
649
+ // Insert at cursor
650
+ const before = this.lineBuffer.slice(0, this.cursorPos);
651
+ const after = this.lineBuffer.slice(this.cursorPos);
652
+ this.lineBuffer = before + data + after;
653
+ this.cursorPos += data.length;
654
+ this.redrawLine();
655
+ }
656
+ }
657
+
658
+ private handleTab(): void {
659
+ const completionCtx: CompletionContext = {
660
+ line: this.lineBuffer,
661
+ cursorPos: this.cursorPos,
662
+ cwd: this.cwd,
663
+ env: this.env,
664
+ vfs: this.vfs,
665
+ registry: this.registry,
666
+ builtinNames: [...this.builtins.keys()],
667
+ };
668
+
669
+ const result = complete(completionCtx);
670
+ const currentWord = this.lineBuffer.slice(result.replacementStart, result.replacementEnd);
671
+
672
+ if (result.completions.length === 0) {
673
+ // No completions -- bell
674
+ this.terminal.write('\x07');
675
+ return;
676
+ }
677
+
678
+ if (result.completions.length === 1) {
679
+ // Single completion -- insert it
680
+ const completion = result.completions[0];
681
+ const suffix = completion.endsWith('/') ? '' : ' ';
682
+ this.applyCompletion(result.replacementStart, result.replacementEnd, completion + suffix);
683
+ this.tabCount = 0;
684
+ return;
685
+ }
686
+
687
+ // Multiple completions
688
+ if (result.commonPrefix.length > currentWord.length) {
689
+ // Extend to common prefix
690
+ this.applyCompletion(result.replacementStart, result.replacementEnd, result.commonPrefix);
691
+ this.tabCount = 0;
692
+ return;
693
+ }
694
+
695
+ // Same word as before -- second tab shows all completions
696
+ this.tabCount++;
697
+ if (this.tabCount >= 2) {
698
+ this.terminal.write('\r\n');
699
+ this.writeToTerminal(result.completions.join(' ') + '\n');
700
+ this.printPrompt();
701
+ this.terminal.write(this.lineBuffer);
702
+ // Move cursor to correct position
703
+ const diff = this.lineBuffer.length - this.cursorPos;
704
+ if (diff > 0) {
705
+ this.terminal.write(`\x1b[${diff}D`);
706
+ }
707
+ this.tabCount = 0;
708
+ }
709
+ }
710
+
711
+ private handleStdinInput(data: string): void {
712
+ if (data.length > 1 && !isTerminalControlSequence(data)) {
713
+ for (const ch of data) this.handleStdinInput(ch);
714
+ return;
715
+ }
716
+
717
+ // Arrow keys for line editing
718
+ if (data === '\x1b[D') {
719
+ // Left arrow
720
+ if (this.stdinCursorPos > 0) {
721
+ this.stdinCursorPos--;
722
+ this.terminal.write('\x1b[D');
723
+ }
724
+ return;
725
+ }
726
+ if (data === '\x1b[C') {
727
+ // Right arrow
728
+ if (this.stdinCursorPos < this.stdinLineBuffer.length) {
729
+ this.stdinCursorPos++;
730
+ this.terminal.write('\x1b[C');
731
+ }
732
+ return;
733
+ }
734
+ if (data === '\x1b[H' || data === '\x01') {
735
+ // Home / Ctrl+A
736
+ if (this.stdinCursorPos > 0) {
737
+ this.terminal.write(`\x1b[${this.stdinCursorPos}D`);
738
+ this.stdinCursorPos = 0;
739
+ }
740
+ return;
741
+ }
742
+ if (data === '\x1b[F' || data === '\x05') {
743
+ // End / Ctrl+E
744
+ const diff = this.stdinLineBuffer.length - this.stdinCursorPos;
745
+ if (diff > 0) {
746
+ this.terminal.write(`\x1b[${diff}C`);
747
+ this.stdinCursorPos = this.stdinLineBuffer.length;
748
+ }
749
+ return;
750
+ }
751
+
752
+ // Ignore other escape sequences (up/down arrows, etc.)
753
+ if (data.startsWith('\x1b')) return;
754
+
755
+ // Enter -- feed line to stdin
756
+ if (data === '\r') {
757
+ this.terminal.write('\r\n');
758
+ this.terminalStdin!.feed(this.stdinLineBuffer + '\n');
759
+ this.stdinLineBuffer = '';
760
+ this.stdinCursorPos = 0;
761
+ return;
762
+ }
763
+
764
+ // Backspace
765
+ if (data === '\x7f' || data === '\b') {
766
+ if (this.stdinCursorPos > 0) {
767
+ const before = this.stdinLineBuffer.slice(0, this.stdinCursorPos - 1);
768
+ const after = this.stdinLineBuffer.slice(this.stdinCursorPos);
769
+ this.stdinLineBuffer = before + after;
770
+ this.stdinCursorPos--;
771
+ // Redraw: move back, write rest + space to clear, reposition cursor
772
+ this.terminal.write('\b' + after + ' ');
773
+ // Move cursor back to position
774
+ const moveBack = after.length + 1;
775
+ if (moveBack > 0) {
776
+ this.terminal.write(`\x1b[${moveBack}D`);
777
+ }
778
+ }
779
+ return;
780
+ }
781
+
782
+ // Printable characters
783
+ if (data >= ' ') {
784
+ const before = this.stdinLineBuffer.slice(0, this.stdinCursorPos);
785
+ const after = this.stdinLineBuffer.slice(this.stdinCursorPos);
786
+ this.stdinLineBuffer = before + data + after;
787
+ this.stdinCursorPos += data.length;
788
+ // Write char + rest of line, reposition cursor
789
+ this.terminal.write(data + after);
790
+ if (after.length > 0) {
791
+ this.terminal.write(`\x1b[${after.length}D`);
792
+ }
793
+ }
794
+ }
795
+
796
+ private applyCompletion(start: number, end: number, text: string): void {
797
+ const before = this.lineBuffer.slice(0, start);
798
+ const after = this.lineBuffer.slice(end);
799
+ this.lineBuffer = before + text + after;
800
+ this.cursorPos = start + text.length;
801
+ this.redrawLine();
802
+ }
803
+
804
+ private getPromptWidth(): number {
805
+ const { displayPath, user, host } = shellPromptParts(this.env, this.cwd);
806
+ // "user@host:path$ " — count visible chars only (no ANSI codes)
807
+ return user.length + 1 + host.length + 1 + displayPath.length + 2;
808
+ }
809
+
810
+ redrawLine(): void {
811
+ const cols = this.terminal.cols;
812
+ const promptWidth = this.getPromptWidth();
813
+ const totalLen = promptWidth + this.lineBuffer.length;
814
+
815
+ // Move up from wherever the cursor actually is to the prompt start row
816
+ if (this.screenCursorRow > 0) {
817
+ this.terminal.write(`\x1b[${this.screenCursorRow}A`);
818
+ }
819
+ this.terminal.write('\r');
820
+
821
+ // Clear from here to end of screen
822
+ this.terminal.write('\x1b[J');
823
+
824
+ // Rewrite prompt + buffer
825
+ this.terminal.write(formatShellPrompt(this.env, this.cwd));
826
+ this.terminal.write(this.lineBuffer);
827
+
828
+ // After writing all content, figure out which row the cursor is on.
829
+ // If content exactly fills N rows, the terminal auto-wraps cursor to the next row.
830
+ let endRow: number;
831
+ if (totalLen > 0 && totalLen % cols === 0) {
832
+ endRow = totalLen / cols; // cursor wraps to one row past the last content row
833
+ } else {
834
+ endRow = Math.floor(totalLen / cols);
835
+ }
836
+
837
+ // Position cursor at the desired column
838
+ const desiredCol = promptWidth + this.cursorPos;
839
+ const desiredRow = Math.floor(desiredCol / cols);
840
+
841
+ // Move up from content end to desired row
842
+ const rowDiff = endRow - desiredRow;
843
+ if (rowDiff > 0) {
844
+ this.terminal.write(`\x1b[${rowDiff}A`);
845
+ }
846
+ // Move to correct column within the row
847
+ const colInRow = desiredCol % cols;
848
+ this.terminal.write('\r');
849
+ if (colInRow > 0) {
850
+ this.terminal.write(`\x1b[${colInRow}C`);
851
+ }
852
+
853
+ // Track where we left the cursor
854
+ this.screenCursorRow = desiredRow;
855
+ }
856
+
857
+ /**
858
+ * Replay buffered type-ahead through the line editor. Stops the moment a
859
+ * replayed keystroke starts a command: the rest stays queued and is
860
+ * delivered when that one settles, so a queued line is never fed into a
861
+ * shell that is busy again.
862
+ */
863
+ drainTypeAhead(): void {
864
+ while (!this.running && this.typeAhead.length > 0) {
865
+ this.handleInput(this.typeAhead.shift()!);
866
+ }
867
+ }
868
+
869
+ drainPasteQueue(): void {
870
+ const next = this.pasteQueue.shift();
871
+ if (next !== undefined) {
872
+ const line = next.trim();
873
+ if (line) {
874
+ this.terminal.write(line);
875
+ this.terminal.write('\r\n');
876
+ this.history.push(line);
877
+ this.executeLine(line);
878
+ } else {
879
+ // Skip empty lines, try next
880
+ this.drainPasteQueue();
881
+ }
882
+ }
883
+ }
884
+
885
+ private moveCursorLeft(): void {
886
+ if (this.cursorPos > 0) {
887
+ this.cursorPos--;
888
+ this.terminal.write('\x1b[D');
889
+ }
890
+ }
891
+
892
+ private moveCursorRight(): void {
893
+ if (this.cursorPos < this.lineBuffer.length) {
894
+ this.cursorPos++;
895
+ this.terminal.write('\x1b[C');
896
+ }
897
+ }
898
+
899
+ private moveCursorHome(): void {
900
+ if (this.cursorPos > 0) {
901
+ this.terminal.write(`\x1b[${this.cursorPos}D`);
902
+ this.cursorPos = 0;
903
+ }
904
+ }
905
+
906
+ private moveCursorEnd(): void {
907
+ const diff = this.lineBuffer.length - this.cursorPos;
908
+ if (diff > 0) {
909
+ this.terminal.write(`\x1b[${diff}C`);
910
+ this.cursorPos = this.lineBuffer.length;
911
+ }
912
+ }
913
+
914
+ private historyUp(): void {
915
+ if (this.history.length === 0) return;
916
+
917
+ if (this.historyIndex === -1) {
918
+ this.savedLine = this.lineBuffer;
919
+ this.historyIndex = this.history.length - 1;
920
+ } else if (this.historyIndex > 0) {
921
+ this.historyIndex--;
922
+ } else {
923
+ return;
924
+ }
925
+
926
+ this.lineBuffer = this.history[this.historyIndex];
927
+ this.cursorPos = this.lineBuffer.length;
928
+ this.redrawLine();
929
+ }
930
+
931
+ private historyDown(): void {
932
+ if (this.historyIndex === -1) return;
933
+
934
+ if (this.historyIndex < this.history.length - 1) {
935
+ this.historyIndex++;
936
+ this.lineBuffer = this.history[this.historyIndex];
937
+ } else {
938
+ this.historyIndex = -1;
939
+ this.lineBuffer = this.savedLine;
940
+ }
941
+
942
+ this.cursorPos = this.lineBuffer.length;
943
+ this.redrawLine();
944
+ }
945
+
946
+ async executeLine(line: string): Promise<void> {
947
+ // History expansion
948
+ const expanded = this.historyManager.expand(line);
949
+ const actualLine = expanded ?? line;
950
+
951
+ if (expanded !== null) {
952
+ // Show the expanded command
953
+ this.writeToTerminal(actualLine + '\n');
954
+ }
955
+
956
+ // Add to history
957
+ this.historyManager.add(actualLine);
958
+
959
+ this.running = true;
960
+ this.abortController = new AbortController();
961
+ this.terminalStdin = new TerminalStdin();
962
+
963
+ try {
964
+ await this.interpreter.executeLine(actualLine, this.terminalStdin, {
965
+ commandIdentity: this.commandIdentity,
966
+ runAs: this.commandIdentity.runAs,
967
+ signal: this.abortController.signal,
968
+ });
969
+ } finally {
970
+ this.terminalStdin?.close();
971
+ this.terminalStdin = null;
972
+ this.stdinLineBuffer = '';
973
+ this.stdinCursorPos = 0;
974
+ this.running = false;
975
+ this.abortController = null;
976
+ }
977
+
978
+ this.printPrompt();
979
+ this.drainPasteQueue();
980
+ this.drainTypeAhead();
981
+ }
982
+
983
+ // ─── Builtins (now with stdout/stderr params for pipe support) ───
984
+
985
+ private async builtinCd(args: string[], stderr: CommandOutputStream): Promise<number> {
986
+ const target = args[0] ?? this.env['HOME'] ?? '/home/user';
987
+ let newPath: string;
988
+
989
+ if (target === '-') {
990
+ newPath = this.env['OLDPWD'] ?? this.cwd;
991
+ } else if (target === '~' || target.startsWith('~/')) {
992
+ const home = this.env['HOME'] ?? '/home/user';
993
+ newPath = target === '~' ? home : resolve(home, target.slice(2));
994
+ } else {
995
+ newPath = resolve(this.cwd, target);
996
+ }
997
+
998
+ try {
999
+ const stat = this.vfs.stat(newPath);
1000
+ if (stat.type !== 'directory') {
1001
+ stderr.write(`cd: ${target}: Not a directory\n`);
1002
+ return 1;
1003
+ }
1004
+ this.env['OLDPWD'] = this.cwd;
1005
+ this.cwd = newPath;
1006
+ return 0;
1007
+ } catch (e) {
1008
+ if (e instanceof VFSError) {
1009
+ stderr.write(`cd: ${target}: ${e.message}\n`);
1010
+ return 1;
1011
+ }
1012
+ throw e;
1013
+ }
1014
+ }
1015
+
1016
+ private async builtinPwd(stdout: CommandOutputStream): Promise<number> {
1017
+ stdout.write(this.cwd + '\n');
1018
+ return 0;
1019
+ }
1020
+
1021
+ private async builtinEcho(args: string[], stdout: CommandOutputStream): Promise<number> {
1022
+ let interpretEscapes = false;
1023
+ let suppressNewline = false;
1024
+ let i = 0;
1025
+
1026
+ while (i < args.length) {
1027
+ const arg = args[i];
1028
+ if (arg === '--') {
1029
+ i++;
1030
+ break;
1031
+ }
1032
+ if (arg === '-n') {
1033
+ suppressNewline = true;
1034
+ i++;
1035
+ continue;
1036
+ }
1037
+ if (arg === '-e') {
1038
+ interpretEscapes = true;
1039
+ i++;
1040
+ continue;
1041
+ }
1042
+ if (arg === '-E') {
1043
+ interpretEscapes = false;
1044
+ i++;
1045
+ continue;
1046
+ }
1047
+ if (isEchoFlagCluster(arg)) {
1048
+ for (const ch of arg.slice(1)) {
1049
+ if (ch === 'n') suppressNewline = true;
1050
+ else if (ch === 'e') interpretEscapes = true;
1051
+ else if (ch === 'E') interpretEscapes = false;
1052
+ }
1053
+ i++;
1054
+ continue;
1055
+ }
1056
+ break;
1057
+ }
1058
+
1059
+ const body = args.slice(i).join(' ');
1060
+ const output = interpretEscapes ? decodeEchoEscapes(body) : body;
1061
+ stdout.write(suppressNewline ? output : `${output}\n`);
1062
+ return 0;
1063
+ }
1064
+
1065
+ private async builtinClear(): Promise<number> {
1066
+ this.terminal.clear();
1067
+ return 0;
1068
+ }
1069
+
1070
+ private async builtinExport(args: string[], stderr: CommandOutputStream): Promise<number> {
1071
+ let exitCode = 0;
1072
+ for (const arg of args) {
1073
+ const eqIdx = arg.indexOf('=');
1074
+ if (eqIdx !== -1) {
1075
+ const key = arg.slice(0, eqIdx);
1076
+ const value = arg.slice(eqIdx + 1);
1077
+ if (!this.assignEnv(key, value, stderr)) exitCode = 1;
1078
+ }
1079
+ }
1080
+ return exitCode;
1081
+ }
1082
+
1083
+ private async builtinSet(
1084
+ args: string[],
1085
+ stdout: CommandOutputStream,
1086
+ stderr: CommandOutputStream,
1087
+ context?: BuiltinExecutionContext,
1088
+ ): Promise<number> {
1089
+ if (args.length === 0) {
1090
+ for (const key of Object.keys(this.env).sort()) {
1091
+ stdout.write(`${key}=${quoteSetValue(this.env[key] ?? '')}\n`);
1092
+ }
1093
+ return 0;
1094
+ }
1095
+
1096
+ let positionalsStart = -1;
1097
+ for (let i = 0; i < args.length; i++) {
1098
+ const arg = args[i];
1099
+ if (arg === '--') {
1100
+ positionalsStart = i + 1;
1101
+ break;
1102
+ }
1103
+ if (arg === '-') {
1104
+ continue;
1105
+ }
1106
+ if (arg === '-o' || arg === '+o') {
1107
+ const option = args[i + 1];
1108
+ if (!option) {
1109
+ this.printShellOptions(stdout);
1110
+ return 0;
1111
+ }
1112
+ if (!this.setShellOptionByName(option, arg[0] === '-')) {
1113
+ stderr.write(`set: ${option}: invalid option name\n`);
1114
+ return 2;
1115
+ }
1116
+ i++;
1117
+ continue;
1118
+ }
1119
+ if (isSetOptionCluster(arg)) {
1120
+ const enabled = arg[0] === '-';
1121
+ for (let j = 1; j < arg.length; j++) {
1122
+ const flag = arg[j];
1123
+ if (flag === 'o') {
1124
+ const option = j === arg.length - 1 ? args[i + 1] : arg.slice(j + 1);
1125
+ if (!option) {
1126
+ this.printShellOptions(stdout);
1127
+ return 0;
1128
+ }
1129
+ if (!this.setShellOptionByName(option, enabled)) {
1130
+ stderr.write(`set: ${option}: invalid option name\n`);
1131
+ return 2;
1132
+ }
1133
+ if (j === arg.length - 1) i++;
1134
+ break;
1135
+ }
1136
+ if (!this.setShellOptionByFlag(flag, enabled)) {
1137
+ stderr.write(`set: -${flag}: invalid option\n`);
1138
+ return 2;
1139
+ }
1140
+ }
1141
+ continue;
1142
+ }
1143
+ positionalsStart = i;
1144
+ break;
1145
+ }
1146
+
1147
+ if (positionalsStart >= 0) {
1148
+ this.setPositionals(args.slice(positionalsStart), context);
1149
+ }
1150
+ return 0;
1151
+ }
1152
+
1153
+ private async builtinShift(
1154
+ args: string[],
1155
+ stderr: CommandOutputStream,
1156
+ context?: BuiltinExecutionContext,
1157
+ ): Promise<number> {
1158
+ if (args.length > 1) {
1159
+ stderr.write('shift: too many arguments\n');
1160
+ return 1;
1161
+ }
1162
+
1163
+ const raw = args[0] ?? '1';
1164
+ if (!isDecimalInteger(raw)) {
1165
+ stderr.write(`shift: ${raw}: numeric argument required\n`);
1166
+ return 1;
1167
+ }
1168
+
1169
+ const count = Number.parseInt(raw, 10);
1170
+ const positionals = this.currentPositionals(context);
1171
+ if (count > positionals.length) {
1172
+ stderr.write('shift: shift count out of range\n');
1173
+ return 1;
1174
+ }
1175
+
1176
+ this.setPositionals(positionals.slice(count), context);
1177
+ return 0;
1178
+ }
1179
+
1180
+ private async builtinTrap(args: string[], stdout: CommandOutputStream, stderr: CommandOutputStream): Promise<number> {
1181
+ if (args.length === 0) {
1182
+ for (const [signal, action] of this.traps.entries()) {
1183
+ stdout.write(`trap -- ${quoteSetValue(action)} ${signal}\n`);
1184
+ }
1185
+ return 0;
1186
+ }
1187
+
1188
+ let index = 0;
1189
+ if (args[index] === '--') index++;
1190
+ const action = args[index];
1191
+ if (action === undefined) {
1192
+ stderr.write('trap: missing action\n');
1193
+ return 2;
1194
+ }
1195
+ index++;
1196
+
1197
+ if (index >= args.length) {
1198
+ stderr.write('trap: missing signal\n');
1199
+ return 2;
1200
+ }
1201
+
1202
+ for (; index < args.length; index++) {
1203
+ const signal = normalizeTrapSignal(args[index]);
1204
+ if (!signal) {
1205
+ stderr.write(`trap: ${args[index]}: invalid signal\n`);
1206
+ return 2;
1207
+ }
1208
+ if (action === '-') this.traps.delete(signal);
1209
+ else this.traps.set(signal, action);
1210
+ }
1211
+ return 0;
1212
+ }
1213
+
1214
+ private async builtinHash(args: string[], stdout: CommandOutputStream, stderr: CommandOutputStream): Promise<number> {
1215
+ if (args.length === 0 || (args.length === 1 && args[0] === '-r')) return 0;
1216
+ let exitCode = 0;
1217
+ for (const arg of args) {
1218
+ if (arg.startsWith('-')) {
1219
+ stderr.write(`hash: ${arg}: invalid option\n`);
1220
+ exitCode = 2;
1221
+ continue;
1222
+ }
1223
+ const command = await this.registry.resolve(arg);
1224
+ if (!command) {
1225
+ stderr.write(`hash: ${arg}: not found\n`);
1226
+ exitCode = 1;
1227
+ } else {
1228
+ stdout.write(`${arg}\n`);
1229
+ }
1230
+ }
1231
+ return exitCode;
1232
+ }
1233
+
1234
+ private printShellOptions(stdout: CommandOutputStream): void {
1235
+ stdout.write(`errexit ${this.shellOptions.errexit ? 'on' : 'off'}\n`);
1236
+ stdout.write(`nounset ${this.shellOptions.nounset ? 'on' : 'off'}\n`);
1237
+ stdout.write(`pipefail ${this.shellOptions.pipefail ? 'on' : 'off'}\n`);
1238
+ }
1239
+
1240
+ private setShellOptionByName(option: string, enabled: boolean): boolean {
1241
+ switch (option) {
1242
+ case 'errexit':
1243
+ this.shellOptions.errexit = enabled;
1244
+ return true;
1245
+ case 'nounset':
1246
+ this.shellOptions.nounset = enabled;
1247
+ return true;
1248
+ case 'pipefail':
1249
+ this.shellOptions.pipefail = enabled;
1250
+ return true;
1251
+ default:
1252
+ return false;
1253
+ }
1254
+ }
1255
+
1256
+ private setShellOptionByFlag(flag: string, enabled: boolean): boolean {
1257
+ switch (flag) {
1258
+ case 'e':
1259
+ this.shellOptions.errexit = enabled;
1260
+ return true;
1261
+ case 'u':
1262
+ this.shellOptions.nounset = enabled;
1263
+ return true;
1264
+ default:
1265
+ return false;
1266
+ }
1267
+ }
1268
+
1269
+ private setPositionals(args: string[], context?: BuiltinExecutionContext): void {
1270
+ if (context) {
1271
+ context.setPositionals(args);
1272
+ return;
1273
+ }
1274
+ for (const key of Object.keys(this.env)) {
1275
+ if (key === '@' || key === '#' || isPositionalKey(key)) delete this.env[key];
1276
+ }
1277
+ this.env['#'] = String(args.length);
1278
+ this.env['@'] = args.join(' ');
1279
+ for (let i = 0; i < args.length; i++) {
1280
+ this.env[String(i + 1)] = args[i];
1281
+ }
1282
+ }
1283
+
1284
+ private currentPositionals(context?: BuiltinExecutionContext): string[] {
1285
+ if (context) return [...context.getPositionals()];
1286
+ const count = Number.parseInt(this.env['#'] ?? '0', 10);
1287
+ const args: string[] = [];
1288
+ for (let i = 1; i <= count; i++) args.push(this.env[String(i)] ?? '');
1289
+ return args;
1290
+ }
1291
+
1292
+ private async builtinReadonly(args: string[], stdout: CommandOutputStream, stderr: CommandOutputStream): Promise<number> {
1293
+ if (args.length === 0 || (args.length === 1 && args[0] === '-p')) {
1294
+ for (const name of Array.from(this.readonlyNames).sort()) {
1295
+ const value = this.env[name];
1296
+ stdout.write(value === undefined
1297
+ ? `readonly ${name}\n`
1298
+ : `readonly ${name}=${quoteSetValue(value)}\n`);
1299
+ }
1300
+ return 0;
1301
+ }
1302
+
1303
+ let exitCode = 0;
1304
+ for (const arg of args) {
1305
+ if (arg.startsWith('-')) {
1306
+ stderr.write(`readonly: ${arg}: invalid option\n`);
1307
+ exitCode = 2;
1308
+ continue;
1309
+ }
1310
+ const eqIdx = arg.indexOf('=');
1311
+ if (eqIdx > 0) {
1312
+ const name = arg.slice(0, eqIdx);
1313
+ if (!isShellIdentifier(name)) {
1314
+ stderr.write(`readonly: ${name}: not a valid identifier\n`);
1315
+ exitCode = 1;
1316
+ continue;
1317
+ }
1318
+ if (this.assignEnv(name, arg.slice(eqIdx + 1), stderr)) {
1319
+ this.readonlyNames.add(name);
1320
+ } else {
1321
+ exitCode = 1;
1322
+ }
1323
+ continue;
1324
+ }
1325
+ if (!isShellIdentifier(arg)) {
1326
+ stderr.write(`readonly: ${arg}: not a valid identifier\n`);
1327
+ exitCode = 1;
1328
+ continue;
1329
+ }
1330
+ this.readonlyNames.add(arg);
1331
+ }
1332
+ return exitCode;
1333
+ }
1334
+
1335
+ private async builtinRead(
1336
+ args: string[],
1337
+ stdin: CommandInputStream | undefined,
1338
+ stderr: CommandOutputStream,
1339
+ context?: BuiltinExecutionContext,
1340
+ ): Promise<number> {
1341
+ const options = parseReadArgs(args);
1342
+ if (!options.ok) {
1343
+ stderr.write(`read: ${options.error}\n`);
1344
+ return 1;
1345
+ }
1346
+ if (options.prompt && context?.isFdTerminal(0)) {
1347
+ stderr.write(options.prompt);
1348
+ }
1349
+
1350
+ const line = await readLineStdin(stdin);
1351
+ if (line === null) {
1352
+ // EOF: bash clears every named variable before returning non-zero.
1353
+ for (const name of options.names) {
1354
+ if (!this.assignEnv(name, '', stderr)) return 1;
1355
+ }
1356
+ return 1;
1357
+ }
1358
+
1359
+ const assignments = splitReadAssignments(line, options.names);
1360
+ for (const [name, value] of assignments) {
1361
+ if (!this.assignEnv(name, value, stderr)) return 1;
1362
+ }
1363
+ return 0;
1364
+ }
1365
+
1366
+ private async builtinWait(args: string[], stderr: CommandOutputStream): Promise<number> {
1367
+ const targets: Array<{ value: number; byJob: boolean }> = [];
1368
+ for (const arg of args) {
1369
+ const parsed = parseWaitTarget(arg);
1370
+ if (parsed === null) {
1371
+ stderr.write(`wait: ${arg}: not a valid job id\n`);
1372
+ return 127;
1373
+ }
1374
+ targets.push({ value: parsed.value, byJob: parsed.byJob });
1375
+ }
1376
+
1377
+ const waitables = targets.length === 0
1378
+ ? this.jobTable.list()
1379
+ .filter((job) => job.status === 'running')
1380
+ .map((job) => job.promise)
1381
+ : targets.map((target) => this.resolveWaitTarget(target.value, target.byJob, stderr));
1382
+
1383
+ let last = 0;
1384
+ for (const waitable of waitables) {
1385
+ if (!waitable) {
1386
+ last = 127;
1387
+ continue;
1388
+ }
1389
+ try {
1390
+ const result = await waitable;
1391
+ last = typeof result === 'number' ? result : 0;
1392
+ } catch {
1393
+ last = 1;
1394
+ }
1395
+ }
1396
+ return last;
1397
+ }
1398
+
1399
+ private resolveWaitTarget(
1400
+ value: number,
1401
+ byJob: boolean,
1402
+ stderr: CommandOutputStream,
1403
+ ): Promise<number> | null {
1404
+ if (byJob) {
1405
+ const job = this.jobTable.get(value);
1406
+ if (!job) {
1407
+ stderr.write(`wait: %${value}: no such job\n`);
1408
+ return null;
1409
+ }
1410
+ return job.promise;
1411
+ }
1412
+
1413
+ const proc = this.processRegistry.get(value);
1414
+ if (proc) return proc.promise;
1415
+
1416
+ const job = this.jobTable.get(value);
1417
+ if (job) return job.promise;
1418
+
1419
+ stderr.write(`wait: ${value}: no such process\n`);
1420
+ return null;
1421
+ }
1422
+
1423
+ private async builtinUnset(args: string[], stderr: CommandOutputStream): Promise<number> {
1424
+ let exitCode = 0;
1425
+ for (const arg of args) {
1426
+ // `unset arr[2]` clears one element; `unset arr` removes the variable.
1427
+ const element = /^([a-zA-Z_][a-zA-Z0-9_]*)\[([^\]]*)\]$/.exec(arg);
1428
+ const name = element === null ? arg : element[1];
1429
+ if (!isShellIdentifier(name)) continue;
1430
+ if (this.readonlyNames.has(name)) {
1431
+ stderr.write(`${name}: readonly variable\n`);
1432
+ exitCode = 1;
1433
+ continue;
1434
+ }
1435
+ if (element === null) {
1436
+ delete this.env[name];
1437
+ this.arrays.delete(name);
1438
+ continue;
1439
+ }
1440
+ const array = this.arrays.get(name);
1441
+ if (array === undefined) continue;
1442
+ const index = Number.parseInt(element[2], 10);
1443
+ if (Number.isNaN(index)) continue;
1444
+ delete array[index < 0 ? array.length + index : index];
1445
+ }
1446
+ return exitCode;
1447
+ }
1448
+
1449
+ /**
1450
+ * `local name`, `local name=value`, `local name=(word …)` and the `declare` /
1451
+ * `typeset` spellings. `local` binds each name to the running function, so
1452
+ * the value it had outside comes back when the function returns; `declare`
1453
+ * only does so when it is itself inside a function, matching bash.
1454
+ *
1455
+ * Attribute flags (-a -A -i -r -x -g) are accepted. Only -r has an effect —
1456
+ * the rest describe types this shell does not distinguish.
1457
+ */
1458
+ private async builtinDeclare(
1459
+ verb: 'local' | 'declare' | 'typeset',
1460
+ args: string[],
1461
+ stderr: CommandOutputStream,
1462
+ context?: BuiltinExecutionContext,
1463
+ ): Promise<number> {
1464
+ let readonlyFlag = false;
1465
+ let global = false;
1466
+ let exitCode = 0;
1467
+
1468
+ for (const arg of args) {
1469
+ if (arg.startsWith('-') && arg.length > 1 && !arg.includes('=')) {
1470
+ for (const flag of arg.slice(1)) {
1471
+ if (flag === 'r') readonlyFlag = true;
1472
+ else if (flag === 'g') global = true;
1473
+ else if (!'aAixlunft'.includes(flag)) {
1474
+ stderr.write(`${verb}: -${flag}: invalid option\n`);
1475
+ return 2;
1476
+ }
1477
+ }
1478
+ continue;
1479
+ }
1480
+
1481
+ const eq = arg.indexOf('=');
1482
+ const name = eq === -1 ? arg : arg.slice(0, eq);
1483
+ if (!isShellIdentifier(name)) {
1484
+ stderr.write(`${verb}: \`${arg}': not a valid identifier\n`);
1485
+ exitCode = 1;
1486
+ continue;
1487
+ }
1488
+
1489
+ const scope = verb === 'local' || !global;
1490
+ if (scope && context?.declareLocal(name) !== true && verb === 'local') {
1491
+ stderr.write(`${verb}: can only be used in a function\n`);
1492
+ return 1;
1493
+ }
1494
+
1495
+ if (eq !== -1 && !this.assignDeclared(name, arg.slice(eq + 1), stderr)) exitCode = 1;
1496
+ if (readonlyFlag) this.readonlyNames.add(name);
1497
+ }
1498
+ return exitCode;
1499
+ }
1500
+
1501
+ /** The right-hand side of a declaration: `(word …)` is an array literal. */
1502
+ private assignDeclared(name: string, text: string, stderr: CommandOutputStream): boolean {
1503
+ if (this.readonlyNames.has(name)) {
1504
+ stderr.write(`${name}: readonly variable\n`);
1505
+ return false;
1506
+ }
1507
+ if (text.startsWith('(') && text.endsWith(')')) {
1508
+ const elements: string[] = [];
1509
+ for (const token of lex(text.slice(1, -1))) {
1510
+ if (token.kind === TokenKind.Word) elements.push(unquoteWord(token));
1511
+ }
1512
+ delete this.env[name];
1513
+ this.arrays.set(name, elements);
1514
+ return true;
1515
+ }
1516
+ assignScalar(this.env, this.arrays, name, text);
1517
+ return true;
1518
+ }
1519
+
1520
+ private assignEnv(name: string, value: string, stderr: CommandOutputStream): boolean {
1521
+ if (this.readonlyNames.has(name)) {
1522
+ stderr.write(`${name}: readonly variable\n`);
1523
+ return false;
1524
+ }
1525
+ assignScalar(this.env, this.arrays, name, value);
1526
+ return true;
1527
+ }
1528
+
1529
+ private snapshotShellState(): ShellStateFrame {
1530
+ return {
1531
+ cwd: this.cwd,
1532
+ env: { ...this.env },
1533
+ arrays: cloneArrays(this.arrays),
1534
+ shellOptions: { ...this.shellOptions },
1535
+ traps: new Map(this.traps),
1536
+ readonlyNames: new Set(this.readonlyNames),
1537
+ };
1538
+ }
1539
+
1540
+ private restoreShellState(frame: ShellStateFrame): void {
1541
+ this.cwd = frame.cwd;
1542
+ replaceRecord(this.env, frame.env);
1543
+ replaceMap(this.arrays, frame.arrays);
1544
+ restoreShellOptions(this.shellOptions, frame.shellOptions);
1545
+ replaceMap(this.traps, frame.traps);
1546
+ replaceSet(this.readonlyNames, frame.readonlyNames);
1547
+ }
1548
+
1549
+ private async builtinExit(args: string[], stderr: CommandOutputStream): Promise<number> {
1550
+ if (args.length > 1) {
1551
+ stderr.write('exit: too many arguments\n');
1552
+ return 1;
1553
+ }
1554
+
1555
+ if (args.length === 0) {
1556
+ throw new ExitSignal(this.interpreter.getLastExitCode());
1557
+ }
1558
+
1559
+ const status = parseShellExitStatus(args[0] ?? '');
1560
+ if (status === null) {
1561
+ stderr.write(`exit: ${args[0]}: numeric argument required\n`);
1562
+ throw new ExitSignal(2);
1563
+ }
1564
+
1565
+ throw new ExitSignal(status);
1566
+ }
1567
+
1568
+ private async builtinJobs(stdout: CommandOutputStream): Promise<number> {
1569
+ const jobs = this.jobTable.list();
1570
+ for (const job of jobs) {
1571
+ stdout.write(`[${job.id}] ${job.status} ${job.command}\n`);
1572
+ }
1573
+ return 0;
1574
+ }
1575
+
1576
+ private async builtinFg(args: string[], stdout: CommandOutputStream, stderr: CommandOutputStream): Promise<number> {
1577
+ const id = args[0] ? parseInt(args[0], 10) : undefined;
1578
+ const jobs = this.jobTable.list();
1579
+
1580
+ if (jobs.length === 0) {
1581
+ stderr.write('fg: no current job\n');
1582
+ return 1;
1583
+ }
1584
+
1585
+ const job = id ? this.jobTable.get(id) : jobs[jobs.length - 1];
1586
+ if (!job) {
1587
+ stderr.write(`fg: ${id}: no such job\n`);
1588
+ return 1;
1589
+ }
1590
+
1591
+ stdout.write(`${job.command}\n`);
1592
+ const exitCode = await job.promise;
1593
+ this.jobTable.remove(job.id);
1594
+ return exitCode;
1595
+ }
1596
+
1597
+ private async builtinBg(args: string[], stdout: CommandOutputStream, stderr: CommandOutputStream): Promise<number> {
1598
+ const id = args[0] ? parseInt(args[0], 10) : undefined;
1599
+ const jobs = this.jobTable.list();
1600
+
1601
+ if (jobs.length === 0) {
1602
+ stderr.write('bg: no current job\n');
1603
+ return 1;
1604
+ }
1605
+
1606
+ const job = id ? this.jobTable.get(id) : jobs[jobs.length - 1];
1607
+ if (!job) {
1608
+ stderr.write(`bg: ${id}: no such job\n`);
1609
+ return 1;
1610
+ }
1611
+
1612
+ stdout.write(`[${job.id}] ${job.command} &\n`);
1613
+ return 0;
1614
+ }
1615
+
1616
+ private async builtinHistory(stdout: CommandOutputStream): Promise<number> {
1617
+ const entries = this.historyManager.getAll();
1618
+ for (let i = 0; i < entries.length; i++) {
1619
+ stdout.write(` ${i + 1} ${entries[i]}\n`);
1620
+ }
1621
+ return 0;
1622
+ }
1623
+
1624
+ async sourceFile(path: string): Promise<void> {
1625
+ try {
1626
+ const content = this.vfs.readFileString(path);
1627
+ await this.interpreter.executeLine(content);
1628
+ } catch {
1629
+ // Silently ignore missing config files
1630
+ }
1631
+ }
1632
+
1633
+ private async builtinSource(
1634
+ args: string[],
1635
+ stdout: CommandOutputStream,
1636
+ stderr: CommandOutputStream,
1637
+ context?: BuiltinExecutionContext,
1638
+ ): Promise<number> {
1639
+ if (args.length === 0) {
1640
+ stderr.write('source: missing filename\n');
1641
+ return 1;
1642
+ }
1643
+ const path = resolve(this.cwd, args[0]);
1644
+ let content: string;
1645
+ try {
1646
+ content = this.vfs.readFileString(path);
1647
+ } catch {
1648
+ stderr.write(`source: ${args[0]}: No such file\n`);
1649
+ return 1;
1650
+ }
1651
+
1652
+ if (!context) {
1653
+ stderr.write('source: execution context unavailable\n');
1654
+ return 1;
1655
+ }
1656
+
1657
+ const sourceArgs = args.slice(1);
1658
+ return context.executeInline(
1659
+ content,
1660
+ sourceArgs.length > 0 ? { positionals: sourceArgs } : undefined,
1661
+ );
1662
+ }
1663
+
1664
+ private async builtinAlias(args: string[], stdout: CommandOutputStream): Promise<number> {
1665
+ if (args.length === 0) {
1666
+ for (const [name, value] of this.aliases) {
1667
+ stdout.write(`alias ${name}='${value}'\n`);
1668
+ }
1669
+ return 0;
1670
+ }
1671
+
1672
+ for (const arg of args) {
1673
+ const eqIdx = arg.indexOf('=');
1674
+ if (eqIdx !== -1) {
1675
+ const name = arg.slice(0, eqIdx);
1676
+ const value = arg.slice(eqIdx + 1);
1677
+ this.aliases.set(name, value);
1678
+ } else {
1679
+ const value = this.aliases.get(arg);
1680
+ if (value !== undefined) {
1681
+ stdout.write(`alias ${arg}='${value}'\n`);
1682
+ } else {
1683
+ stdout.write(`alias: ${arg}: not found\n`);
1684
+ }
1685
+ }
1686
+ }
1687
+ return 0;
1688
+ }
1689
+
1690
+ private async builtinUnalias(args: string[], stderr: CommandOutputStream): Promise<number> {
1691
+ if (args.length === 0) {
1692
+ stderr.write('unalias: usage: unalias name ...\n');
1693
+ return 1;
1694
+ }
1695
+ for (const name of args) {
1696
+ if (!this.aliases.delete(name)) {
1697
+ stderr.write(`unalias: ${name}: not found\n`);
1698
+ }
1699
+ }
1700
+ return 0;
1701
+ }
1702
+
1703
+ private writeToTerminal(text: string): void {
1704
+ this.terminal.write(normalizeTerminalNewlines(text));
1705
+ }
1706
+
1707
+ }
1708
+
1709
+ function isEchoFlagCluster(arg: string): boolean {
1710
+ if (arg.length < 2 || arg[0] !== '-') return false;
1711
+ for (const ch of arg.slice(1)) {
1712
+ if (ch !== 'n' && ch !== 'e' && ch !== 'E') return false;
1713
+ }
1714
+ return true;
1715
+ }
1716
+
1717
+ function decodeEchoEscapes(input: string): string {
1718
+ let output = '';
1719
+ for (let i = 0; i < input.length; i++) {
1720
+ const ch = input[i];
1721
+ if (ch !== '\\' || i + 1 >= input.length) {
1722
+ output += ch;
1723
+ continue;
1724
+ }
1725
+
1726
+ const next = input[++i];
1727
+ switch (next) {
1728
+ case '\\': output += '\\'; break;
1729
+ case 'n': output += '\n'; break;
1730
+ case 't': output += '\t'; break;
1731
+ case 'r': output += '\r'; break;
1732
+ case 'b': output += '\b'; break;
1733
+ case 'f': output += '\f'; break;
1734
+ case 'v': output += '\v'; break;
1735
+ case 'a': output += '\x07'; break;
1736
+ case 'x': {
1737
+ const parsed = readHexEscape(input, i + 1);
1738
+ if (parsed) {
1739
+ output += String.fromCharCode(parsed.value);
1740
+ i = parsed.end - 1;
1741
+ } else {
1742
+ output += 'x';
1743
+ }
1744
+ break;
1745
+ }
1746
+ case '0': {
1747
+ const parsed = readOctalEscape(input, i + 1);
1748
+ output += String.fromCharCode(parsed.value);
1749
+ i = parsed.end - 1;
1750
+ break;
1751
+ }
1752
+ default:
1753
+ output += next;
1754
+ break;
1755
+ }
1756
+ }
1757
+ return output;
1758
+ }
1759
+
1760
+ function readHexEscape(input: string, pos: number): { value: number; end: number } | null {
1761
+ let value = 0;
1762
+ let end = pos;
1763
+ while (end < input.length && end - pos < 2) {
1764
+ const digit = hexValue(input.charCodeAt(end));
1765
+ if (digit === null) break;
1766
+ value = value * 16 + digit;
1767
+ end++;
1768
+ }
1769
+ return end === pos ? null : { value, end };
1770
+ }
1771
+
1772
+ function readOctalEscape(input: string, pos: number): { value: number; end: number } {
1773
+ let value = 0;
1774
+ let end = pos;
1775
+ while (end < input.length && end - pos < 3) {
1776
+ const code = input.charCodeAt(end);
1777
+ if (code < 48 || code > 55) break;
1778
+ value = value * 8 + (code - 48);
1779
+ end++;
1780
+ }
1781
+ return { value, end };
1782
+ }
1783
+
1784
+ function hexValue(code: number): number | null {
1785
+ if (code >= 48 && code <= 57) return code - 48;
1786
+ if (code >= 65 && code <= 70) return code - 55;
1787
+ if (code >= 97 && code <= 102) return code - 87;
1788
+ return null;
1789
+ }
1790
+
1791
+ type ReadArgs =
1792
+ | { ok: true; names: string[]; prompt?: string }
1793
+ | { ok: false; error: string };
1794
+
1795
+ function parseReadArgs(args: string[]): ReadArgs {
1796
+ const names: string[] = [];
1797
+ let prompt: string | undefined;
1798
+ let parsingOptions = true;
1799
+
1800
+ for (let i = 0; i < args.length; i++) {
1801
+ const arg = args[i];
1802
+ if (parsingOptions && arg === '--') {
1803
+ parsingOptions = false;
1804
+ continue;
1805
+ }
1806
+
1807
+ if (parsingOptions && arg.startsWith('-') && arg !== '-') {
1808
+ if (arg === '-r') continue;
1809
+ if (arg === '-p' || arg === '-rp' || arg === '-pr') {
1810
+ const next = args[++i];
1811
+ if (next === undefined) return { ok: false, error: `${arg}: option requires an argument` };
1812
+ prompt = next;
1813
+ continue;
1814
+ }
1815
+ if (arg.startsWith('-p') && arg.length > 2) {
1816
+ prompt = arg.slice(2);
1817
+ continue;
1818
+ }
1819
+ return { ok: false, error: `${arg}: unsupported option` };
1820
+ }
1821
+
1822
+ parsingOptions = false;
1823
+ names.push(arg);
1824
+ }
1825
+
1826
+ const resolvedNames = names.length > 0 ? names : ['REPLY'];
1827
+ for (const name of resolvedNames) {
1828
+ if (!isShellIdentifier(name)) return { ok: false, error: `${name}: not a valid identifier` };
1829
+ }
1830
+ return prompt === undefined
1831
+ ? { ok: true, names: resolvedNames }
1832
+ : { ok: true, names: resolvedNames, prompt };
1833
+ }
1834
+
1835
+ async function readLineStdin(stdin: CommandInputStream | undefined): Promise<string | null> {
1836
+ if (!stdin) return null;
1837
+ if (stdin.readLine) return stdin.readLine();
1838
+
1839
+ let line = '';
1840
+ let readChunk = false;
1841
+ while (true) {
1842
+ const chunk = await stdin.read();
1843
+ if (chunk === null) break;
1844
+
1845
+ readChunk = true;
1846
+ const newline = chunk.indexOf('\n');
1847
+ if (newline >= 0) return line + chunk.slice(0, newline);
1848
+ line += chunk;
1849
+ }
1850
+ if (readChunk) return line;
1851
+
1852
+ const content = await stdin.readAll();
1853
+ if (content.length === 0) return null;
1854
+
1855
+ const newline = content.indexOf('\n');
1856
+ return newline >= 0 ? content.slice(0, newline) : content;
1857
+ }
1858
+
1859
+ function splitReadAssignments(line: string, names: string[]): Array<[string, string]> {
1860
+ if (names.length === 1) return [[names[0], line]];
1861
+
1862
+ const fields = splitWhitespaceFields(line);
1863
+ const assignments: Array<[string, string]> = [];
1864
+ for (let i = 0; i < names.length; i++) {
1865
+ if (i === names.length - 1) {
1866
+ assignments.push([names[i], fields.slice(i).join(' ')]);
1867
+ } else {
1868
+ assignments.push([names[i], fields[i] ?? '']);
1869
+ }
1870
+ }
1871
+ return assignments;
1872
+ }
1873
+
1874
+ function splitWhitespaceFields(line: string): string[] {
1875
+ const fields: string[] = [];
1876
+ let current = '';
1877
+ for (let i = 0; i < line.length; i++) {
1878
+ const code = line.charCodeAt(i);
1879
+ const whitespace = code === 32 || code === 9;
1880
+ if (whitespace) {
1881
+ if (current.length > 0) {
1882
+ fields.push(current);
1883
+ current = '';
1884
+ }
1885
+ } else {
1886
+ current += line[i];
1887
+ }
1888
+ }
1889
+ if (current.length > 0) fields.push(current);
1890
+ return fields;
1891
+ }
1892
+
1893
+ function isTerminalControlSequence(data: string): boolean {
1894
+ return data.startsWith('\x1b[') || data.startsWith('\x1b(') || data.startsWith('\x1b)');
1895
+ }
1896
+
1897
+ function parseWaitTarget(arg: string): { value: number; byJob: boolean } | null {
1898
+ const byJob = arg[0] === '%';
1899
+ const text = byJob ? arg.slice(1) : arg;
1900
+ if (!isDecimalInteger(text)) return null;
1901
+ return { value: Number.parseInt(text, 10), byJob };
1902
+ }
1903
+
1904
+ /** A lexed word's text with its quoting removed, the way expansion leaves it. */
1905
+ function unquoteWord(token: { value: string; parts?: Array<{ text: string }> }): string {
1906
+ return token.parts === undefined ? token.value : token.parts.map((p) => p.text).join('');
1907
+ }
1908
+
1909
+ function isShellIdentifier(value: string): boolean {
1910
+ if (value.length === 0) return false;
1911
+ const first = value.charCodeAt(0);
1912
+ if (!isIdentifierStart(first)) return false;
1913
+ for (let i = 1; i < value.length; i++) {
1914
+ if (!isIdentifierPart(value.charCodeAt(i))) return false;
1915
+ }
1916
+ return true;
1917
+ }
1918
+
1919
+ function isPositionalKey(key: string): boolean {
1920
+ return isDecimalInteger(key);
1921
+ }
1922
+
1923
+ function isSetOptionCluster(arg: string): boolean {
1924
+ if (arg.length < 2) return false;
1925
+ if (arg[0] !== '-' && arg[0] !== '+') return false;
1926
+ return arg !== '--' && arg !== '++';
1927
+ }
1928
+
1929
+ function normalizeTrapSignal(raw: string): string | null {
1930
+ const signal = raw.toUpperCase();
1931
+ if (signal === '0' || signal === 'EXIT') return 'EXIT';
1932
+ if (signal.startsWith('SIG') && signal.length > 3) return signal.slice(3);
1933
+ if (isShellIdentifier(signal)) return signal;
1934
+ return null;
1935
+ }
1936
+
1937
+ function quoteSetValue(value: string): string {
1938
+ if (value.length === 0) return "''";
1939
+ if (isPlainSetValue(value)) return value;
1940
+ return `'${value.replace(/'/g, "'\\''")}'`;
1941
+ }
1942
+
1943
+ function isPlainSetValue(value: string): boolean {
1944
+ for (let i = 0; i < value.length; i++) {
1945
+ const code = value.charCodeAt(i);
1946
+ const ok =
1947
+ (code >= 48 && code <= 57) ||
1948
+ (code >= 65 && code <= 90) ||
1949
+ (code >= 97 && code <= 122) ||
1950
+ code === 95 ||
1951
+ code === 45 ||
1952
+ code === 46 ||
1953
+ code === 47 ||
1954
+ code === 58;
1955
+ if (!ok) return false;
1956
+ }
1957
+ return true;
1958
+ }
1959
+
1960
+ function isIdentifierStart(code: number): boolean {
1961
+ return code === 95 || (code >= 65 && code <= 90) || (code >= 97 && code <= 122);
1962
+ }
1963
+
1964
+ function isIdentifierPart(code: number): boolean {
1965
+ return isIdentifierStart(code) || (code >= 48 && code <= 57);
1966
+ }
1967
+
1968
+ function isDecimalInteger(value: string): boolean {
1969
+ if (value.length === 0) return false;
1970
+ for (let i = 0; i < value.length; i++) {
1971
+ const code = value.charCodeAt(i);
1972
+ if (code < 48 || code > 57) return false;
1973
+ }
1974
+ return true;
1975
+ }
1976
+
1977
+ function parseShellExitStatus(raw: string): number | null {
1978
+ if (raw.length === 0) return null;
1979
+
1980
+ const sign = raw[0] === '-' ? -1n : 1n;
1981
+ const digits = raw[0] === '-' || raw[0] === '+' ? raw.slice(1) : raw;
1982
+ if (!isDecimalInteger(digits)) return null;
1983
+
1984
+ const value = BigInt(digits) * sign;
1985
+ const normalized = ((value % 256n) + 256n) % 256n;
1986
+ return Number(normalized);
1987
+ }
1988
+
1989
+ type ShellStateFrame = {
1990
+ cwd: string;
1991
+ env: Record<string, string>;
1992
+ arrays: Map<string, (string | undefined)[]>;
1993
+ shellOptions: ShellOptions;
1994
+ traps: Map<string, string>;
1995
+ readonlyNames: Set<string>;
1996
+ };
1997
+
1998
+ function snapshotEnvKeys(env: Record<string, string>, keys: string[]): Map<string, string | undefined> {
1999
+ const snapshot = new Map<string, string | undefined>();
2000
+ for (const key of keys) snapshot.set(key, env[key]);
2001
+ return snapshot;
2002
+ }
2003
+
2004
+ function restoreEnvKeys(env: Record<string, string>, snapshot: Map<string, string | undefined>): void {
2005
+ for (const [key, value] of snapshot.entries()) {
2006
+ if (value === undefined) delete env[key];
2007
+ else env[key] = value;
2008
+ }
2009
+ }
2010
+
2011
+ function replaceRecord(target: Record<string, string>, source: Record<string, string>): void {
2012
+ for (const key of Object.keys(target)) delete target[key];
2013
+ Object.assign(target, source);
2014
+ }
2015
+
2016
+ function restoreShellOptions(target: ShellOptions, source: ShellOptions): void {
2017
+ target.errexit = source.errexit;
2018
+ target.nounset = source.nounset;
2019
+ target.pipefail = source.pipefail;
2020
+ }
2021
+
2022
+ /** Arrays are mutated in place, so a snapshot has to copy each one. */
2023
+ function cloneArrays(
2024
+ arrays: Map<string, (string | undefined)[]>,
2025
+ ): Map<string, (string | undefined)[]> {
2026
+ const copy = new Map<string, (string | undefined)[]>();
2027
+ for (const [name, elements] of arrays) copy.set(name, [...elements]);
2028
+ return copy;
2029
+ }
2030
+
2031
+ function replaceMap<K, V>(target: Map<K, V>, source: Map<K, V>): void {
2032
+ target.clear();
2033
+ for (const [key, value] of source.entries()) target.set(key, value);
2034
+ }
2035
+
2036
+ function replaceSet<T>(target: Set<T>, source: Set<T>): void {
2037
+ target.clear();
2038
+ for (const value of source.values()) target.add(value);
2039
+ }
2040
+
2041
+ function isVfsCred(value: unknown): value is VfsCred {
2042
+ if (typeof value !== 'object' || value === null) return false;
2043
+ if (!('uid' in value) || typeof value.uid !== 'number') return false;
2044
+ if (!('gid' in value) || typeof value.gid !== 'number') return false;
2045
+ if (!('umask' in value) || typeof value.umask !== 'number') return false;
2046
+ return 'groups' in value && Array.isArray(value.groups)
2047
+ && value.groups.every((group) => typeof group === 'number');
2048
+ }