@nimbus-sh/worker 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (408) hide show
  1. package/README.md +219 -0
  2. package/dist/_shared/bytes.d.ts +18 -0
  3. package/dist/_shared/bytes.d.ts.map +1 -0
  4. package/dist/_shared/bytes.js +17 -0
  5. package/dist/_shared/cache-stats.d.ts +146 -0
  6. package/dist/_shared/cache-stats.d.ts.map +1 -0
  7. package/dist/_shared/cache-stats.js +162 -0
  8. package/dist/_shared/exports-resolver.d.ts +76 -0
  9. package/dist/_shared/exports-resolver.d.ts.map +1 -0
  10. package/dist/_shared/exports-resolver.js +284 -0
  11. package/dist/_shared/install-phase.d.ts +47 -0
  12. package/dist/_shared/install-phase.d.ts.map +1 -0
  13. package/dist/_shared/install-phase.js +1 -0
  14. package/dist/_shared/real-node-imports.d.ts +38 -0
  15. package/dist/_shared/real-node-imports.d.ts.map +1 -0
  16. package/dist/_shared/real-node-imports.js +46 -0
  17. package/dist/_shared/retry.d.ts +93 -0
  18. package/dist/_shared/retry.d.ts.map +1 -0
  19. package/dist/_shared/retry.js +161 -0
  20. package/dist/_shared/session-id.d.ts +39 -0
  21. package/dist/_shared/session-id.d.ts.map +1 -0
  22. package/dist/_shared/session-id.js +127 -0
  23. package/dist/_shared/session-router.d.ts +104 -0
  24. package/dist/_shared/session-router.d.ts.map +1 -0
  25. package/dist/_shared/session-router.js +165 -0
  26. package/dist/_shared/w7-frame.d.ts +93 -0
  27. package/dist/_shared/w7-frame.d.ts.map +1 -0
  28. package/dist/_shared/w7-frame.js +402 -0
  29. package/dist/auth/index.d.ts +16 -0
  30. package/dist/auth/index.d.ts.map +1 -0
  31. package/dist/auth/index.js +15 -0
  32. package/dist/auth/middleware.d.ts +85 -0
  33. package/dist/auth/middleware.d.ts.map +1 -0
  34. package/dist/auth/middleware.js +150 -0
  35. package/dist/auth/token.d.ts +96 -0
  36. package/dist/auth/token.d.ts.map +1 -0
  37. package/dist/auth/token.js +226 -0
  38. package/dist/auth/types.d.ts +141 -0
  39. package/dist/auth/types.d.ts.map +1 -0
  40. package/dist/auth/types.js +114 -0
  41. package/dist/bindings/d1.d.ts +102 -0
  42. package/dist/bindings/d1.d.ts.map +1 -0
  43. package/dist/bindings/d1.js +549 -0
  44. package/dist/bindings/kv.d.ts +82 -0
  45. package/dist/bindings/kv.d.ts.map +1 -0
  46. package/dist/bindings/kv.js +290 -0
  47. package/dist/bindings/r2.d.ts +137 -0
  48. package/dist/bindings/r2.d.ts.map +1 -0
  49. package/dist/bindings/r2.js +379 -0
  50. package/dist/cirrus-npm-cjs.generated.d.ts +17 -0
  51. package/dist/cirrus-npm-cjs.generated.d.ts.map +1 -0
  52. package/dist/cirrus-npm-cjs.generated.js +41 -0
  53. package/dist/cirrus-plugin-react.generated.d.ts +34 -0
  54. package/dist/cirrus-plugin-react.generated.d.ts.map +1 -0
  55. package/dist/cirrus-plugin-react.generated.js +33 -0
  56. package/dist/constants.d.ts +34 -0
  57. package/dist/constants.d.ts.map +1 -0
  58. package/dist/constants.js +116 -0
  59. package/dist/esbuild-wasm-bundle.generated.d.ts +41 -0
  60. package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -0
  61. package/dist/esbuild-wasm-bundle.generated.js +40 -0
  62. package/dist/facets/cirrus-real.d.ts +147 -0
  63. package/dist/facets/cirrus-real.d.ts.map +1 -0
  64. package/dist/facets/cirrus-real.js +981 -0
  65. package/dist/facets/inner-do-registry.d.ts +41 -0
  66. package/dist/facets/inner-do-registry.d.ts.map +1 -0
  67. package/dist/facets/inner-do-registry.js +51 -0
  68. package/dist/facets/manager.d.ts +314 -0
  69. package/dist/facets/manager.d.ts.map +1 -0
  70. package/dist/facets/manager.js +2681 -0
  71. package/dist/facets/process.d.ts +318 -0
  72. package/dist/facets/process.d.ts.map +1 -0
  73. package/dist/facets/process.js +567 -0
  74. package/dist/facets/real-vite-fs-shim.d.ts +151 -0
  75. package/dist/facets/real-vite-fs-shim.d.ts.map +1 -0
  76. package/dist/facets/real-vite-fs-shim.js +1279 -0
  77. package/dist/facets/real-vite-hmr.d.ts +142 -0
  78. package/dist/facets/real-vite-hmr.d.ts.map +1 -0
  79. package/dist/facets/real-vite-hmr.js +476 -0
  80. package/dist/facets/vite-dev-server.d.ts +293 -0
  81. package/dist/facets/vite-dev-server.d.ts.map +1 -0
  82. package/dist/facets/vite-dev-server.js +2580 -0
  83. package/dist/facets/wasm-swap-registry.d.ts +261 -0
  84. package/dist/facets/wasm-swap-registry.d.ts.map +1 -0
  85. package/dist/facets/wasm-swap-registry.js +551 -0
  86. package/dist/facets/ws-terminal.d.ts +107 -0
  87. package/dist/facets/ws-terminal.d.ts.map +1 -0
  88. package/dist/facets/ws-terminal.js +207 -0
  89. package/dist/git/commands.d.ts +13 -0
  90. package/dist/git/commands.d.ts.map +1 -0
  91. package/dist/git/commands.js +633 -0
  92. package/dist/git/network-facet.d.ts +61 -0
  93. package/dist/git/network-facet.d.ts.map +1 -0
  94. package/dist/git/network-facet.js +700 -0
  95. package/dist/git-bundle.generated.d.ts +16 -0
  96. package/dist/git-bundle.generated.d.ts.map +1 -0
  97. package/dist/git-bundle.generated.js +15 -0
  98. package/dist/index.d.ts +41 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +73 -0
  101. package/dist/loaders/child-process/spawn-facet.d.ts +90 -0
  102. package/dist/loaders/child-process/spawn-facet.d.ts.map +1 -0
  103. package/dist/loaders/child-process/spawn-facet.js +103 -0
  104. package/dist/loaders/child-process/spawn-pool.d.ts +110 -0
  105. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -0
  106. package/dist/loaders/child-process/spawn-pool.js +161 -0
  107. package/dist/loaders/fanout-pool.d.ts +195 -0
  108. package/dist/loaders/fanout-pool.d.ts.map +1 -0
  109. package/dist/loaders/fanout-pool.js +326 -0
  110. package/dist/loaders/generated-workers.d.ts +26 -0
  111. package/dist/loaders/generated-workers.d.ts.map +1 -0
  112. package/dist/loaders/generated-workers.js +25 -0
  113. package/dist/loaders/index.d.ts +15 -0
  114. package/dist/loaders/index.d.ts.map +1 -0
  115. package/dist/loaders/index.js +13 -0
  116. package/dist/loaders/loader-pool.d.ts +273 -0
  117. package/dist/loaders/loader-pool.d.ts.map +1 -0
  118. package/dist/loaders/loader-pool.js +624 -0
  119. package/dist/loaders/npm-resolve-preamble.d.ts +34 -0
  120. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -0
  121. package/dist/loaders/npm-resolve-preamble.js +237 -0
  122. package/dist/loaders/pre-bundle-preamble.d.ts +41 -0
  123. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -0
  124. package/dist/loaders/pre-bundle-preamble.js +114 -0
  125. package/dist/loaders/vendor/codegen.d.ts +24 -0
  126. package/dist/loaders/vendor/codegen.d.ts.map +1 -0
  127. package/dist/loaders/vendor/codegen.js +44 -0
  128. package/dist/loaders/vendor/errors.d.ts +24 -0
  129. package/dist/loaders/vendor/errors.d.ts.map +1 -0
  130. package/dist/loaders/vendor/errors.js +46 -0
  131. package/dist/loaders/vendor/index.d.ts +16 -0
  132. package/dist/loaders/vendor/index.d.ts.map +1 -0
  133. package/dist/loaders/vendor/index.js +11 -0
  134. package/dist/loaders/vendor/pool.d.ts +88 -0
  135. package/dist/loaders/vendor/pool.d.ts.map +1 -0
  136. package/dist/loaders/vendor/pool.js +353 -0
  137. package/dist/loaders/vendor/primitives.d.ts +11 -0
  138. package/dist/loaders/vendor/primitives.d.ts.map +1 -0
  139. package/dist/loaders/vendor/primitives.js +33 -0
  140. package/dist/loaders/vendor/serialize.d.ts +3 -0
  141. package/dist/loaders/vendor/serialize.d.ts.map +1 -0
  142. package/dist/loaders/vendor/serialize.js +25 -0
  143. package/dist/loaders/vendor/types.d.ts +60 -0
  144. package/dist/loaders/vendor/types.d.ts.map +1 -0
  145. package/dist/loaders/vendor/types.js +4 -0
  146. package/dist/npm/cache.d.ts +136 -0
  147. package/dist/npm/cache.d.ts.map +1 -0
  148. package/dist/npm/cache.js +429 -0
  149. package/dist/npm/install-batch-facet.d.ts +129 -0
  150. package/dist/npm/install-batch-facet.d.ts.map +1 -0
  151. package/dist/npm/install-batch-facet.js +598 -0
  152. package/dist/npm/install-facet.d.ts +29 -0
  153. package/dist/npm/install-facet.d.ts.map +1 -0
  154. package/dist/npm/install-facet.js +9 -0
  155. package/dist/npm/installer.d.ts +239 -0
  156. package/dist/npm/installer.d.ts.map +1 -0
  157. package/dist/npm/installer.js +2022 -0
  158. package/dist/npm/npx-install.d.ts +74 -0
  159. package/dist/npm/npx-install.d.ts.map +1 -0
  160. package/dist/npm/npx-install.js +302 -0
  161. package/dist/npm/pre-bundle-facet.d.ts +168 -0
  162. package/dist/npm/pre-bundle-facet.d.ts.map +1 -0
  163. package/dist/npm/pre-bundle-facet.js +653 -0
  164. package/dist/npm/r2-cache.d.ts +286 -0
  165. package/dist/npm/r2-cache.d.ts.map +1 -0
  166. package/dist/npm/r2-cache.js +506 -0
  167. package/dist/npm/resolve-facet.d.ts +202 -0
  168. package/dist/npm/resolve-facet.d.ts.map +1 -0
  169. package/dist/npm/resolve-facet.js +833 -0
  170. package/dist/npm/resolve-one-facet.d.ts +204 -0
  171. package/dist/npm/resolve-one-facet.d.ts.map +1 -0
  172. package/dist/npm/resolve-one-facet.js +437 -0
  173. package/dist/npm/resolver.d.ts +109 -0
  174. package/dist/npm/resolver.d.ts.map +1 -0
  175. package/dist/npm/resolver.js +899 -0
  176. package/dist/npm/tarball-stream.d.ts +85 -0
  177. package/dist/npm/tarball-stream.d.ts.map +1 -0
  178. package/dist/npm/tarball-stream.js +205 -0
  179. package/dist/npm/tarball.d.ts +51 -0
  180. package/dist/npm/tarball.d.ts.map +1 -0
  181. package/dist/npm/tarball.js +185 -0
  182. package/dist/observability/diag-counters.d.ts +292 -0
  183. package/dist/observability/diag-counters.d.ts.map +1 -0
  184. package/dist/observability/diag-counters.js +302 -0
  185. package/dist/observability/heap-estimate.d.ts +166 -0
  186. package/dist/observability/heap-estimate.d.ts.map +1 -0
  187. package/dist/observability/heap-estimate.js +192 -0
  188. package/dist/observability/heavy-alloc-coord.d.ts +95 -0
  189. package/dist/observability/heavy-alloc-coord.d.ts.map +1 -0
  190. package/dist/observability/heavy-alloc-coord.js +149 -0
  191. package/dist/observability/oom-classify.d.ts +56 -0
  192. package/dist/observability/oom-classify.d.ts.map +1 -0
  193. package/dist/observability/oom-classify.js +118 -0
  194. package/dist/observability/oom-discriminator.d.ts +192 -0
  195. package/dist/observability/oom-discriminator.d.ts.map +1 -0
  196. package/dist/observability/oom-discriminator.js +233 -0
  197. package/dist/real-vite-bundle.generated.d.ts +46 -0
  198. package/dist/real-vite-bundle.generated.d.ts.map +1 -0
  199. package/dist/real-vite-bundle.generated.js +53 -0
  200. package/dist/replica/routing.d.ts +171 -0
  201. package/dist/replica/routing.d.ts.map +1 -0
  202. package/dist/replica/routing.js +288 -0
  203. package/dist/replica/suspension.d.ts +36 -0
  204. package/dist/replica/suspension.d.ts.map +1 -0
  205. package/dist/replica/suspension.js +49 -0
  206. package/dist/router/index.d.ts +156 -0
  207. package/dist/router/index.d.ts.map +1 -0
  208. package/dist/router/index.js +220 -0
  209. package/dist/runtime/assets-loader.d.ts +71 -0
  210. package/dist/runtime/assets-loader.d.ts.map +1 -0
  211. package/dist/runtime/assets-loader.js +128 -0
  212. package/dist/runtime/barrel-detect.d.ts +46 -0
  213. package/dist/runtime/barrel-detect.d.ts.map +1 -0
  214. package/dist/runtime/barrel-detect.js +73 -0
  215. package/dist/runtime/barrel-synthesizer.d.ts +181 -0
  216. package/dist/runtime/barrel-synthesizer.d.ts.map +1 -0
  217. package/dist/runtime/barrel-synthesizer.js +541 -0
  218. package/dist/runtime/bun-repl.d.ts +46 -0
  219. package/dist/runtime/bun-repl.d.ts.map +1 -0
  220. package/dist/runtime/bun-repl.js +326 -0
  221. package/dist/runtime/bun-runner.d.ts +66 -0
  222. package/dist/runtime/bun-runner.d.ts.map +1 -0
  223. package/dist/runtime/bun-runner.js +219 -0
  224. package/dist/runtime/clang-runner.d.ts +38 -0
  225. package/dist/runtime/clang-runner.d.ts.map +1 -0
  226. package/dist/runtime/clang-runner.js +1033 -0
  227. package/dist/runtime/comment-strip.d.ts +37 -0
  228. package/dist/runtime/comment-strip.d.ts.map +1 -0
  229. package/dist/runtime/comment-strip.js +74 -0
  230. package/dist/runtime/esbuild-service.d.ts +201 -0
  231. package/dist/runtime/esbuild-service.d.ts.map +1 -0
  232. package/dist/runtime/esbuild-service.js +1444 -0
  233. package/dist/runtime/esbuild-wasm-bytes.d.ts +87 -0
  234. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -0
  235. package/dist/runtime/esbuild-wasm-bytes.js +131 -0
  236. package/dist/runtime/framework-detect.d.ts +71 -0
  237. package/dist/runtime/framework-detect.d.ts.map +1 -0
  238. package/dist/runtime/framework-detect.js +178 -0
  239. package/dist/runtime/long-running-handle.d.ts +133 -0
  240. package/dist/runtime/long-running-handle.d.ts.map +1 -0
  241. package/dist/runtime/long-running-handle.js +192 -0
  242. package/dist/runtime/node-repl.d.ts +36 -0
  243. package/dist/runtime/node-repl.d.ts.map +1 -0
  244. package/dist/runtime/node-repl.js +293 -0
  245. package/dist/runtime/node-runner.d.ts +111 -0
  246. package/dist/runtime/node-runner.d.ts.map +1 -0
  247. package/dist/runtime/node-runner.js +194 -0
  248. package/dist/runtime/node-shims.d.ts +24 -0
  249. package/dist/runtime/node-shims.d.ts.map +1 -0
  250. package/dist/runtime/node-shims.js +3019 -0
  251. package/dist/runtime/package-manager.d.ts +118 -0
  252. package/dist/runtime/package-manager.d.ts.map +1 -0
  253. package/dist/runtime/package-manager.js +420 -0
  254. package/dist/runtime/port-registry.d.ts +80 -0
  255. package/dist/runtime/port-registry.d.ts.map +1 -0
  256. package/dist/runtime/port-registry.js +166 -0
  257. package/dist/runtime/process-logs-api.d.ts +102 -0
  258. package/dist/runtime/process-logs-api.d.ts.map +1 -0
  259. package/dist/runtime/process-logs-api.js +253 -0
  260. package/dist/runtime/process-logs.d.ts +311 -0
  261. package/dist/runtime/process-logs.d.ts.map +1 -0
  262. package/dist/runtime/process-logs.js +656 -0
  263. package/dist/runtime/process-table.d.ts +65 -0
  264. package/dist/runtime/process-table.d.ts.map +1 -0
  265. package/dist/runtime/process-table.js +107 -0
  266. package/dist/runtime/project-detect.d.ts +21 -0
  267. package/dist/runtime/project-detect.d.ts.map +1 -0
  268. package/dist/runtime/project-detect.js +46 -0
  269. package/dist/runtime/python-repl.d.ts +66 -0
  270. package/dist/runtime/python-repl.d.ts.map +1 -0
  271. package/dist/runtime/python-repl.js +563 -0
  272. package/dist/runtime/python-runner.d.ts +50 -0
  273. package/dist/runtime/python-runner.d.ts.map +1 -0
  274. package/dist/runtime/python-runner.js +870 -0
  275. package/dist/runtime/repl-session.d.ts +160 -0
  276. package/dist/runtime/repl-session.d.ts.map +1 -0
  277. package/dist/runtime/repl-session.js +393 -0
  278. package/dist/runtime/require-resolver.d.ts +52 -0
  279. package/dist/runtime/require-resolver.d.ts.map +1 -0
  280. package/dist/runtime/require-resolver.js +690 -0
  281. package/dist/runtime/router-basename.d.ts +36 -0
  282. package/dist/runtime/router-basename.d.ts.map +1 -0
  283. package/dist/runtime/router-basename.js +310 -0
  284. package/dist/runtime/ruby-repl.d.ts +43 -0
  285. package/dist/runtime/ruby-repl.d.ts.map +1 -0
  286. package/dist/runtime/ruby-repl.js +229 -0
  287. package/dist/runtime/ruby-runner.d.ts +62 -0
  288. package/dist/runtime/ruby-runner.d.ts.map +1 -0
  289. package/dist/runtime/ruby-runner.js +737 -0
  290. package/dist/runtime/runtime-catalog.d.ts +99 -0
  291. package/dist/runtime/runtime-catalog.d.ts.map +1 -0
  292. package/dist/runtime/runtime-catalog.js +183 -0
  293. package/dist/runtime/runtime-registry.d.ts +136 -0
  294. package/dist/runtime/runtime-registry.d.ts.map +1 -0
  295. package/dist/runtime/runtime-registry.js +318 -0
  296. package/dist/runtime/streams.d.ts +13 -0
  297. package/dist/runtime/streams.d.ts.map +1 -0
  298. package/dist/runtime/streams.js +402 -0
  299. package/dist/runtime/wasi-instance.d.ts +190 -0
  300. package/dist/runtime/wasi-instance.d.ts.map +1 -0
  301. package/dist/runtime/wasi-instance.js +2044 -0
  302. package/dist/runtime/wasm-runner.d.ts +117 -0
  303. package/dist/runtime/wasm-runner.d.ts.map +1 -0
  304. package/dist/runtime/wasm-runner.js +705 -0
  305. package/dist/session/bindings.d.ts +168 -0
  306. package/dist/session/bindings.d.ts.map +1 -0
  307. package/dist/session/bindings.js +524 -0
  308. package/dist/session/ctx-exports.d.ts +16 -0
  309. package/dist/session/ctx-exports.d.ts.map +1 -0
  310. package/dist/session/ctx-exports.js +22 -0
  311. package/dist/session/diag.d.ts +62 -0
  312. package/dist/session/diag.d.ts.map +1 -0
  313. package/dist/session/diag.js +118 -0
  314. package/dist/session/fs-watch.d.ts +132 -0
  315. package/dist/session/fs-watch.d.ts.map +1 -0
  316. package/dist/session/fs-watch.js +255 -0
  317. package/dist/session/helpers.d.ts +150 -0
  318. package/dist/session/helpers.d.ts.map +1 -0
  319. package/dist/session/helpers.js +472 -0
  320. package/dist/session/hibernation.d.ts +145 -0
  321. package/dist/session/hibernation.d.ts.map +1 -0
  322. package/dist/session/hibernation.js +385 -0
  323. package/dist/session/init-phases.d.ts +87 -0
  324. package/dist/session/init-phases.d.ts.map +1 -0
  325. package/dist/session/init-phases.js +137 -0
  326. package/dist/session/init.d.ts +46 -0
  327. package/dist/session/init.d.ts.map +1 -0
  328. package/dist/session/init.js +3579 -0
  329. package/dist/session/keys.d.ts +56 -0
  330. package/dist/session/keys.d.ts.map +1 -0
  331. package/dist/session/keys.js +55 -0
  332. package/dist/session/nimbus-session.d.ts +434 -0
  333. package/dist/session/nimbus-session.d.ts.map +1 -0
  334. package/dist/session/nimbus-session.js +1084 -0
  335. package/dist/session/programmatic.d.ts +105 -0
  336. package/dist/session/programmatic.d.ts.map +1 -0
  337. package/dist/session/programmatic.js +326 -0
  338. package/dist/session/replica-routes.d.ts +68 -0
  339. package/dist/session/replica-routes.d.ts.map +1 -0
  340. package/dist/session/replica-routes.js +77 -0
  341. package/dist/session/routes.d.ts +29 -0
  342. package/dist/session/routes.d.ts.map +1 -0
  343. package/dist/session/routes.js +1331 -0
  344. package/dist/session/rpc.d.ts +323 -0
  345. package/dist/session/rpc.d.ts.map +1 -0
  346. package/dist/session/rpc.js +808 -0
  347. package/dist/session/state-store.d.ts +210 -0
  348. package/dist/session/state-store.d.ts.map +1 -0
  349. package/dist/session/state-store.js +459 -0
  350. package/dist/session/supervisor-rpc.d.ts +269 -0
  351. package/dist/session/supervisor-rpc.d.ts.map +1 -0
  352. package/dist/session/supervisor-rpc.js +437 -0
  353. package/dist/session/ws-hibernation-config.d.ts +64 -0
  354. package/dist/session/ws-hibernation-config.d.ts.map +1 -0
  355. package/dist/session/ws-hibernation-config.js +89 -0
  356. package/dist/session/ws.d.ts +95 -0
  357. package/dist/session/ws.d.ts.map +1 -0
  358. package/dist/session/ws.js +395 -0
  359. package/dist/shell/features.d.ts +410 -0
  360. package/dist/shell/features.d.ts.map +1 -0
  361. package/dist/shell/features.js +1885 -0
  362. package/dist/shell/unix-commands.d.ts +15 -0
  363. package/dist/shell/unix-commands.d.ts.map +1 -0
  364. package/dist/shell/unix-commands.js +3703 -0
  365. package/dist/stubs/lifo-ui.d.ts +10 -0
  366. package/dist/stubs/lifo-ui.d.ts.map +1 -0
  367. package/dist/stubs/lifo-ui.js +1 -0
  368. package/dist/tailwind-play.generated.d.ts +19 -0
  369. package/dist/tailwind-play.generated.d.ts.map +1 -0
  370. package/dist/tailwind-play.generated.js +18 -0
  371. package/dist/vfs/dev-provider.d.ts +64 -0
  372. package/dist/vfs/dev-provider.d.ts.map +1 -0
  373. package/dist/vfs/dev-provider.js +191 -0
  374. package/dist/vfs/events.d.ts +51 -0
  375. package/dist/vfs/events.d.ts.map +1 -0
  376. package/dist/vfs/events.js +127 -0
  377. package/dist/vfs/path.d.ts +30 -0
  378. package/dist/vfs/path.d.ts.map +1 -0
  379. package/dist/vfs/path.js +41 -0
  380. package/dist/vfs/seed-project.d.ts +62 -0
  381. package/dist/vfs/seed-project.d.ts.map +1 -0
  382. package/dist/vfs/seed-project.js +1045 -0
  383. package/dist/vfs/sqlite-vfs.d.ts +435 -0
  384. package/dist/vfs/sqlite-vfs.d.ts.map +1 -0
  385. package/dist/vfs/sqlite-vfs.js +1670 -0
  386. package/dist/vfs/symlink-registry.d.ts +64 -0
  387. package/dist/vfs/symlink-registry.d.ts.map +1 -0
  388. package/dist/vfs/symlink-registry.js +137 -0
  389. package/dist/wrangler/nimbus-wrangler.d.ts +157 -0
  390. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -0
  391. package/dist/wrangler/nimbus-wrangler.js +931 -0
  392. package/package.json +77 -0
  393. package/public/_assets/cirrus-plugin-react.bundle.js +70740 -0
  394. package/public/_assets/esbuild-0.24.2.wasm +0 -0
  395. package/public/_assets/real-vite-bundle.js +101478 -0
  396. package/public/_assets/rollup.wasm +0 -0
  397. package/public/favicon.svg +8 -0
  398. package/public/index.html +565 -0
  399. package/public/s/index.html +2379 -0
  400. package/scripts/bundle-esbuild-wasm.mjs +244 -0
  401. package/scripts/bundle-facet-workers.mjs +137 -0
  402. package/scripts/bundle-git.mjs +118 -0
  403. package/scripts/bundle-npm-cjs.mjs +363 -0
  404. package/scripts/bundle-plugin-react.mjs +480 -0
  405. package/scripts/bundle-real-vite.mjs +959 -0
  406. package/scripts/bundle-runtime.mjs +600 -0
  407. package/scripts/bundle-tailwind-play.mjs +130 -0
  408. package/scripts/patch-lifo-ui.mjs +131 -0
