@seanhogg/builderforce-webcontainers-core 2026.10.1 → 2026.10.3

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 (431) hide show
  1. package/dist/build.d.ts +42 -0
  2. package/dist/build.d.ts.map +1 -0
  3. package/dist/build.js +65 -0
  4. package/dist/build.js.map +1 -0
  5. package/dist/buildHost.d.ts +31 -0
  6. package/dist/buildHost.d.ts.map +1 -0
  7. package/dist/buildHost.js +125 -0
  8. package/dist/buildHost.js.map +1 -0
  9. package/dist/buildHtml.d.ts +28 -0
  10. package/dist/buildHtml.d.ts.map +1 -0
  11. package/dist/buildHtml.js +74 -0
  12. package/dist/buildHtml.js.map +1 -0
  13. package/dist/bundler.d.ts +129 -0
  14. package/dist/bundler.d.ts.map +1 -0
  15. package/dist/bundler.js +79 -0
  16. package/dist/bundler.js.map +1 -0
  17. package/dist/check/acquire.d.ts +46 -0
  18. package/dist/check/acquire.d.ts.map +1 -0
  19. package/dist/check/acquire.js +179 -0
  20. package/dist/check/acquire.js.map +1 -0
  21. package/dist/check/compilerHost.d.ts +22 -0
  22. package/dist/check/compilerHost.d.ts.map +1 -0
  23. package/dist/check/compilerHost.js +128 -0
  24. package/dist/check/compilerHost.js.map +1 -0
  25. package/dist/check/diagnostics.d.ts +23 -0
  26. package/dist/check/diagnostics.d.ts.map +1 -0
  27. package/dist/check/diagnostics.js +28 -0
  28. package/dist/check/diagnostics.js.map +1 -0
  29. package/dist/check/index.d.ts +19 -0
  30. package/dist/check/index.d.ts.map +1 -0
  31. package/dist/check/index.js +13 -0
  32. package/dist/check/index.js.map +1 -0
  33. package/dist/check/projects.d.ts +26 -0
  34. package/dist/check/projects.d.ts.map +1 -0
  35. package/dist/check/projects.js +124 -0
  36. package/dist/check/projects.js.map +1 -0
  37. package/dist/check/shims.d.ts +29 -0
  38. package/dist/check/shims.d.ts.map +1 -0
  39. package/dist/check/shims.js +76 -0
  40. package/dist/check/shims.js.map +1 -0
  41. package/dist/check/typeStore.d.ts +57 -0
  42. package/dist/check/typeStore.d.ts.map +1 -0
  43. package/dist/check/typeStore.js +89 -0
  44. package/dist/check/typeStore.js.map +1 -0
  45. package/dist/check/typecheck.d.ts +29 -0
  46. package/dist/check/typecheck.d.ts.map +1 -0
  47. package/dist/check/typecheck.js +91 -0
  48. package/dist/check/typecheck.js.map +1 -0
  49. package/dist/compileComponent.d.ts +8 -0
  50. package/dist/compileComponent.d.ts.map +1 -0
  51. package/dist/compileComponent.js +22 -0
  52. package/dist/compileComponent.js.map +1 -0
  53. package/dist/compileScript.d.ts +19 -4
  54. package/dist/compileScript.d.ts.map +1 -1
  55. package/dist/compileScript.js +37 -12
  56. package/dist/compileScript.js.map +1 -1
  57. package/dist/components.d.ts +41 -0
  58. package/dist/components.d.ts.map +1 -0
  59. package/dist/components.js +14 -0
  60. package/dist/components.js.map +1 -0
  61. package/dist/detectProject.d.ts +3 -0
  62. package/dist/detectProject.d.ts.map +1 -1
  63. package/dist/detectProject.js +16 -6
  64. package/dist/detectProject.js.map +1 -1
  65. package/dist/devServer.d.ts +5 -2
  66. package/dist/devServer.d.ts.map +1 -1
  67. package/dist/devServer.js +16 -8
  68. package/dist/devServer.js.map +1 -1
  69. package/dist/hash.d.ts +2 -0
  70. package/dist/hash.d.ts.map +1 -0
  71. package/dist/hash.js +22 -0
  72. package/dist/hash.js.map +1 -0
  73. package/dist/html.d.ts +8 -0
  74. package/dist/html.d.ts.map +1 -1
  75. package/dist/html.js +17 -1
  76. package/dist/html.js.map +1 -1
  77. package/dist/index.d.ts +25 -7
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +15 -4
  80. package/dist/index.js.map +1 -1
  81. package/dist/installer/bins.d.ts +24 -0
  82. package/dist/installer/bins.d.ts.map +1 -0
  83. package/dist/installer/bins.js +56 -0
  84. package/dist/installer/bins.js.map +1 -0
  85. package/dist/installer/index.d.ts +14 -0
  86. package/dist/installer/index.d.ts.map +1 -0
  87. package/dist/installer/index.js +9 -0
  88. package/dist/installer/index.js.map +1 -0
  89. package/dist/installer/install.d.ts +46 -0
  90. package/dist/installer/install.d.ts.map +1 -0
  91. package/dist/installer/install.js +245 -0
  92. package/dist/installer/install.js.map +1 -0
  93. package/dist/installer/lockfile.d.ts +49 -0
  94. package/dist/installer/lockfile.d.ts.map +1 -0
  95. package/dist/installer/lockfile.js +110 -0
  96. package/dist/installer/lockfile.js.map +1 -0
  97. package/dist/installer/registry.d.ts +84 -0
  98. package/dist/installer/registry.d.ts.map +1 -0
  99. package/dist/installer/registry.js +130 -0
  100. package/dist/installer/registry.js.map +1 -0
  101. package/dist/installer/semver.d.ts +38 -0
  102. package/dist/installer/semver.d.ts.map +1 -0
  103. package/dist/installer/semver.js +187 -0
  104. package/dist/installer/semver.js.map +1 -0
  105. package/dist/installer/spec.d.ts +30 -0
  106. package/dist/installer/spec.d.ts.map +1 -0
  107. package/dist/installer/spec.js +30 -0
  108. package/dist/installer/spec.js.map +1 -0
  109. package/dist/installer/tar.d.ts +17 -0
  110. package/dist/installer/tar.d.ts.map +1 -0
  111. package/dist/installer/tar.js +150 -0
  112. package/dist/installer/tar.js.map +1 -0
  113. package/dist/installer/tree.d.ts +48 -0
  114. package/dist/installer/tree.d.ts.map +1 -0
  115. package/dist/installer/tree.js +179 -0
  116. package/dist/installer/tree.js.map +1 -0
  117. package/dist/node/assert.d.ts +15 -0
  118. package/dist/node/assert.d.ts.map +1 -0
  119. package/dist/node/assert.js +137 -0
  120. package/dist/node/assert.js.map +1 -0
  121. package/dist/node/buffer.d.ts +84 -0
  122. package/dist/node/buffer.d.ts.map +1 -0
  123. package/dist/node/buffer.js +304 -0
  124. package/dist/node/buffer.js.map +1 -0
  125. package/dist/node/builtins.d.ts +25 -0
  126. package/dist/node/builtins.d.ts.map +1 -0
  127. package/dist/node/builtins.js +101 -0
  128. package/dist/node/builtins.js.map +1 -0
  129. package/dist/node/callable.d.ts +13 -0
  130. package/dist/node/callable.d.ts.map +1 -0
  131. package/dist/node/callable.js +26 -0
  132. package/dist/node/callable.js.map +1 -0
  133. package/dist/node/childProcess.d.ts +13 -0
  134. package/dist/node/childProcess.d.ts.map +1 -0
  135. package/dist/node/childProcess.js +143 -0
  136. package/dist/node/childProcess.js.map +1 -0
  137. package/dist/node/crypto.d.ts +3 -0
  138. package/dist/node/crypto.d.ts.map +1 -0
  139. package/dist/node/crypto.js +180 -0
  140. package/dist/node/crypto.js.map +1 -0
  141. package/dist/node/esm.d.ts +9 -0
  142. package/dist/node/esm.d.ts.map +1 -0
  143. package/dist/node/esm.js +202 -0
  144. package/dist/node/esm.js.map +1 -0
  145. package/dist/node/events.d.ts +40 -0
  146. package/dist/node/events.d.ts.map +1 -0
  147. package/dist/node/events.js +160 -0
  148. package/dist/node/events.js.map +1 -0
  149. package/dist/node/fs/index.d.ts +7 -0
  150. package/dist/node/fs/index.d.ts.map +1 -0
  151. package/dist/node/fs/index.js +270 -0
  152. package/dist/node/fs/index.js.map +1 -0
  153. package/dist/node/fs/stats.d.ts +93 -0
  154. package/dist/node/fs/stats.d.ts.map +1 -0
  155. package/dist/node/fs/stats.js +104 -0
  156. package/dist/node/fs/stats.js.map +1 -0
  157. package/dist/node/fs/sync.d.ts +98 -0
  158. package/dist/node/fs/sync.d.ts.map +1 -0
  159. package/dist/node/fs/sync.js +348 -0
  160. package/dist/node/fs/sync.js.map +1 -0
  161. package/dist/node/hashes.d.ts +15 -0
  162. package/dist/node/hashes.d.ts.map +1 -0
  163. package/dist/node/hashes.js +195 -0
  164. package/dist/node/hashes.js.map +1 -0
  165. package/dist/node/http/client.d.ts +35 -0
  166. package/dist/node/http/client.d.ts.map +1 -0
  167. package/dist/node/http/client.js +161 -0
  168. package/dist/node/http/client.js.map +1 -0
  169. package/dist/node/http/index.d.ts +5 -0
  170. package/dist/node/http/index.d.ts.map +1 -0
  171. package/dist/node/http/index.js +125 -0
  172. package/dist/node/http/index.js.map +1 -0
  173. package/dist/node/http/server.d.ts +135 -0
  174. package/dist/node/http/server.d.ts.map +1 -0
  175. package/dist/node/http/server.js +308 -0
  176. package/dist/node/http/server.js.map +1 -0
  177. package/dist/node/http/status.d.ts +3 -0
  178. package/dist/node/http/status.d.ts.map +1 -0
  179. package/dist/node/http/status.js +13 -0
  180. package/dist/node/http/status.js.map +1 -0
  181. package/dist/node/inspect.d.ts +22 -0
  182. package/dist/node/inspect.d.ts.map +1 -0
  183. package/dist/node/inspect.js +172 -0
  184. package/dist/node/inspect.js.map +1 -0
  185. package/dist/node/loader.d.ts +91 -0
  186. package/dist/node/loader.d.ts.map +1 -0
  187. package/dist/node/loader.js +265 -0
  188. package/dist/node/loader.js.map +1 -0
  189. package/dist/node/loop.d.ts +71 -0
  190. package/dist/node/loop.d.ts.map +1 -0
  191. package/dist/node/loop.js +189 -0
  192. package/dist/node/loop.js.map +1 -0
  193. package/dist/node/misc.d.ts +10 -0
  194. package/dist/node/misc.d.ts.map +1 -0
  195. package/dist/node/misc.js +256 -0
  196. package/dist/node/misc.js.map +1 -0
  197. package/dist/node/path.d.ts +14 -0
  198. package/dist/node/path.d.ts.map +1 -0
  199. package/dist/node/path.js +128 -0
  200. package/dist/node/path.js.map +1 -0
  201. package/dist/node/process.d.ts +31 -0
  202. package/dist/node/process.d.ts.map +1 -0
  203. package/dist/node/process.js +309 -0
  204. package/dist/node/process.js.map +1 -0
  205. package/dist/node/program.d.ts +19 -0
  206. package/dist/node/program.d.ts.map +1 -0
  207. package/dist/node/program.js +165 -0
  208. package/dist/node/program.js.map +1 -0
  209. package/dist/node/readline.d.ts +2 -0
  210. package/dist/node/readline.d.ts.map +1 -0
  211. package/dist/node/readline.js +155 -0
  212. package/dist/node/readline.js.map +1 -0
  213. package/dist/node/resolve.d.ts +45 -0
  214. package/dist/node/resolve.d.ts.map +1 -0
  215. package/dist/node/resolve.js +206 -0
  216. package/dist/node/resolve.js.map +1 -0
  217. package/dist/node/runtime.d.ts +40 -0
  218. package/dist/node/runtime.d.ts.map +1 -0
  219. package/dist/node/runtime.js +149 -0
  220. package/dist/node/runtime.js.map +1 -0
  221. package/dist/node/stream/index.d.ts +52 -0
  222. package/dist/node/stream/index.d.ts.map +1 -0
  223. package/dist/node/stream/index.js +184 -0
  224. package/dist/node/stream/index.js.map +1 -0
  225. package/dist/node/stream/readable.d.ts +83 -0
  226. package/dist/node/stream/readable.d.ts.map +1 -0
  227. package/dist/node/stream/readable.js +325 -0
  228. package/dist/node/stream/readable.js.map +1 -0
  229. package/dist/node/stream/writable.d.ts +80 -0
  230. package/dist/node/stream/writable.d.ts.map +1 -0
  231. package/dist/node/stream/writable.js +224 -0
  232. package/dist/node/stream/writable.js.map +1 -0
  233. package/dist/node/urlqs.d.ts +22 -0
  234. package/dist/node/urlqs.d.ts.map +1 -0
  235. package/dist/node/urlqs.js +165 -0
  236. package/dist/node/urlqs.js.map +1 -0
  237. package/dist/node/util.d.ts +37 -0
  238. package/dist/node/util.d.ts.map +1 -0
  239. package/dist/node/util.js +160 -0
  240. package/dist/node/util.js.map +1 -0
  241. package/dist/node/zlib.d.ts +2 -0
  242. package/dist/node/zlib.d.ts.map +1 -0
  243. package/dist/node/zlib.js +133 -0
  244. package/dist/node/zlib.js.map +1 -0
  245. package/dist/packageCdn.d.ts +12 -0
  246. package/dist/packageCdn.d.ts.map +1 -1
  247. package/dist/packageCdn.js +3 -1
  248. package/dist/packageCdn.js.map +1 -1
  249. package/dist/projectConfig.d.ts +6 -2
  250. package/dist/projectConfig.d.ts.map +1 -1
  251. package/dist/projectConfig.js +32 -8
  252. package/dist/projectConfig.js.map +1 -1
  253. package/dist/shell/builtins.d.ts +23 -0
  254. package/dist/shell/builtins.d.ts.map +1 -0
  255. package/dist/shell/builtins.js +131 -0
  256. package/dist/shell/builtins.js.map +1 -0
  257. package/dist/shell/context.d.ts +41 -0
  258. package/dist/shell/context.d.ts.map +1 -0
  259. package/dist/shell/context.js +65 -0
  260. package/dist/shell/context.js.map +1 -0
  261. package/dist/shell/devHandoff.d.ts +18 -0
  262. package/dist/shell/devHandoff.d.ts.map +1 -0
  263. package/dist/shell/devHandoff.js +36 -0
  264. package/dist/shell/devHandoff.js.map +1 -0
  265. package/dist/shell/exec.d.ts +67 -0
  266. package/dist/shell/exec.d.ts.map +1 -0
  267. package/dist/shell/exec.js +247 -0
  268. package/dist/shell/exec.js.map +1 -0
  269. package/dist/shell/expand.d.ts +28 -0
  270. package/dist/shell/expand.d.ts.map +1 -0
  271. package/dist/shell/expand.js +149 -0
  272. package/dist/shell/expand.js.map +1 -0
  273. package/dist/shell/fileCommands.d.ts +10 -0
  274. package/dist/shell/fileCommands.d.ts.map +1 -0
  275. package/dist/shell/fileCommands.js +208 -0
  276. package/dist/shell/fileCommands.js.map +1 -0
  277. package/dist/shell/lineEditor.d.ts +43 -0
  278. package/dist/shell/lineEditor.d.ts.map +1 -0
  279. package/dist/shell/lineEditor.js +234 -0
  280. package/dist/shell/lineEditor.js.map +1 -0
  281. package/dist/shell/npm.d.ts +6 -0
  282. package/dist/shell/npm.d.ts.map +1 -0
  283. package/dist/shell/npm.js +234 -0
  284. package/dist/shell/npm.js.map +1 -0
  285. package/dist/shell/parse.d.ts +73 -0
  286. package/dist/shell/parse.d.ts.map +1 -0
  287. package/dist/shell/parse.js +300 -0
  288. package/dist/shell/parse.js.map +1 -0
  289. package/dist/shell/program.d.ts +12 -0
  290. package/dist/shell/program.d.ts.map +1 -0
  291. package/dist/shell/program.js +219 -0
  292. package/dist/shell/program.js.map +1 -0
  293. package/dist/shell/textCommands.d.ts +15 -0
  294. package/dist/shell/textCommands.d.ts.map +1 -0
  295. package/dist/shell/textCommands.js +185 -0
  296. package/dist/shell/textCommands.js.map +1 -0
  297. package/dist/styleModules.d.ts +6 -0
  298. package/dist/styleModules.d.ts.map +1 -1
  299. package/dist/styleModules.js +14 -4
  300. package/dist/styleModules.js.map +1 -1
  301. package/dist/svelteCompiler.d.ts +28 -0
  302. package/dist/svelteCompiler.d.ts.map +1 -0
  303. package/dist/svelteCompiler.js +13 -0
  304. package/dist/svelteCompiler.js.map +1 -0
  305. package/dist/system/commands.d.ts +26 -0
  306. package/dist/system/commands.d.ts.map +1 -0
  307. package/dist/system/commands.js +53 -0
  308. package/dist/system/commands.js.map +1 -0
  309. package/dist/system/index.d.ts +23 -0
  310. package/dist/system/index.d.ts.map +1 -0
  311. package/dist/system/index.js +16 -0
  312. package/dist/system/index.js.map +1 -0
  313. package/dist/system/kernel.d.ts +54 -0
  314. package/dist/system/kernel.d.ts.map +1 -0
  315. package/dist/system/kernel.js +81 -0
  316. package/dist/system/kernel.js.map +1 -0
  317. package/dist/system/ports.d.ts +32 -0
  318. package/dist/system/ports.d.ts.map +1 -0
  319. package/dist/system/ports.js +57 -0
  320. package/dist/system/ports.js.map +1 -0
  321. package/dist/system/process.d.ts +32 -0
  322. package/dist/system/process.d.ts.map +1 -0
  323. package/dist/system/process.js +130 -0
  324. package/dist/system/process.js.map +1 -0
  325. package/dist/system/programs.d.ts +10 -0
  326. package/dist/system/programs.d.ts.map +1 -0
  327. package/dist/system/programs.js +22 -0
  328. package/dist/system/programs.js.map +1 -0
  329. package/dist/system/terminal.d.ts +45 -0
  330. package/dist/system/terminal.d.ts.map +1 -0
  331. package/dist/system/terminal.js +127 -0
  332. package/dist/system/terminal.js.map +1 -0
  333. package/dist/system/types.d.ts +100 -0
  334. package/dist/system/types.d.ts.map +1 -0
  335. package/dist/system/types.js +2 -0
  336. package/dist/system/types.js.map +1 -0
  337. package/dist/vfs.d.ts +28 -4
  338. package/dist/vfs.d.ts.map +1 -1
  339. package/dist/vfs.js +95 -32
  340. package/dist/vfs.js.map +1 -1
  341. package/dist/vueCompiler.d.ts +75 -0
  342. package/dist/vueCompiler.d.ts.map +1 -0
  343. package/dist/vueCompiler.js +67 -0
  344. package/dist/vueCompiler.js.map +1 -0
  345. package/package.json +18 -2
  346. package/src/build.ts +105 -0
  347. package/src/buildHost.ts +154 -0
  348. package/src/buildHtml.ts +101 -0
  349. package/src/bundler.ts +190 -0
  350. package/src/check/acquire.ts +212 -0
  351. package/src/check/compilerHost.ts +138 -0
  352. package/src/check/diagnostics.ts +48 -0
  353. package/src/check/index.ts +28 -0
  354. package/src/check/projects.ts +149 -0
  355. package/src/check/shims.ts +88 -0
  356. package/src/check/typeStore.ts +103 -0
  357. package/src/check/typecheck.ts +134 -0
  358. package/src/compileComponent.ts +21 -0
  359. package/src/compileScript.ts +42 -13
  360. package/src/components.ts +59 -0
  361. package/src/detectProject.ts +18 -6
  362. package/src/devServer.ts +19 -10
  363. package/src/hash.ts +22 -0
  364. package/src/html.ts +19 -1
  365. package/src/index.ts +36 -7
  366. package/src/installer/bins.ts +64 -0
  367. package/src/installer/index.ts +13 -0
  368. package/src/installer/install.ts +275 -0
  369. package/src/installer/lockfile.ts +146 -0
  370. package/src/installer/registry.ts +175 -0
  371. package/src/installer/semver.ts +190 -0
  372. package/src/installer/spec.ts +53 -0
  373. package/src/installer/tar.ts +155 -0
  374. package/src/installer/tree.ts +236 -0
  375. package/src/node/assert.ts +127 -0
  376. package/src/node/buffer.ts +304 -0
  377. package/src/node/builtins.ts +123 -0
  378. package/src/node/callable.ts +25 -0
  379. package/src/node/childProcess.ts +164 -0
  380. package/src/node/crypto.ts +187 -0
  381. package/src/node/esm.ts +196 -0
  382. package/src/node/events.ts +176 -0
  383. package/src/node/fs/index.ts +277 -0
  384. package/src/node/fs/stats.ts +110 -0
  385. package/src/node/fs/sync.ts +335 -0
  386. package/src/node/hashes.ts +171 -0
  387. package/src/node/http/client.ts +173 -0
  388. package/src/node/http/index.ts +122 -0
  389. package/src/node/http/server.ts +308 -0
  390. package/src/node/http/status.ts +13 -0
  391. package/src/node/inspect.ts +166 -0
  392. package/src/node/loader.ts +293 -0
  393. package/src/node/loop.ts +193 -0
  394. package/src/node/misc.ts +250 -0
  395. package/src/node/path.ts +135 -0
  396. package/src/node/process.ts +324 -0
  397. package/src/node/program.ts +170 -0
  398. package/src/node/readline.ts +157 -0
  399. package/src/node/resolve.ts +216 -0
  400. package/src/node/runtime.ts +184 -0
  401. package/src/node/stream/index.ts +196 -0
  402. package/src/node/stream/readable.ts +345 -0
  403. package/src/node/stream/writable.ts +244 -0
  404. package/src/node/urlqs.ts +162 -0
  405. package/src/node/util.ts +145 -0
  406. package/src/node/zlib.ts +145 -0
  407. package/src/packageCdn.ts +11 -1
  408. package/src/projectConfig.ts +34 -7
  409. package/src/shell/builtins.ts +141 -0
  410. package/src/shell/context.ts +89 -0
  411. package/src/shell/devHandoff.ts +49 -0
  412. package/src/shell/exec.ts +268 -0
  413. package/src/shell/expand.ts +145 -0
  414. package/src/shell/fileCommands.ts +206 -0
  415. package/src/shell/lineEditor.ts +233 -0
  416. package/src/shell/npm.ts +229 -0
  417. package/src/shell/parse.ts +295 -0
  418. package/src/shell/program.ts +223 -0
  419. package/src/shell/textCommands.ts +177 -0
  420. package/src/styleModules.ts +15 -4
  421. package/src/svelteCompiler.ts +31 -0
  422. package/src/system/commands.ts +72 -0
  423. package/src/system/index.ts +22 -0
  424. package/src/system/kernel.ts +106 -0
  425. package/src/system/ports.ts +73 -0
  426. package/src/system/process.ts +158 -0
  427. package/src/system/programs.ts +31 -0
  428. package/src/system/terminal.ts +135 -0
  429. package/src/system/types.ts +103 -0
  430. package/src/vfs.ts +92 -28
  431. package/src/vueCompiler.ts +121 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Builtins that change or inspect the shell itself (cd, export, exit…), plus
3
+ * the command tables the executor dispatches on.
4
+ */
5
+ import { findExecutable } from '../system/commands.js';
6
+ import { resolvePath } from './context.js';
7
+ import { cat, cp, ls, mkdir, mv, pwd, rm, touch } from './fileCommands.js';
8
+ import { basename, clear, dirname, echo, env, falseCommand, grep, head, printf, sleep, tail, trueCommand, wc } from './textCommands.js';
9
+ /** Coreutils: plain commands, also spawnable as standalone programs. */
10
+ export const COREUTILS = {
11
+ ls, cat, mkdir, rm, cp, mv, touch, pwd, echo, printf, head, tail, grep, wc, env, clear, sleep, basename, dirname,
12
+ true: trueCommand,
13
+ false: falseCommand,
14
+ };
15
+ /** Programs the runtime provides besides coreutils (reported by `which`/`type`). */
16
+ export const SYSTEM_PROGRAMS = ['node', 'npm', 'npx', 'jsh', 'sh', 'bash'];
17
+ const HELP = `jsh — BuilderForce WebContainers shell
18
+
19
+ Builtins: cd, pwd, export, unset, exit, source, history, type, which, help
20
+ Files: ls [-la], cat, mkdir [-p], rm [-rf], cp [-r], mv, touch
21
+ Text: echo, printf, head, tail, grep, wc, env, clear, sleep, basename, dirname
22
+ Node: node <file>, npm install|ci|run|start|test, npx <bin>
23
+ Syntax: 'quotes' "\$VARS" a && b || c; a | b > out.txt >> log 2>&1 2> err; FOO=bar cmd; $(cmd); *.js
24
+
25
+ `;
26
+ export const BUILTINS = {
27
+ async cd(ctx, shell) {
28
+ const home = shell.env.HOME && ctx.fs.isDirectory(shell.env.HOME) ? shell.env.HOME : '/';
29
+ const target = ctx.args[0] === '-' ? shell.env.OLDPWD ?? shell.cwd : ctx.args[0] ?? home;
30
+ const path = resolvePath(ctx, target);
31
+ if (!ctx.fs.isDirectory(path)) {
32
+ ctx.io.stderr(`cd: ${ctx.fs.isFile(path) ? 'not a directory' : 'no such file or directory'}: ${target}\n`);
33
+ return 1;
34
+ }
35
+ shell.env.OLDPWD = shell.cwd;
36
+ shell.cwd = path;
37
+ shell.env.PWD = path;
38
+ if (ctx.args[0] === '-')
39
+ ctx.io.stdout(path + '\n');
40
+ return 0;
41
+ },
42
+ async export(ctx, shell) {
43
+ if (!ctx.args.length) {
44
+ ctx.io.stdout(Object.entries(shell.env).map(([k, v]) => `export ${k}=${JSON.stringify(v)}`).join('\n') + '\n');
45
+ return 0;
46
+ }
47
+ for (const arg of ctx.args) {
48
+ const eq = arg.indexOf('=');
49
+ if (eq > 0)
50
+ shell.env[arg.slice(0, eq)] = arg.slice(eq + 1);
51
+ else if (!(arg in shell.env))
52
+ shell.env[arg] = '';
53
+ }
54
+ return 0;
55
+ },
56
+ async unset(ctx, shell) {
57
+ for (const name of ctx.args)
58
+ delete shell.env[name];
59
+ return 0;
60
+ },
61
+ async exit(ctx, shell) {
62
+ const code = ctx.args[0] === undefined ? shell.lastStatus : Number(ctx.args[0]);
63
+ shell.exitRequested = Number.isFinite(code) ? code & 255 : 2;
64
+ return shell.exitRequested;
65
+ },
66
+ async source(ctx, shell) {
67
+ const file = ctx.args[0];
68
+ if (!file) {
69
+ ctx.io.stderr('source: filename argument required\n');
70
+ return 2;
71
+ }
72
+ const text = ctx.fs.readText(resolvePath(ctx, file));
73
+ if (text === undefined) {
74
+ ctx.io.stderr(`source: ${file}: No such file or directory\n`);
75
+ return 1;
76
+ }
77
+ return shell.run(text);
78
+ },
79
+ async history(ctx, shell) {
80
+ ctx.io.stdout(shell.history.map((line, i) => `${String(i + 1).padStart(5)} ${line}`).join('\n') + (shell.history.length ? '\n' : ''));
81
+ return 0;
82
+ },
83
+ async help(ctx) {
84
+ ctx.io.stdout(HELP);
85
+ return 0;
86
+ },
87
+ async which(ctx) {
88
+ let status = 0;
89
+ for (const name of ctx.args.filter((a) => !a.startsWith('-'))) {
90
+ if (name in COREUTILS || SYSTEM_PROGRAMS.includes(name))
91
+ ctx.io.stdout(`/usr/local/bin/${name}\n`);
92
+ else if (name in BUILTINS)
93
+ ctx.io.stdout(`${name}: shell built-in command\n`);
94
+ else {
95
+ const file = findExecutable(ctx.fs, name, ctx.cwd, ctx.env);
96
+ if (file)
97
+ ctx.io.stdout(file + '\n');
98
+ else {
99
+ ctx.io.stderr(`${name} not found\n`);
100
+ status = 1;
101
+ }
102
+ }
103
+ }
104
+ return status;
105
+ },
106
+ async type(ctx) {
107
+ let status = 0;
108
+ for (const name of ctx.args) {
109
+ if (name in BUILTINS)
110
+ ctx.io.stdout(`${name} is a shell builtin\n`);
111
+ else if (name in COREUTILS || SYSTEM_PROGRAMS.includes(name))
112
+ ctx.io.stdout(`${name} is /usr/local/bin/${name}\n`);
113
+ else {
114
+ const file = findExecutable(ctx.fs, name, ctx.cwd, ctx.env);
115
+ if (file)
116
+ ctx.io.stdout(`${name} is ${file}\n`);
117
+ else {
118
+ ctx.io.stderr(`type: ${name}: not found\n`);
119
+ status = 1;
120
+ }
121
+ }
122
+ }
123
+ return status;
124
+ },
125
+ async set() {
126
+ return 0; // options (-e, -x) are accepted and ignored
127
+ },
128
+ };
129
+ BUILTINS['.'] = BUILTINS.source;
130
+ BUILTINS[':'] = async () => 0;
131
+ //# sourceMappingURL=builtins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/shell/builtins.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * What a shell command runs with. Builtins get the shell's own state (to `cd`
3
+ * and `export`); coreutils only need IO, cwd and the file system, which is why
4
+ * they can also be spawned as standalone programs (`spawn('ls', ['-la'])`).
5
+ */
6
+ import type { VirtualFileSystem } from '../vfs.js';
7
+ import type { Program, System } from '../system/types.js';
8
+ import { InputQueue } from '../system/terminal.js';
9
+ export interface CommandIO {
10
+ stdout(text: string): void;
11
+ stderr(text: string): void;
12
+ stdin: InputQueue;
13
+ /** stdout is a terminal (colours, `clear`). */
14
+ isTerminal: boolean;
15
+ }
16
+ export interface CommandContext {
17
+ /** Arguments after the command name. */
18
+ args: string[];
19
+ /** The command name as typed (for messages). */
20
+ name: string;
21
+ cwd: string;
22
+ env: Record<string, string>;
23
+ fs: VirtualFileSystem;
24
+ system: System;
25
+ io: CommandIO;
26
+ signal: AbortSignal;
27
+ }
28
+ export type Command = (ctx: CommandContext) => Promise<number>;
29
+ export declare function resolvePath(ctx: {
30
+ cwd: string;
31
+ env: Record<string, string>;
32
+ }, path: string): string;
33
+ /** Split `-abc` style flags from operands (`--` ends flags). */
34
+ export declare function parseFlags(args: string[], withValue?: string[]): {
35
+ flags: Set<string>;
36
+ values: Record<string, string>;
37
+ operands: string[];
38
+ };
39
+ /** Run a coreutil as a standalone program (spawned directly rather than from the shell). */
40
+ export declare function asProgram(command: Command, name: string): Program;
41
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/shell/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,UAAU,CAAC;IAClB,+CAA+C;IAC/C,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,EAAE,EAAE,iBAAiB,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,SAAS,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAE/D,wBAAgB,WAAW,CAAC,GAAG,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnG;AAED,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG;IAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B/I;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAmBjE"}
@@ -0,0 +1,65 @@
1
+ import { InputQueue } from '../system/terminal.js';
2
+ import { join, normalizePath } from '../paths.js';
3
+ export function resolvePath(ctx, path) {
4
+ if (path === '~' || path.startsWith('~/'))
5
+ return join(ctx.env.HOME ?? '/home/user', path.slice(1));
6
+ return path.startsWith('/') ? normalizePath(path) : join(ctx.cwd, path);
7
+ }
8
+ /** Split `-abc` style flags from operands (`--` ends flags). */
9
+ export function parseFlags(args, withValue = []) {
10
+ const flags = new Set();
11
+ const values = {};
12
+ const operands = [];
13
+ for (let i = 0; i < args.length; i++) {
14
+ const arg = args[i];
15
+ if (arg === '--') {
16
+ operands.push(...args.slice(i + 1));
17
+ break;
18
+ }
19
+ if (arg.startsWith('--') && arg.length > 2) {
20
+ const [k, v] = arg.slice(2).split('=', 2);
21
+ if (v !== undefined)
22
+ values[k] = v;
23
+ else if (withValue.includes(k))
24
+ values[k] = args[++i] ?? '';
25
+ else
26
+ flags.add(k);
27
+ }
28
+ else if (arg.startsWith('-') && arg.length > 1 && !/^-\d/.test(arg)) {
29
+ for (let j = 1; j < arg.length; j++) {
30
+ const f = arg[j];
31
+ if (withValue.includes(f)) {
32
+ values[f] = arg.slice(j + 1) || args[++i] || '';
33
+ break;
34
+ }
35
+ flags.add(f);
36
+ }
37
+ }
38
+ else
39
+ operands.push(arg);
40
+ }
41
+ return { flags, values, operands };
42
+ }
43
+ /** Run a coreutil as a standalone program (spawned directly rather than from the shell). */
44
+ export function asProgram(command, name) {
45
+ return async (ctx) => {
46
+ const stdin = new InputQueue();
47
+ const stop = ctx.io.onStdin((chunk) => stdin.push(chunk));
48
+ try {
49
+ return await command({
50
+ args: ctx.args,
51
+ name,
52
+ cwd: ctx.cwd,
53
+ env: ctx.env,
54
+ fs: ctx.system.fs,
55
+ system: ctx.system,
56
+ io: { stdout: ctx.io.stdout, stderr: ctx.io.stderr, stdin, isTerminal: !!ctx.io.terminal },
57
+ signal: ctx.signal,
58
+ });
59
+ }
60
+ finally {
61
+ stop();
62
+ }
63
+ };
64
+ }
65
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/shell/context.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAyBlD,MAAM,UAAU,WAAW,CAAC,GAAiD,EAAE,IAAY;IACzF,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpG,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,YAAsB,EAAE;IACjE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM;QACR,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3C,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAiC,CAAC;YAC1E,IAAI,CAAC,KAAK,SAAS;gBAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;iBAC9B,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;;gBACvD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;gBAClB,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC1B,MAAM,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBAChD,MAAM;gBACR,CAAC;gBACD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,CAAC;QACH,CAAC;;YAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,SAAS,CAAC,OAAgB,EAAE,IAAY;IACtD,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC;gBACnB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,IAAI;gBACJ,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE;gBACjB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE;gBAC1F,MAAM,EAAE,GAAG,CAAC,MAAM;aACnB,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,EAAE,CAAC;QACT,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Dev-server handoff. `vite`, `vite dev`, `react-scripts start` (what `npm run
3
+ * dev` / `npm start` usually run) cannot run here as-is — Vite itself needs
4
+ * esbuild's native binary — but the runtime already IS a Vite-style dev server:
5
+ * the in-browser DevServer serving the preview. So these commands announce that
6
+ * preview as their server (`server-ready`) and stay "running" until Ctrl-C,
7
+ * which is exactly what a host waiting on `npm run dev` expects.
8
+ */
9
+ import type { CommandContext } from './context.js';
10
+ interface Handoff {
11
+ tool: string;
12
+ defaultPort: number;
13
+ }
14
+ /** Does this command line start a dev server we hand off? */
15
+ export declare function matchDevServer(argv: string[]): Handoff | undefined;
16
+ export declare function runDevServerHandoff(ctx: CommandContext, argv: string[], handoff: Handoff): Promise<number>;
17
+ export {};
18
+ //# sourceMappingURL=devHandoff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devHandoff.d.ts","sourceRoot":"","sources":["../../src/shell/devHandoff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,GAAG,SAAS,CAMlE;AASD,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAiBhH"}
@@ -0,0 +1,36 @@
1
+ /** Does this command line start a dev server we hand off? */
2
+ export function matchDevServer(argv) {
3
+ const [command, ...rest] = argv;
4
+ const sub = rest[0] !== undefined && !rest[0].startsWith('-') ? rest[0] : undefined;
5
+ if (command === 'vite' && (sub === undefined || sub === 'dev' || sub === 'serve'))
6
+ return { tool: 'vite', defaultPort: 5173 };
7
+ if ((command === 'react-scripts' || command === 'craco') && sub === 'start')
8
+ return { tool: 'react-scripts', defaultPort: 3000 };
9
+ return undefined;
10
+ }
11
+ function portOf(argv, fallback, env) {
12
+ const at = argv.findIndex((a) => a === '--port' || a.startsWith('--port='));
13
+ const value = at < 0 ? env.PORT : argv[at].includes('=') ? argv[at].split('=')[1] : argv[at + 1];
14
+ const port = Number(value);
15
+ return Number.isInteger(port) && port > 0 ? port : fallback;
16
+ }
17
+ export async function runDevServerHandoff(ctx, argv, handoff) {
18
+ const url = ctx.system.previewUrl;
19
+ if (!url) {
20
+ ctx.io.stderr(`${handoff.tool}: no in-browser preview is attached to this runtime, so there is nothing to serve.\n`);
21
+ return 1;
22
+ }
23
+ const port = portOf(argv, handoff.defaultPort, ctx.env);
24
+ const banner = handoff.tool === 'vite'
25
+ ? `\n VITE (BuilderForce in-browser dev server) ready\n\n ➜ Local: ${url}\n\n`
26
+ : `\nCompiled successfully!\n\nYou can now view the app in the browser.\n\n Local: ${url}\n\n`;
27
+ ctx.io.stdout(banner);
28
+ ctx.system.announceServer(port, url);
29
+ await new Promise((resolve) => {
30
+ if (ctx.signal.aborted)
31
+ resolve();
32
+ ctx.signal.addEventListener('abort', () => resolve());
33
+ });
34
+ return 130;
35
+ }
36
+ //# sourceMappingURL=devHandoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devHandoff.js","sourceRoot":"","sources":["../../src/shell/devHandoff.ts"],"names":[],"mappings":"AAeA,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC9H,IAAI,CAAC,OAAO,KAAK,eAAe,IAAI,OAAO,KAAK,OAAO,CAAC,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IACjI,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,MAAM,CAAC,IAAc,EAAE,QAAgB,EAAE,GAA2B;IAC3E,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACnG,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAmB,EAAE,IAAc,EAAE,OAAgB;IAC7F,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,sFAAsF,CAAC,CAAC;QACrH,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM;QACpC,CAAC,CAAC,yEAAyE,GAAG,MAAM;QACpF,CAAC,CAAC,qFAAqF,GAAG,MAAM,CAAC;IACnG,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtB,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACrC,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAClC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,CAAC;QAClC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The executor: runs a parsed script. Lists honour `&&`/`||`/`;`/`&`; pipeline
3
+ * stages run concurrently, joined by in-memory pipes; redirects swap a stage's
4
+ * stdin/stdout/stderr for files. Dispatch order per command: shell builtins,
5
+ * extra in-process commands (npm, npx), the dev-server handoff, coreutils, and
6
+ * finally `system.spawn` (node, scripts on PATH, `.bin` entries) — which in the
7
+ * browser is a separate Web Worker.
8
+ */
9
+ import type { System } from '../system/types.js';
10
+ import { InputQueue } from '../system/terminal.js';
11
+ import { type ShellState } from './builtins.js';
12
+ import { type CommandContext } from './context.js';
13
+ export interface ShellIO {
14
+ stdout(text: string): void;
15
+ stderr(text: string): void;
16
+ /** stdout is a terminal. */
17
+ isTerminal: boolean;
18
+ }
19
+ /** A job's stdin: a queue, and (interactive) a raw keystroke tap for a terminal-attached child. */
20
+ export interface JobInput {
21
+ queue: InputQueue;
22
+ /** Route raw terminal input straight to `sink` (a child with its own line discipline), or back to the queue. */
23
+ setRawSink?(sink: ((data: string) => void) | undefined): void;
24
+ }
25
+ /** In-process commands with access to the shell (npm runs scripts through it). */
26
+ export type ShellCommand = (ctx: CommandContext, shell: Shell, input: JobInput) => Promise<number>;
27
+ export interface ShellOptions {
28
+ system: System;
29
+ cwd: string;
30
+ env: Record<string, string>;
31
+ positional?: string[];
32
+ /** The terminal size, when attached to one. */
33
+ terminalSize?: () => {
34
+ cols: number;
35
+ rows: number;
36
+ } | undefined;
37
+ commands?: Record<string, ShellCommand>;
38
+ }
39
+ export declare class Shell implements ShellState {
40
+ readonly options: ShellOptions;
41
+ cwd: string;
42
+ env: Record<string, string>;
43
+ lastStatus: number;
44
+ history: string[];
45
+ exitRequested?: number;
46
+ readonly pid: number;
47
+ readonly system: System;
48
+ private readonly positional;
49
+ private current?;
50
+ constructor(options: ShellOptions);
51
+ /** A child shell for `npm run` / subshells: same IO, its own cwd and environment. */
52
+ fork(overrides: {
53
+ cwd?: string;
54
+ env?: Record<string, string>;
55
+ positional?: string[];
56
+ }): Shell;
57
+ /** Parse and run `source`. Syntax errors print and return 2. */
58
+ exec(source: string, io: ShellIO, input: JobInput, signal: AbortSignal): Promise<number>;
59
+ /** `source` and friends: run in this shell with the current job's IO. */
60
+ run(source: string): Promise<number>;
61
+ private expandContext;
62
+ private runPipeline;
63
+ private runCommand;
64
+ private dispatch;
65
+ private spawnExternal;
66
+ }
67
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/shell/exec.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAGhE,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,4BAA4B;IAC5B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,mGAAmG;AACnG,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,UAAU,CAAC;IAClB,gHAAgH;IAChH,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC;CAC/D;AAED,kFAAkF;AAClF,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEnG,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC;AAID,qBAAa,KAAM,YAAW,UAAU;IAW1B,QAAQ,CAAC,OAAO,EAAE,YAAY;IAV1C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,UAAU,SAAK;IACf,OAAO,EAAE,MAAM,EAAE,CAAM;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,SAAkB;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAW;IACtC,OAAO,CAAC,OAAO,CAAC,CAAwD;gBAEnD,OAAO,EAAE,YAAY;IAO1C,qFAAqF;IACrF,IAAI,CAAC,SAAS,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,KAAK;IAI7F,gEAAgE;IAC1D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAmC9F,yEAAyE;IACzE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMpC,OAAO,CAAC,aAAa;YAkBP,WAAW;YAmBX,UAAU;YA+DV,QAAQ;YAwBR,aAAa;CA0B5B"}
@@ -0,0 +1,247 @@
1
+ import { InputQueue } from '../system/terminal.js';
2
+ import { parse, ShellSyntaxError } from './parse.js';
3
+ import { expandWord, expandWords } from './expand.js';
4
+ import { BUILTINS, COREUTILS } from './builtins.js';
5
+ import { resolvePath } from './context.js';
6
+ import { matchDevServer, runDevServerHandoff } from './devHandoff.js';
7
+ let nextShellPid = 500;
8
+ export class Shell {
9
+ options;
10
+ cwd;
11
+ env;
12
+ lastStatus = 0;
13
+ history = [];
14
+ exitRequested;
15
+ pid = nextShellPid++;
16
+ system;
17
+ positional;
18
+ current;
19
+ constructor(options) {
20
+ this.options = options;
21
+ this.system = options.system;
22
+ this.cwd = options.cwd;
23
+ this.env = { ...options.env, PWD: options.cwd };
24
+ this.positional = options.positional ?? [];
25
+ }
26
+ /** A child shell for `npm run` / subshells: same IO, its own cwd and environment. */
27
+ fork(overrides) {
28
+ return new Shell({ ...this.options, cwd: overrides.cwd ?? this.cwd, env: { ...this.env, ...overrides.env }, positional: overrides.positional });
29
+ }
30
+ /** Parse and run `source`. Syntax errors print and return 2. */
31
+ async exec(source, io, input, signal) {
32
+ let script;
33
+ try {
34
+ script = parse(source);
35
+ }
36
+ catch (error) {
37
+ if (!(error instanceof ShellSyntaxError))
38
+ throw error;
39
+ io.stderr(`jsh: ${error.message}\n`);
40
+ this.lastStatus = 2;
41
+ return 2;
42
+ }
43
+ const previous = this.current;
44
+ this.current = { io, input, signal };
45
+ try {
46
+ for (const list of script) {
47
+ if (this.exitRequested !== undefined || signal.aborted)
48
+ break;
49
+ const run = async () => {
50
+ let status = await this.runPipeline(list.first, io, input, signal);
51
+ for (const { op, pipeline } of list.rest) {
52
+ if (this.exitRequested !== undefined || signal.aborted)
53
+ break;
54
+ if ((op === '&&') === (status === 0))
55
+ status = await this.runPipeline(pipeline, io, input, signal);
56
+ }
57
+ return status;
58
+ };
59
+ if (list.background) {
60
+ void run();
61
+ this.lastStatus = 0;
62
+ }
63
+ else
64
+ this.lastStatus = await run();
65
+ }
66
+ }
67
+ finally {
68
+ this.current = previous;
69
+ }
70
+ if (signal.aborted && this.lastStatus === 0)
71
+ this.lastStatus = 130;
72
+ return this.exitRequested ?? this.lastStatus;
73
+ }
74
+ /** `source` and friends: run in this shell with the current job's IO. */
75
+ run(source) {
76
+ const job = this.current;
77
+ if (!job)
78
+ throw new Error('Shell.run outside a job');
79
+ return this.exec(source, job.io, job.input, job.signal);
80
+ }
81
+ expandContext(io, signal) {
82
+ return {
83
+ fs: this.system.fs,
84
+ cwd: this.cwd,
85
+ get: (name) => this.env[name],
86
+ set: (name, value) => void (this.env[name] = value),
87
+ positional: this.positional,
88
+ lastStatus: this.lastStatus,
89
+ pid: this.pid,
90
+ substitute: async (source) => {
91
+ let out = '';
92
+ const sub = this.fork({});
93
+ await sub.exec(source, { stdout: (t) => (out += t), stderr: io.stderr, isTerminal: false }, { queue: emptyInput() }, signal);
94
+ return out;
95
+ },
96
+ };
97
+ }
98
+ async runPipeline(pipeline, io, input, signal) {
99
+ const count = pipeline.commands.length;
100
+ const pipes = Array.from({ length: count - 1 }, () => new InputQueue());
101
+ const statuses = await Promise.all(pipeline.commands.map(async (command, i) => {
102
+ const stdin = i === 0 ? input : { queue: pipes[i - 1] };
103
+ const stdout = i === count - 1 ? io.stdout : (text) => pipes[i].push(text);
104
+ const stageIO = { stdout, stderr: io.stderr, isTerminal: io.isTerminal && i === count - 1 };
105
+ try {
106
+ return await this.runCommand(command, stageIO, stdin, signal, count === 1);
107
+ }
108
+ finally {
109
+ if (i < count - 1)
110
+ pipes[i].push(null);
111
+ }
112
+ }));
113
+ const status = statuses[statuses.length - 1];
114
+ return pipeline.negate ? (status === 0 ? 1 : 0) : status;
115
+ }
116
+ async runCommand(node, io, input, signal, alone) {
117
+ const ectx = this.expandContext(io, signal);
118
+ const argv = await expandWords(node.words, ectx);
119
+ const assigned = {};
120
+ for (const { name, value } of node.assignments)
121
+ assigned[name] = (await expandWord(value, ectx, { split: false, glob: false })).join('');
122
+ if (!argv.length) {
123
+ Object.assign(this.env, assigned);
124
+ return 0;
125
+ }
126
+ // Redirects.
127
+ let stdout = io.stdout;
128
+ let stderr = io.stderr;
129
+ let stdin = input;
130
+ let isTerminal = io.isTerminal;
131
+ const flushes = [];
132
+ for (const redirect of node.redirects) {
133
+ if (redirect.op === '2>&1') {
134
+ stderr = stdout;
135
+ continue;
136
+ }
137
+ if (redirect.op === '>&2') {
138
+ stdout = stderr;
139
+ continue;
140
+ }
141
+ const target = (await expandWord(redirect.target, ectx)).join(' ');
142
+ const path = resolvePath(this, target);
143
+ if (redirect.op === '<') {
144
+ const text = this.system.fs.readText(path);
145
+ if (text === undefined) {
146
+ io.stderr(`jsh: ${target}: No such file or directory\n`);
147
+ return 1;
148
+ }
149
+ const queue = new InputQueue();
150
+ queue.push(text);
151
+ queue.push(null);
152
+ stdin = { queue };
153
+ continue;
154
+ }
155
+ if (this.system.fs.isDirectory(path)) {
156
+ io.stderr(`jsh: ${target}: Is a directory\n`);
157
+ return 1;
158
+ }
159
+ const append = redirect.op === '>>' || redirect.op === '2>>';
160
+ let content = append ? this.system.fs.readText(path) ?? '' : '';
161
+ this.system.fs.writeFile(path, content);
162
+ const sink = (text) => void (content += text);
163
+ flushes.push(() => this.system.fs.writeFile(path, content));
164
+ if (redirect.op === '2>' || redirect.op === '2>>')
165
+ stderr = sink;
166
+ else if (redirect.op === '&>')
167
+ stdout = stderr = sink;
168
+ else {
169
+ stdout = sink;
170
+ isTerminal = false;
171
+ }
172
+ }
173
+ try {
174
+ return await this.dispatch(argv, assigned, { stdout, stderr, isTerminal }, stdin, signal, alone && isTerminal);
175
+ }
176
+ finally {
177
+ for (const flush of flushes)
178
+ flush();
179
+ }
180
+ }
181
+ async dispatch(argv, assigned, io, input, signal, attachTerminal) {
182
+ const [name, ...args] = argv;
183
+ const env = { ...this.env, ...assigned };
184
+ const ctx = {
185
+ args,
186
+ name,
187
+ cwd: this.cwd,
188
+ env,
189
+ fs: this.system.fs,
190
+ system: this.system,
191
+ io: { stdout: io.stdout, stderr: io.stderr, stdin: input.queue, isTerminal: io.isTerminal },
192
+ signal,
193
+ };
194
+ const builtin = BUILTINS[name];
195
+ if (builtin)
196
+ return builtin(ctx, this);
197
+ const command = this.options.commands?.[name];
198
+ if (command)
199
+ return command(ctx, this, input);
200
+ const handoff = matchDevServer(argv);
201
+ if (handoff)
202
+ return runDevServerHandoff(ctx, argv, handoff);
203
+ const coreutil = COREUTILS[name];
204
+ if (coreutil)
205
+ return coreutil(ctx);
206
+ return this.spawnExternal(name, args, env, io, input, signal, attachTerminal);
207
+ }
208
+ async spawnExternal(name, args, env, io, input, signal, attachTerminal) {
209
+ const size = attachTerminal ? this.options.terminalSize?.() : undefined;
210
+ let child;
211
+ try {
212
+ child = this.system.spawn(name, args, { cwd: this.cwd, env, terminal: size });
213
+ }
214
+ catch (error) {
215
+ if (error.code !== 'ENOENT')
216
+ throw error;
217
+ io.stderr(`jsh: command not found: ${name}\n`);
218
+ return 127;
219
+ }
220
+ child.onStdout(io.stdout);
221
+ child.onStderr(io.stderr);
222
+ let stop;
223
+ if (size && input.setRawSink)
224
+ input.setRawSink((data) => child.write(data));
225
+ else
226
+ stop = input.queue.subscribe((chunk) => (chunk === null ? child.closeStdin() : child.write(chunk)));
227
+ const onAbort = () => child.kill(typeof signal.reason === 'string' ? signal.reason : 'SIGINT');
228
+ if (signal.aborted)
229
+ onAbort();
230
+ signal.addEventListener('abort', onAbort);
231
+ try {
232
+ return await child.exit;
233
+ }
234
+ finally {
235
+ signal.removeEventListener('abort', onAbort);
236
+ if (size && input.setRawSink)
237
+ input.setRawSink(undefined);
238
+ stop?.();
239
+ }
240
+ }
241
+ }
242
+ function emptyInput() {
243
+ const queue = new InputQueue();
244
+ queue.push(null);
245
+ return queue;
246
+ }
247
+ //# sourceMappingURL=exec.js.map