@@ -0,0 +1,1033 @@
1
+ /**
2
+ * clang-runner.ts — Wave-3 v1.1: full hello-world.
3
+ *
4
+ * v1.1 architecture (compile-link-run, TWO facet calls):
5
+ *
6
+ * compile : clang.wasm + memfs.wasm + sysroot subset for C includes
7
+ * + user .c → produces .o bytes (returned to supervisor).
8
+ * link : lld.wasm + memfs.wasm + sysroot subset for link
9
+ * (crt1.o + libc.a) + .o from compile → produces .wasm
10
+ * executable.
11
+ * write : final .wasm flushed to user VFS at the requested path.
12
+ *
13
+ * Splitting compile and link into separate LOADER calls keeps each
14
+ * call under the empirical ~32 MiB per-call ceiling (verdict.md §3
15
+ * path B). Each ships:
16
+ *
17
+ * - compile: 31 MiB clang.wasm + 0.35 MiB memfs + ~1.3 MiB sysroot
18
+ * subset (C includes) = ~32.6 MiB.
19
+ * - link : 19 MiB lld.wasm + 0.35 MiB memfs + ~0.75 MiB libs +
20
+ * tiny .o = ~20 MiB.
21
+ *
22
+ * Sysroot subset extraction happens supervisor-side via a small ustar
23
+ * parser. The full 9.3 MiB sysroot.tar is parsed once per compile;
24
+ * only the files matching the role's prefix-allowlist are forwarded.
25
+ *
26
+ * Anti-reqs from plan §8.1: no setTimeout / no retry / no
27
+ * defensive-catch in dispatch.
28
+ */
29
+ /** Build the runner factory. Closes over facetMgr + vfs. */
30
+ export function makeClangRunnerFactory(deps) {
31
+ const { facetMgr, vfs } = deps;
32
+ return function clangRunnerFactory(manifest, installRoot, binName, binKind) {
33
+ const findFile = (rel) => {
34
+ const entry = manifest.files.find((f) => f.path === rel);
35
+ return entry ? `${installRoot}/${entry.path}` : null;
36
+ };
37
+ const clangVfsPath = findFile('bin/clang');
38
+ const lldVfsPath = findFile('bin/wasm-ld');
39
+ const memfsVfsPath = findFile('share/clang/memfs.wasm');
40
+ const sysrootVfsPath = findFile('share/clang/sysroot.tar');
41
+ return async function clangBinHandler(ctx) {
42
+ const argv = ctx.args || [];
43
+ const cwd = ctx.cwd || '/home/user';
44
+ // Fast paths — no wasm boot.
45
+ if (argv.includes('--version') || argv.includes('-v')) {
46
+ ctx.stdout.write(`Nimbus wasm-clang (binji-2020, LLVM 8.0.1)\n`);
47
+ ctx.stdout.write(`Target: wasm32-wasi (via wasm-ld linker)\n`);
48
+ return 0;
49
+ }
50
+ if (argv.includes('--help') || argv.includes('-h')) {
51
+ ctx.stdout.write(`usage: ${binName} [options] <source.c> -o <output>\n`);
52
+ ctx.stdout.write(`Wasm-compiled clang/wasm-ld bundle for Nimbus.\n`);
53
+ ctx.stdout.write(`Supported: C compilation + linking to wasm.\n`);
54
+ return 0;
55
+ }
56
+ const isLinker = binKind === 'linker' || binName === 'wasm-ld';
57
+ // Resolve bundle paths.
58
+ if (!memfsVfsPath || !vfs.exists(memfsVfsPath)) {
59
+ ctx.stderr.write(`${binName}: memfs.wasm missing from install (re-run 'nimbus install clang')\n`);
60
+ return 127;
61
+ }
62
+ if (!sysrootVfsPath || !vfs.exists(sysrootVfsPath)) {
63
+ ctx.stderr.write(`${binName}: sysroot.tar missing from install\n`);
64
+ return 127;
65
+ }
66
+ if (!clangVfsPath || !lldVfsPath) {
67
+ ctx.stderr.write(`${binName}: clang/wasm-ld missing from install\n`);
68
+ return 127;
69
+ }
70
+ const memfsBytes = vfs.readFile(memfsVfsPath);
71
+ const sysrootBytes = vfs.readFile(sysrootVfsPath);
72
+ // Parse argv: find input .c + output path.
73
+ const parsed = parseUserArgv(argv);
74
+ if (parsed.error) {
75
+ ctx.stderr.write(`${binName}: ${parsed.error}\n`);
76
+ return parsed.exitCode;
77
+ }
78
+ if (isLinker) {
79
+ // Direct wasm-ld invocation: pass argv through (advanced
80
+ // users only). Not on the hello-world path.
81
+ ctx.stderr.write(`${binName}: direct wasm-ld invocation not yet wired (v1.2)\n`);
82
+ return 2;
83
+ }
84
+ // Parse sysroot.tar ONCE on supervisor side.
85
+ const sysroot = parseUstar(sysrootBytes);
86
+ // Validate all user-supplied source inputs exist in the user's
87
+ // session VFS. Collect their bytes for memfs population.
88
+ const userSourceFiles = {};
89
+ // Pre-built objects/archives the user passed (e.g. extra.o, libfoo.a)
90
+ // — shipped to the LINK step only (not compile).
91
+ const preBuiltLinkInputs = [];
92
+ const sourceInputs = [];
93
+ for (const input of parsed.inputPaths) {
94
+ const inputAbs = resolveVfsPath(input, cwd);
95
+ if (!vfs.exists(inputAbs)) {
96
+ ctx.stderr.write(`${binName}: ${input}: No such file or directory\n`);
97
+ return 1;
98
+ }
99
+ const inputBytes = vfs.readFile(inputAbs);
100
+ userSourceFiles[input] = inputBytes;
101
+ if (isSourceExt(input)) {
102
+ sourceInputs.push(input);
103
+ }
104
+ else {
105
+ // .o / .a — pass through to link as a pre-built input. The
106
+ // path inside memfs is the user-supplied relative path.
107
+ preBuiltLinkInputs.push(input);
108
+ }
109
+ }
110
+ if (sourceInputs.length === 0 && preBuiltLinkInputs.length === 0) {
111
+ ctx.stderr.write(`${binName}: no compilable / linkable inputs\n`);
112
+ return 1;
113
+ }
114
+ // Walk the user's cwd to gather headers (.h/.hpp/.hxx/.inc/...)
115
+ // and any sibling headers users typically expect to be visible
116
+ // to #include "..." resolution. Real clang/gcc auto-search the
117
+ // dir of the including source for quote-form includes; we ship
118
+ // those files to memfs at their relative-to-cwd paths so the
119
+ // memfs layout reproduces the user's working tree.
120
+ //
121
+ // Size-capped (4 MiB, 200 files, depth 8) so accidental
122
+ // huge-projects don't OOM the facet. Real C-tutorial projects
123
+ // are vastly under the cap.
124
+ const userIncludeBundle = collectIncludeBundle(vfs, cwd.replace(/^\/+/, ''));
125
+ // ── COMPILE PHASE ────────────────────────────────────────────
126
+ // Ship: clang.wasm + memfs.wasm + C-include subset of sysroot
127
+ // + user's source files + user's header bundle.
128
+ const compileSysroot = filterSysrootForCompile(sysroot);
129
+ const clangBytes = vfs.readFile(clangVfsPath);
130
+ // Build -I flag list. We pass each user -I path verbatim AND add
131
+ // an implicit '.' (cwd) for quote-form lookup. wasm-clang's -cc1
132
+ // mode does NOT add cwd to the quote search list by default
133
+ // (the driver normally does that for "foo.h" includes), so we
134
+ // wire it ourselves. This is what makes
135
+ // clang main.c (main.c does #include "greet.h", greet.h
136
+ // next to main.c)
137
+ // succeed without an explicit -I from the user.
138
+ const userIncludeFlags = [];
139
+ for (const ip of parsed.includePaths) {
140
+ userIncludeFlags.push('-I', ip);
141
+ }
142
+ userIncludeFlags.push('-I', '.');
143
+ // Compile each source to its own .o. Object file naming: replace
144
+ // the source extension with .o. Collisions across cwd subdirs
145
+ // (e.g. src/foo.c and lib/foo.c both → foo.o) are avoided by
146
+ // keeping the directory component (memfs preserves user layout).
147
+ const objPaths = [];
148
+ const objBytesMap = {};
149
+ for (const src of sourceInputs) {
150
+ const objPath = src.replace(/\.(c|cc|cpp|cxx|c\+\+|C)$/, '.o');
151
+ // For C++ inputs use -x c++; default -x c.
152
+ const isCpp = /\.(cc|cpp|cxx|c\+\+|C)$/.test(src);
153
+ const compileArgv = [
154
+ 'clang', '-cc1', '-emit-obj',
155
+ '-disable-free',
156
+ '-isysroot', '/',
157
+ '-internal-isystem', '/include/c++/v1',
158
+ '-internal-isystem', '/include',
159
+ '-internal-isystem', '/lib/clang/8.0.1/include',
160
+ '-ferror-limit', '19',
161
+ '-fmessage-length', '80',
162
+ '-fcolor-diagnostics',
163
+ '-O2',
164
+ ...userIncludeFlags,
165
+ '-o', objPath,
166
+ '-x', isCpp ? 'c++' : 'c',
167
+ src,
168
+ ];
169
+ // Per compile we ship: the current source file + the user's
170
+ // header bundle. Multi-TU is handled at link time, not compile,
171
+ // so sibling sources stay out of memfs (smaller payload, no
172
+ // surface for unintended cross-TU textual inclusion via -I.).
173
+ const oneSourceFile = { [src]: userSourceFiles[src] };
174
+ const compileResult = await dispatchClangFacet(facetMgr, {
175
+ primaryName: 'clang',
176
+ primaryBytes: clangBytes,
177
+ memfsBytes,
178
+ sysrootFiles: {
179
+ ...compileSysroot,
180
+ ...oneSourceFile,
181
+ // User's headers from cwd tree (so quote-form #include
182
+ // resolves; this is the primary clang-include-fix payload).
183
+ ...userIncludeBundle,
184
+ },
185
+ argv: compileArgv,
186
+ outputPaths: [objPath],
187
+ });
188
+ if (compileResult.stdout)
189
+ ctx.stdout.write(compileResult.stdout);
190
+ if (compileResult.stderr)
191
+ ctx.stderr.write(compileResult.stderr);
192
+ if (compileResult.error) {
193
+ ctx.stderr.write(`${binName}: ${compileResult.error}\n`);
194
+ return 1;
195
+ }
196
+ if (compileResult.exitCode !== 0) {
197
+ return compileResult.exitCode;
198
+ }
199
+ const objBytes = compileResult.outputFiles[objPath];
200
+ if (!objBytes || objBytes.length === 0) {
201
+ ctx.stderr.write(`${binName}: compile produced no ${objPath} (internal error)\n`);
202
+ return 1;
203
+ }
204
+ objPaths.push(objPath);
205
+ objBytesMap[objPath] = objBytes;
206
+ }
207
+ // -c (compile-only): flush each .o to the user VFS, no link.
208
+ if (parsed.compileOnly) {
209
+ for (const objPath of objPaths) {
210
+ const objVfsPath = resolveVfsPath(objPath, cwd);
211
+ const parent = objVfsPath.replace(/\/[^/]+$/, '');
212
+ if (parent && parent !== objVfsPath && !vfs.exists(parent)) {
213
+ vfs.mkdir(parent, { recursive: true });
214
+ }
215
+ vfs.writeFile(objVfsPath, objBytesMap[objPath]);
216
+ }
217
+ // Honor user's -o for single-input compile-only: rename the one
218
+ // .o to the requested output if -o was passed.
219
+ if (sourceInputs.length === 1 && parsed.outputPath !== 'a.out') {
220
+ const fromVfs = resolveVfsPath(objPaths[0], cwd);
221
+ const toVfs = resolveVfsPath(parsed.outputPath, cwd);
222
+ if (fromVfs !== toVfs) {
223
+ try {
224
+ vfs.writeFile(toVfs, vfs.readFile(fromVfs));
225
+ vfs.unlink(fromVfs);
226
+ }
227
+ catch { /* best-effort */ }
228
+ }
229
+ }
230
+ return 0;
231
+ }
232
+ // Add pre-built .o / .a inputs (the user passed them on argv
233
+ // alongside .c sources, e.g. `clang main.c extra.o -o out`).
234
+ const preBuiltBytesMap = {};
235
+ for (const lp of preBuiltLinkInputs) {
236
+ preBuiltBytesMap[lp] = userSourceFiles[lp];
237
+ }
238
+ // ── LINK PHASE ───────────────────────────────────────────────
239
+ // Ship: lld.wasm + memfs.wasm + lib subset of sysroot + .o's.
240
+ const linkSysroot = filterSysrootForLink(sysroot);
241
+ const lldBytes = vfs.readFile(lldVfsPath);
242
+ const stackSize = 1024 * 1024;
243
+ // User-supplied -L paths and -l libraries flow through. The user
244
+ // -L paths point at user-VFS dirs; we currently don't ship user
245
+ // libraries (they'd need their own collect step), so -l<name>
246
+ // works only against the sysroot's -L paths today. -L user-side
247
+ // would no-op silently in v1 — out of scope for this wave.
248
+ const userLinkFlags = [];
249
+ for (const lp of parsed.libraryPaths) {
250
+ userLinkFlags.push('-L', lp);
251
+ }
252
+ const linkArgv = [
253
+ 'wasm-ld',
254
+ '--no-threads',
255
+ '--export-dynamic',
256
+ '-z', `stack-size=${stackSize}`,
257
+ '-L/lib/wasm32-wasi',
258
+ // Stream-C: modern wasi-libc references __muloti4 / __divti3
259
+ // (128-bit math from utimensat's timespec arithmetic) — these
260
+ // live in compiler-rt's libclang_rt.builtins-wasm32.a at the
261
+ // clang resource dir. binji-2020's libc.a self-bundled them;
262
+ // modern doesn't, so we link compiler-rt explicitly. wasm-ld
263
+ // dead-strips unused builtins, so binji binaries are unaffected.
264
+ '-L/lib/clang/8.0.1/lib/wasi',
265
+ ...userLinkFlags,
266
+ '/lib/wasm32-wasi/crt1.o',
267
+ ...objPaths,
268
+ ...preBuiltLinkInputs,
269
+ '-lc',
270
+ ...parsed.libraries.map((l) => '-l' + l),
271
+ '-lclang_rt.builtins-wasm32',
272
+ '-o', parsed.outputPath,
273
+ ];
274
+ const linkResult = await dispatchClangFacet(facetMgr, {
275
+ primaryName: 'wasm-ld',
276
+ primaryBytes: lldBytes,
277
+ memfsBytes,
278
+ sysrootFiles: { ...linkSysroot, ...objBytesMap, ...preBuiltBytesMap },
279
+ argv: linkArgv,
280
+ outputPaths: [parsed.outputPath],
281
+ });
282
+ if (linkResult.stdout)
283
+ ctx.stdout.write(linkResult.stdout);
284
+ if (linkResult.stderr)
285
+ ctx.stderr.write(linkResult.stderr);
286
+ if (linkResult.error) {
287
+ ctx.stderr.write(`${binName}: ${linkResult.error}\n`);
288
+ return 1;
289
+ }
290
+ if (linkResult.exitCode !== 0) {
291
+ return linkResult.exitCode;
292
+ }
293
+ const wasmBytes = linkResult.outputFiles[parsed.outputPath];
294
+ if (!wasmBytes || wasmBytes.length === 0) {
295
+ ctx.stderr.write(`${binName}: link produced no ${parsed.outputPath} (internal error)\n`);
296
+ return 1;
297
+ }
298
+ // ── FLUSH OUTPUT ─────────────────────────────────────────────
299
+ const outVfsPath = resolveVfsPath(parsed.outputPath, cwd);
300
+ const parent = outVfsPath.replace(/\/[^/]+$/, '');
301
+ if (parent && parent !== outVfsPath && !vfs.exists(parent)) {
302
+ vfs.mkdir(parent, { recursive: true });
303
+ }
304
+ vfs.writeFile(outVfsPath, wasmBytes);
305
+ return 0;
306
+ };
307
+ };
308
+ }
309
+ /** Recognized C / C++ source extensions for input classification. */
310
+ function isSourceExt(p) {
311
+ return /\.(c|cc|cpp|cxx|c\+\+|C)$/.test(p);
312
+ }
313
+ function parseUserArgv(argv) {
314
+ const inputPaths = [];
315
+ const includePaths = [];
316
+ const libraryPaths = [];
317
+ const libraries = [];
318
+ let outputPath = 'a.out';
319
+ let compileOnly = false;
320
+ // Flags that take a separate argv slot for their value.
321
+ const takesArg = new Set(['-o', '-x', '-isystem', '-include', '-isysroot',
322
+ '-target', '--target', '-std', '-MF', '-MT', '-MQ']);
323
+ for (let i = 0; i < argv.length; i++) {
324
+ const a = argv[i];
325
+ if (a === '-o' && i + 1 < argv.length) {
326
+ outputPath = argv[i + 1];
327
+ i++;
328
+ continue;
329
+ }
330
+ if (a === '-c') {
331
+ compileOnly = true;
332
+ continue;
333
+ }
334
+ // -I<path> or -I <path>
335
+ if (a === '-I' && i + 1 < argv.length) {
336
+ includePaths.push(argv[i + 1]);
337
+ i++;
338
+ continue;
339
+ }
340
+ if (a.startsWith('-I')) {
341
+ includePaths.push(a.substring(2));
342
+ continue;
343
+ }
344
+ // -L<path> or -L <path>
345
+ if (a === '-L' && i + 1 < argv.length) {
346
+ libraryPaths.push(argv[i + 1]);
347
+ i++;
348
+ continue;
349
+ }
350
+ if (a.startsWith('-L')) {
351
+ libraryPaths.push(a.substring(2));
352
+ continue;
353
+ }
354
+ // -l<name> or -l <name>
355
+ if (a === '-l' && i + 1 < argv.length) {
356
+ libraries.push(argv[i + 1]);
357
+ i++;
358
+ continue;
359
+ }
360
+ if (a.startsWith('-l')) {
361
+ libraries.push(a.substring(2));
362
+ continue;
363
+ }
364
+ // Skip recognised takes-arg flags we don't yet interpret.
365
+ if (takesArg.has(a) && i + 1 < argv.length) {
366
+ i++;
367
+ continue;
368
+ }
369
+ // Any other -flag is opaque to the parser; the user passes them
370
+ // through (we don't currently relay arbitrary flags to clang-cc1,
371
+ // see compileArgv construction).
372
+ if (a.startsWith('-'))
373
+ continue;
374
+ // Positional. If it looks like a source file, take it; else ignore.
375
+ if (isSourceExt(a)) {
376
+ inputPaths.push(a);
377
+ }
378
+ else if (a.endsWith('.o') || a.endsWith('.a')) {
379
+ // Pre-built objects/archives — treat as link-only inputs. We
380
+ // surface them as inputs so the link step picks them up; the
381
+ // compile step skips them (it only walks .c/.cc/.cpp).
382
+ inputPaths.push(a);
383
+ }
384
+ // else: drop silently (e.g. typos). clang would warn; we don't yet.
385
+ }
386
+ if (inputPaths.length === 0) {
387
+ return {
388
+ inputPaths: [], inputPath: '', includePaths, libraryPaths, libraries,
389
+ outputPath: '', compileOnly, exitCode: 2, error: 'no input files',
390
+ };
391
+ }
392
+ return {
393
+ inputPaths, inputPath: inputPaths[0], includePaths, libraryPaths, libraries,
394
+ outputPath, compileOnly, exitCode: 0,
395
+ };
396
+ }
397
+ function resolveVfsPath(rel, cwd) {
398
+ const cwdN = cwd.replace(/^\/+/, '').replace(/\/+$/, '');
399
+ if (rel.startsWith('/'))
400
+ return rel.replace(/^\/+/, '');
401
+ if (rel === '.')
402
+ return cwdN;
403
+ return `${cwdN}/${rel}`;
404
+ }
405
+ /**
406
+ * Recognise headers / inline-include files. The compile facet ships
407
+ * these alongside the .c sources so `#include "foo.h"` (quote-form)
408
+ * resolves against the directory of the including source file — which
409
+ * is how clang / gcc behave on real Unix.
410
+ */
411
+ function isHeaderExt(name) {
412
+ return /\.(h|hh|hpp|hxx|H|inc|ipp|tcc)$/.test(name);
413
+ }
414
+ /**
415
+ * Walk a VFS directory recursively to collect headers + (optionally)
416
+ * source files, with bounded depth and total size cap, returning a
417
+ * map of memfs-relative-path → bytes.
418
+ *
419
+ * Layout convention: paths returned are RELATIVE TO `rootVfsPath`, so
420
+ * a header at `home/user/sub/foo.h` (when rootVfsPath is `home/user`)
421
+ * comes out as `sub/foo.h`. This matches the layout the user passes
422
+ * on argv (e.g. `clang sub/lib.c -o out`, with `lib.c` including
423
+ * `"helpers.h"` next to itself).
424
+ *
425
+ * `extra` extensions can be added (used to include `.c/.cpp/.o/.a` when
426
+ * looking under -L / sibling source dirs). Empty by default.
427
+ *
428
+ * Anti-DoS:
429
+ * - MAX_FILES = 200 (covers realistic user projects without ballooning
430
+ * the facet payload).
431
+ * - MAX_BYTES = 4 MiB.
432
+ * - MAX_DEPTH = 8 (deep enough for typical "src/", "include/", "lib/" trees).
433
+ * - skipDirs prunes obvious non-source directories.
434
+ */
435
+ function collectIncludeBundle(vfs, rootVfsPath, opts = {}) {
436
+ const extraExts = opts.extraExts ?? null;
437
+ const MAX_FILES = opts.maxFiles ?? 200;
438
+ const MAX_BYTES = opts.maxBytes ?? 4 * 1024 * 1024;
439
+ const MAX_DEPTH = opts.maxDepth ?? 8;
440
+ const out = {};
441
+ if (!vfs.exists(rootVfsPath) || !vfs.isDirectory(rootVfsPath))
442
+ return out;
443
+ // Directories pruned regardless of depth — these never contain user
444
+ // headers and would balloon the payload if traversed.
445
+ const skipDirs = new Set([
446
+ '.nimbus', 'node_modules', '.cache', '.npm', '.git',
447
+ 'dist', 'build', '.next', '.nuxt', '.svelte-kit', 'coverage',
448
+ ]);
449
+ const root = rootVfsPath.replace(/^\/+/, '').replace(/\/+$/, '');
450
+ let totalBytes = 0;
451
+ let fileCount = 0;
452
+ const stack = [{ dir: root, depth: 0 }];
453
+ while (stack.length > 0) {
454
+ const { dir, depth } = stack.pop();
455
+ if (depth > MAX_DEPTH)
456
+ continue;
457
+ let entries;
458
+ try {
459
+ entries = vfs.readdir(dir);
460
+ }
461
+ catch {
462
+ continue;
463
+ }
464
+ for (const e of entries) {
465
+ const childAbs = dir + '/' + e.name;
466
+ const rel = childAbs.startsWith(root + '/') ? childAbs.substring(root.length + 1) : childAbs;
467
+ if (e.type === 'directory') {
468
+ if (skipDirs.has(e.name))
469
+ continue;
470
+ stack.push({ dir: childAbs, depth: depth + 1 });
471
+ continue;
472
+ }
473
+ const isHeader = isHeaderExt(e.name);
474
+ const isExtra = extraExts && extraExts.test(e.name);
475
+ if (!isHeader && !isExtra)
476
+ continue;
477
+ let bytes;
478
+ try {
479
+ bytes = vfs.readFile(childAbs);
480
+ }
481
+ catch {
482
+ continue;
483
+ }
484
+ totalBytes += bytes.length;
485
+ fileCount++;
486
+ if (totalBytes > MAX_BYTES || fileCount > MAX_FILES) {
487
+ // Cap reached — stop walking but return what we have.
488
+ return out;
489
+ }
490
+ out[rel] = bytes;
491
+ }
492
+ }
493
+ return out;
494
+ }
495
+ // ── ustar parser (supervisor-side) ───────────────────────────────────
496
+ /**
497
+ * Parse a POSIX ustar archive into a path→bytes map. Trims the
498
+ * leading "/" from paths so memfs sees them as "include/stdio.h"
499
+ * (not "/include/stdio.h"). Directories are NOT recorded — only
500
+ * regular file entries.
501
+ */
502
+ function parseUstar(tarBytes) {
503
+ const files = new Map();
504
+ let off = 0;
505
+ while (off + 512 <= tarBytes.length) {
506
+ let nameEnd = off;
507
+ while (nameEnd < off + 100 && tarBytes[nameEnd] !== 0)
508
+ nameEnd++;
509
+ let name = '';
510
+ for (let i = off; i < nameEnd; i++)
511
+ name += String.fromCharCode(tarBytes[i]);
512
+ if (!name)
513
+ break;
514
+ const typeflag = tarBytes[off + 156];
515
+ let sizeStr = '';
516
+ for (let i = off + 124; i < off + 124 + 11; i++) {
517
+ const c = tarBytes[i];
518
+ if (c >= 0x30 && c <= 0x37)
519
+ sizeStr += String.fromCharCode(c);
520
+ }
521
+ const size = parseInt(sizeStr || '0', 8);
522
+ let prefixEnd = off + 345;
523
+ while (prefixEnd < off + 345 + 155 && tarBytes[prefixEnd] !== 0)
524
+ prefixEnd++;
525
+ let prefix = '';
526
+ for (let i = off + 345; i < prefixEnd; i++)
527
+ prefix += String.fromCharCode(tarBytes[i]);
528
+ const fullName = prefix ? `${prefix}/${name}` : name;
529
+ off += 512;
530
+ const isRegular = typeflag === 0 || typeflag === 0x30; // '0'
531
+ const isDir = typeflag === 0x35 || fullName.endsWith('/'); // '5'
532
+ if (isRegular && !isDir) {
533
+ const bytes = tarBytes.slice(off, off + size);
534
+ files.set(fullName.replace(/\/$/, ''), bytes);
535
+ }
536
+ off += Math.ceil(size / 512) * 512;
537
+ }
538
+ return files;
539
+ }
540
+ /**
541
+ * Filter the sysroot to just what the compile step needs:
542
+ * - include/ (minus include/c++/) — C system headers
543
+ * - lib/clang/8.0.1/include/ — clang intrinsic headers
544
+ *
545
+ * Excludes the C++ standard library headers (libc++/v1) which alone
546
+ * are ~4 MiB and aren't needed for plain C compilation.
547
+ */
548
+ function filterSysrootForCompile(all) {
549
+ const out = {};
550
+ for (const [path, bytes] of all.entries()) {
551
+ if (path.startsWith('include/c++/'))
552
+ continue;
553
+ if (path.startsWith('include/')) {
554
+ out[path] = bytes;
555
+ continue;
556
+ }
557
+ if (path.startsWith('lib/clang/')) {
558
+ out[path] = bytes;
559
+ continue;
560
+ }
561
+ }
562
+ return out;
563
+ }
564
+ /**
565
+ * Filter the sysroot to just what the link step needs for a C program:
566
+ * - lib/wasm32-wasi/crt1.o — the entry-point start file
567
+ * - lib/wasm32-wasi/libc.a — libc archive (printf etc.)
568
+ * - lib/wasm32-wasi/libc.imports — WASI symbol allow-list. Without
569
+ * this, wasm-ld treats `__wasi_fd_close` etc. as undefined
570
+ * symbols (the symbols are SUPPOSED to be unresolved imports,
571
+ * not errors); the .imports file tells lld "these names are
572
+ * external WASI imports, not link errors."
573
+ * - lib/clang/8.0.1/lib/wasi/libclang_rt.builtins-wasm32.a — compiler-rt
574
+ * builtins (e.g. __muloti4 for 128-bit math). Modern wasi-libc's
575
+ * utimensat.o references __muloti4; binji-2020 self-bundled it
576
+ * into libc.a, the modern build expects compiler-rt to provide.
577
+ * wasm-ld dead-strips, so trivial mains pay zero cost.
578
+ *
579
+ * Excludes libc++/libc++abi (C++-only) and the WASI emulated-mman /
580
+ * pthread / canvas variants we don't drive in v1.1.
581
+ */
582
+ function filterSysrootForLink(all) {
583
+ const out = {};
584
+ for (const [path, bytes] of all.entries()) {
585
+ if (path === 'lib/wasm32-wasi/crt1.o') {
586
+ out[path] = bytes;
587
+ continue;
588
+ }
589
+ if (path === 'lib/wasm32-wasi/libc.a') {
590
+ out[path] = bytes;
591
+ continue;
592
+ }
593
+ if (path === 'lib/wasm32-wasi/libc.imports') {
594
+ out[path] = bytes;
595
+ continue;
596
+ }
597
+ if (path === 'lib/clang/8.0.1/lib/wasi/libclang_rt.builtins-wasm32.a') {
598
+ out[path] = bytes;
599
+ continue;
600
+ }
601
+ }
602
+ return out;
603
+ }
604
+ async function dispatchClangFacet(facetMgr, args) {
605
+ const toAB = (u8) => u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength);
606
+ // Encode sysroot files as base64 for context ferrying. We do this on
607
+ // the supervisor to keep the facet preamble small and CPU-light.
608
+ const filesB64 = {};
609
+ for (const [path, bytes] of Object.entries(args.sysrootFiles)) {
610
+ filesB64[path] = uint8ToBase64(bytes);
611
+ }
612
+ const { NimbusLoaderPool } = await import('../loaders/loader-pool.js');
613
+ const env = facetMgr.env;
614
+ const ctx = facetMgr.ctx;
615
+ const pool = new NimbusLoaderPool(env, ctx, {
616
+ tag: `clang-runner-${args.primaryName}`,
617
+ concurrency: 1,
618
+ omitSupervisor: true,
619
+ preamble: CLANG_RUNNER_PREAMBLE,
620
+ });
621
+ const facetFn = async function clangFacetCall(inArgs) {
622
+ const wasmTable = globalThis.__NIMBUS_WASM || {};
623
+ const memfsMod = wasmTable['memfs.wasm'];
624
+ const primaryMod = wasmTable['primary.wasm'];
625
+ if (!memfsMod || !primaryMod) {
626
+ return {
627
+ exitCode: 127, stdout: '', stderr: '',
628
+ outputFiles: {},
629
+ error: 'clang-runner: __NIMBUS_WASM missing memfs.wasm or primary.wasm',
630
+ };
631
+ }
632
+ const fn = globalThis.__clangRun;
633
+ if (typeof fn !== 'function') {
634
+ return {
635
+ exitCode: 127, stdout: '', stderr: '',
636
+ outputFiles: {},
637
+ error: 'clang-runner preamble missing: __clangRun not in scope',
638
+ };
639
+ }
640
+ return await fn({
641
+ primaryName: inArgs.primaryName,
642
+ argv: inArgs.argv,
643
+ filesB64: inArgs.filesB64,
644
+ outputPaths: inArgs.outputPaths,
645
+ memfsMod,
646
+ primaryMod,
647
+ });
648
+ };
649
+ try {
650
+ const result = await pool.submit(facetFn, {
651
+ primaryName: args.primaryName,
652
+ argv: args.argv,
653
+ filesB64,
654
+ outputPaths: args.outputPaths,
655
+ }, {
656
+ wasmModules: {
657
+ 'memfs.wasm': toAB(args.memfsBytes),
658
+ 'primary.wasm': toAB(args.primaryBytes),
659
+ },
660
+ timeoutMs: 300_000,
661
+ });
662
+ // Decode outputFiles from base64 → Uint8Array.
663
+ const outputFiles = {};
664
+ if (result.outputFiles) {
665
+ for (const [path, b64] of Object.entries(result.outputFiles)) {
666
+ const bin = atob(b64);
667
+ const u8 = new Uint8Array(bin.length);
668
+ for (let i = 0; i < bin.length; i++)
669
+ u8[i] = bin.charCodeAt(i);
670
+ outputFiles[path] = u8;
671
+ }
672
+ }
673
+ return {
674
+ exitCode: result.exitCode,
675
+ stdout: result.stdout || '',
676
+ stderr: result.stderr || '',
677
+ outputFiles,
678
+ error: result.error,
679
+ };
680
+ }
681
+ catch (e) {
682
+ return {
683
+ exitCode: 1,
684
+ stdout: '',
685
+ stderr: '',
686
+ outputFiles: {},
687
+ error: `clang-runner dispatch failed: ${e?.message || e}`,
688
+ };
689
+ }
690
+ }
691
+ function uint8ToBase64(u8) {
692
+ // Chunked to avoid String.fromCharCode call-stack limits on big arrays.
693
+ const CHUNK = 0x8000;
694
+ let s = '';
695
+ for (let i = 0; i < u8.length; i += CHUNK) {
696
+ s += String.fromCharCode.apply(null, Array.from(u8.subarray(i, Math.min(i + CHUNK, u8.length))));
697
+ }
698
+ return btoa(s);
699
+ }
700
+ // ── Facet preamble ───────────────────────────────────────────────────
701
+ export const CLANG_RUNNER_PREAMBLE = `
702
+ // ── BEGIN: clang-runner preamble (binji/wasm-clang port, v1.1) ─────
703
+
704
+ const __ESUCCESS = 0;
705
+ const __EBADF = 8;
706
+ const __EINVAL = 28;
707
+ const __ENOSYS = 52;
708
+
709
+ class __ProcExit {
710
+ constructor(code) { this.code = code | 0; this.message = 'process exited ' + code; this.name = 'ProcExit'; }
711
+ }
712
+
713
+ function __readStr(u8, o, len) {
714
+ if (typeof len !== 'number' || len < 0) len = -1;
715
+ let str = '';
716
+ let end = u8.length;
717
+ if (len !== -1) end = o + len;
718
+ for (let i = o; i < end && u8[i] !== 0; i++) str += String.fromCharCode(u8[i]);
719
+ return str;
720
+ }
721
+
722
+ function __writeStr(u8, off, s) {
723
+ for (let i = 0; i < s.length; i++) u8[off + i] = s.charCodeAt(i) & 0xff;
724
+ u8[off + s.length] = 0;
725
+ return s.length + 1;
726
+ }
727
+
728
+ class __HostMem {
729
+ constructor(memory) { this.memory = memory; }
730
+ get buffer() { return this.memory.buffer; }
731
+ check() { /* no-op */ }
732
+ read32(off) { return new DataView(this.memory.buffer).getUint32(off, true); }
733
+ write32(off, v) { new DataView(this.memory.buffer).setUint32(off, v >>> 0, true); }
734
+ write64(off, v) {
735
+ const dv = new DataView(this.memory.buffer);
736
+ if (typeof v === 'bigint') {
737
+ dv.setBigUint64(off, v, true);
738
+ } else {
739
+ dv.setUint32(off, (v >>> 0), true);
740
+ dv.setUint32(off + 4, Math.floor(v / 0x100000000) >>> 0, true);
741
+ }
742
+ }
743
+ readStr(off, len) { return __readStr(new Uint8Array(this.memory.buffer), off, len); }
744
+ writeStr(off, s) { return __writeStr(new Uint8Array(this.memory.buffer), off, s); }
745
+ write(off, bytes) {
746
+ const u8 = new Uint8Array(this.memory.buffer);
747
+ if (typeof bytes === 'string') {
748
+ for (let i = 0; i < bytes.length; i++) u8[off + i] = bytes.charCodeAt(i) & 0xff;
749
+ } else {
750
+ u8.set(bytes, off);
751
+ }
752
+ }
753
+ }
754
+
755
+ /**
756
+ * Add a single file to memfs at the given path. Recursively creates
757
+ * parent directories — binji's memfs only auto-creates direct parents
758
+ * when AddFileNode is called, so we walk path segments first.
759
+ */
760
+ function __memfsAddFile(memfsExports, memfsMem, path, bytes) {
761
+ // Strip a leading slash if present; memfs stores rootless paths.
762
+ const p = path.replace(/^\\/+/, '');
763
+ // Create parent dirs.
764
+ const parts = p.split('/');
765
+ for (let i = 1; i < parts.length; i++) {
766
+ const dir = parts.slice(0, i).join('/');
767
+ if (!dir) continue;
768
+ const pBuf = memfsExports.GetPathBuf();
769
+ const m = new Uint8Array(memfsMem.buffer);
770
+ for (let j = 0; j < dir.length; j++) m[pBuf + j] = dir.charCodeAt(j) & 0xff;
771
+ // Try to add — memfs ignores duplicate adds.
772
+ try { memfsExports.AddDirectoryNode(dir.length); } catch { /* may already exist */ }
773
+ }
774
+ // Now the file itself.
775
+ const pBuf = memfsExports.GetPathBuf();
776
+ const m1 = new Uint8Array(memfsMem.buffer);
777
+ for (let i = 0; i < p.length; i++) m1[pBuf + i] = p.charCodeAt(i) & 0xff;
778
+ const inode = memfsExports.AddFileNode(p.length, bytes.length);
779
+ const addr = memfsExports.GetFileNodeAddress(inode);
780
+ if (bytes.length > 0) {
781
+ new Uint8Array(memfsMem.buffer).set(bytes, addr);
782
+ }
783
+ }
784
+
785
+ /**
786
+ * Decode base64 → Uint8Array (chunked-safe).
787
+ */
788
+ function __b64decode(b64) {
789
+ const bin = atob(b64);
790
+ const u8 = new Uint8Array(bin.length);
791
+ for (let i = 0; i < bin.length; i++) u8[i] = bin.charCodeAt(i);
792
+ return u8;
793
+ }
794
+
795
+ /**
796
+ * Encode Uint8Array → base64 (chunked-safe).
797
+ */
798
+ function __b64encode(u8) {
799
+ const CHUNK = 0x8000;
800
+ let s = '';
801
+ for (let i = 0; i < u8.length; i += CHUNK) {
802
+ let chunk = '';
803
+ const end = Math.min(i + CHUNK, u8.length);
804
+ for (let j = i; j < end; j++) chunk += String.fromCharCode(u8[j]);
805
+ s += chunk;
806
+ }
807
+ return btoa(s);
808
+ }
809
+
810
+ globalThis.__clangRun = async function __clangRun(args) {
811
+ const stdoutChunks = [];
812
+ const stderrChunks = [];
813
+ const hostWrite = (s) => { stdoutChunks.push(s); };
814
+ const hostWriteErr = (s) => { stderrChunks.push(s); };
815
+
816
+ // 1. Instantiate memfs.wasm with the binji-shaped env imports.
817
+ let memfsInst;
818
+ let memfsMem;
819
+ const memfsHandle = { mem: null, hostMem: null, stdinStr: '', stdinPos: 0 };
820
+ const memfsImports = {
821
+ env: {
822
+ abort: () => { throw new Error('memfs: abort'); },
823
+ host_write: (fd, iovs, iovs_len, nwritten_out) => {
824
+ const hm = memfsHandle.hostMem;
825
+ if (!hm) return __EBADF;
826
+ let size = 0;
827
+ let str = '';
828
+ for (let i = 0; i < iovs_len; i++) {
829
+ const buf = hm.read32(iovs); iovs += 4;
830
+ const len = hm.read32(iovs); iovs += 4;
831
+ str += hm.readStr(buf, len);
832
+ size += len;
833
+ }
834
+ hm.write32(nwritten_out, size);
835
+ if (fd === 2) hostWriteErr(str); else hostWrite(str);
836
+ return __ESUCCESS;
837
+ },
838
+ host_read: (fd, iovs, iovs_len, nread) => {
839
+ const hm = memfsHandle.hostMem;
840
+ if (!hm) return __EBADF;
841
+ let size = 0;
842
+ for (let i = 0; i < iovs_len; i++) {
843
+ const buf = hm.read32(iovs); iovs += 4;
844
+ const len = hm.read32(iovs); iovs += 4;
845
+ const remain = memfsHandle.stdinStr.length - memfsHandle.stdinPos;
846
+ const toWrite = Math.min(len, remain);
847
+ if (toWrite === 0) break;
848
+ hm.write(buf, memfsHandle.stdinStr.substr(memfsHandle.stdinPos, toWrite));
849
+ size += toWrite;
850
+ memfsHandle.stdinPos += toWrite;
851
+ if (toWrite !== len) break;
852
+ }
853
+ hm.write32(nread, size);
854
+ return __ESUCCESS;
855
+ },
856
+ memfs_log: (buf, len) => {
857
+ const m = new Uint8Array(memfsHandle.mem.buffer);
858
+ const s = __readStr(m, buf, len);
859
+ hostWriteErr('[memfs] ' + s + '\\n');
860
+ },
861
+ copy_in: (memfs_dst, src, size) => {
862
+ const dst = new Uint8Array(memfsHandle.mem.buffer, memfs_dst, size);
863
+ const srcU8 = new Uint8Array(memfsHandle.hostMem.buffer, src, size);
864
+ dst.set(srcU8);
865
+ },
866
+ copy_out: (host_dst, memfs_src, size) => {
867
+ const dst = new Uint8Array(memfsHandle.hostMem.buffer, host_dst, size);
868
+ const srcU8 = new Uint8Array(memfsHandle.mem.buffer, memfs_src, size);
869
+ dst.set(srcU8);
870
+ },
871
+ },
872
+ };
873
+ try {
874
+ const r = await WebAssembly.instantiate(args.memfsMod, memfsImports);
875
+ memfsInst = (r instanceof WebAssembly.Instance ? r : r.instance);
876
+ } catch (e) {
877
+ return { exitCode: 1, stdout: '', stderr: '', outputFiles: {}, error: 'memfs instantiate failed: ' + (e && e.message) };
878
+ }
879
+ memfsMem = memfsInst.exports.memory;
880
+ memfsHandle.mem = memfsMem;
881
+ memfsInst.exports.init();
882
+
883
+ // 2. Populate memfs from filesB64 (sysroot subset + user inputs).
884
+ for (const [path, b64] of Object.entries(args.filesB64 || {})) {
885
+ const bytes = __b64decode(b64);
886
+ try {
887
+ __memfsAddFile(memfsInst.exports, memfsMem, path, bytes);
888
+ } catch (e) {
889
+ hostWriteErr('[clang-runner] failed to add ' + path + ' to memfs: ' + (e && e.message) + '\\n');
890
+ }
891
+ }
892
+
893
+ // 3. Build wasi_unstable imports for the primary.
894
+ const argv = args.argv || [];
895
+ const environ = ['USER=user', 'HOME=/', 'PWD=/'];
896
+ const primaryHandle = { mem: null };
897
+ const primaryWasi = {
898
+ proc_exit: (code) => { throw new __ProcExit(code); },
899
+ args_get: (argv_ptrs, argv_buf) => {
900
+ const hm = primaryHandle.mem;
901
+ for (const a of argv) {
902
+ hm.write32(argv_ptrs, argv_buf);
903
+ argv_ptrs += 4;
904
+ argv_buf += hm.writeStr(argv_buf, a);
905
+ }
906
+ hm.write32(argv_ptrs, 0);
907
+ return __ESUCCESS;
908
+ },
909
+ args_sizes_get: (argc_out, argv_buf_size_out) => {
910
+ const hm = primaryHandle.mem;
911
+ let size = 0;
912
+ for (const a of argv) size += a.length + 1;
913
+ hm.write64(argc_out, argv.length);
914
+ hm.write64(argv_buf_size_out, size);
915
+ return __ESUCCESS;
916
+ },
917
+ environ_get: (environ_ptrs, environ_buf) => {
918
+ const hm = primaryHandle.mem;
919
+ for (const e of environ) {
920
+ hm.write32(environ_ptrs, environ_buf);
921
+ environ_ptrs += 4;
922
+ environ_buf += hm.writeStr(environ_buf, e);
923
+ }
924
+ hm.write32(environ_ptrs, 0);
925
+ return __ESUCCESS;
926
+ },
927
+ environ_sizes_get: (count_out, size_out) => {
928
+ const hm = primaryHandle.mem;
929
+ let size = 0;
930
+ for (const e of environ) size += e.length + 1;
931
+ hm.write64(count_out, environ.length);
932
+ hm.write64(size_out, size);
933
+ return __ESUCCESS;
934
+ },
935
+ random_get: (buf, len) => {
936
+ const hm = primaryHandle.mem;
937
+ const data = new Uint8Array(hm.memory.buffer, buf, len);
938
+ crypto.getRandomValues(data);
939
+ return __ESUCCESS;
940
+ },
941
+ clock_time_get: (clock_id, precision, time_out) => {
942
+ const hm = primaryHandle.mem;
943
+ const ns = BigInt(Date.now()) * 1000000n;
944
+ hm.write64(time_out, ns);
945
+ return __ESUCCESS;
946
+ },
947
+ poll_oneoff: () => __ENOSYS,
948
+ };
949
+ // Compose: memfs.exports satisfies fd_*/path_* fns; host overrides
950
+ // proc_exit/args_*/environ_*/random_get/clock_time_get/poll_oneoff.
951
+ const wasi_unstable = Object.assign({}, memfsInst.exports);
952
+ Object.assign(wasi_unstable, primaryWasi);
953
+
954
+ // env namespace for the primary — stub canvas_*, etc.
955
+ const primaryEnv = new Proxy({}, {
956
+ get(_t, prop) {
957
+ return function envStub() {
958
+ // Only log first occurrence per name to avoid log floods on
959
+ // wasm-ld which may probe many env imports.
960
+ return 0;
961
+ };
962
+ },
963
+ });
964
+
965
+ // 4. Instantiate primary.
966
+ let primaryInst;
967
+ try {
968
+ const r = await WebAssembly.instantiate(args.primaryMod, {
969
+ wasi_unstable,
970
+ env: primaryEnv,
971
+ });
972
+ primaryInst = (r instanceof WebAssembly.Instance ? r : r.instance);
973
+ } catch (e) {
974
+ return {
975
+ exitCode: 1, stdout: stdoutChunks.join(''), stderr: stderrChunks.join(''),
976
+ outputFiles: {},
977
+ error: 'primary (' + args.primaryName + ') instantiate failed: ' + (e && e.message),
978
+ };
979
+ }
980
+ const pmem = primaryInst.exports.memory;
981
+ primaryHandle.mem = new __HostMem(pmem);
982
+ memfsHandle.hostMem = primaryHandle.mem;
983
+
984
+ // 5. Run _start.
985
+ let exitCode = 0;
986
+ try {
987
+ primaryInst.exports._start();
988
+ } catch (exn) {
989
+ if (exn instanceof __ProcExit) {
990
+ exitCode = exn.code;
991
+ } else {
992
+ hostWriteErr('[clang-runner] ' + args.primaryName + ' trapped: ' + (exn && exn.message) + '\\n');
993
+ exitCode = 1;
994
+ }
995
+ }
996
+
997
+ // 6. Harvest output files.
998
+ const outputs = {};
999
+ for (const path of args.outputPaths || []) {
1000
+ // memfs paths are rootless.
1001
+ const p = path.replace(/^\\/+/, '');
1002
+ const pBuf = memfsInst.exports.GetPathBuf();
1003
+ const m = new Uint8Array(memfsMem.buffer);
1004
+ for (let j = 0; j < p.length; j++) m[pBuf + j] = p.charCodeAt(j) & 0xff;
1005
+ try {
1006
+ const inode = memfsInst.exports.FindNode(p.length);
1007
+ if (inode > 0) {
1008
+ const addr = memfsInst.exports.GetFileNodeAddress(inode);
1009
+ const sz = memfsInst.exports.GetFileNodeSize(inode);
1010
+ if (sz > 0) {
1011
+ const bytes = new Uint8Array(memfsMem.buffer, addr, sz);
1012
+ // Copy out (slice) because the next memfs op may invalidate
1013
+ // the view if memory grows.
1014
+ const copy = new Uint8Array(sz);
1015
+ copy.set(bytes);
1016
+ outputs[path] = __b64encode(copy);
1017
+ } else {
1018
+ outputs[path] = '';
1019
+ }
1020
+ }
1021
+ } catch { /* not found */ }
1022
+ }
1023
+
1024
+ return {
1025
+ exitCode,
1026
+ stdout: stdoutChunks.join(''),
1027
+ stderr: stderrChunks.join(''),
1028
+ outputFiles: outputs,
1029
+ };
1030
+ };
1031
+
1032
+ // ── END: clang-runner preamble ────────────────────────────────────────
1033
+ `;