@nimbus-sh/worker 0.9.0 → 0.11.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 (286) hide show
  1. package/NOTICE.md +5 -0
  2. package/README.md +10 -0
  3. package/dist/_shared/session-router.d.ts +7 -0
  4. package/dist/_shared/session-router.d.ts.map +1 -1
  5. package/dist/_shared/session-router.js +7 -0
  6. package/dist/bindings/body.d.ts +6 -0
  7. package/dist/bindings/body.d.ts.map +1 -0
  8. package/dist/bindings/body.js +37 -0
  9. package/dist/bindings/kv.d.ts +0 -2
  10. package/dist/bindings/kv.d.ts.map +1 -1
  11. package/dist/bindings/kv.js +3 -42
  12. package/dist/bindings/r2.d.ts +0 -2
  13. package/dist/bindings/r2.d.ts.map +1 -1
  14. package/dist/bindings/r2.js +4 -44
  15. package/dist/esbuild-cli-artifact.generated.d.ts +18 -0
  16. package/dist/esbuild-cli-artifact.generated.d.ts.map +1 -0
  17. package/dist/esbuild-cli-artifact.generated.js +17 -0
  18. package/dist/esbuild-wasm-bundle.generated.d.ts +24 -24
  19. package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -1
  20. package/dist/esbuild-wasm-bundle.generated.js +24 -24
  21. package/dist/facets/cirrus-real.d.ts.map +1 -1
  22. package/dist/facets/cirrus-real.js +11 -6
  23. package/dist/facets/compose.d.ts +11 -7
  24. package/dist/facets/compose.d.ts.map +1 -1
  25. package/dist/facets/compose.js +8 -31
  26. package/dist/facets/data-plan.d.ts +79 -0
  27. package/dist/facets/data-plan.d.ts.map +1 -0
  28. package/dist/facets/data-plan.js +477 -0
  29. package/dist/facets/esbuild-bundle-pool.d.ts +1 -1
  30. package/dist/facets/esbuild-bundle-pool.js +3 -3
  31. package/dist/facets/esbuild-transform.d.ts +38 -8
  32. package/dist/facets/esbuild-transform.d.ts.map +1 -1
  33. package/dist/facets/esbuild-transform.js +219 -19
  34. package/dist/facets/exec-telemetry.d.ts +7 -3
  35. package/dist/facets/exec-telemetry.d.ts.map +1 -1
  36. package/dist/facets/manager.d.ts +198 -69
  37. package/dist/facets/manager.d.ts.map +1 -1
  38. package/dist/facets/manager.js +1276 -652
  39. package/dist/facets/opencode-staging.d.ts +0 -2
  40. package/dist/facets/opencode-staging.d.ts.map +1 -1
  41. package/dist/facets/opencode-staging.js +5 -11
  42. package/dist/facets/process.d.ts +4 -0
  43. package/dist/facets/process.d.ts.map +1 -1
  44. package/dist/facets/process.js +3 -0
  45. package/dist/facets/read-profile.d.ts +149 -0
  46. package/dist/facets/read-profile.d.ts.map +1 -0
  47. package/dist/facets/read-profile.js +483 -0
  48. package/dist/facets/real-vite-hmr.d.ts +2 -0
  49. package/dist/facets/real-vite-hmr.d.ts.map +1 -1
  50. package/dist/facets/real-vite-hmr.js +3 -2
  51. package/dist/facets/resident-identity.d.ts +0 -1
  52. package/dist/facets/resident-identity.d.ts.map +1 -1
  53. package/dist/facets/resident-identity.js +0 -3
  54. package/dist/facets/wasm-swap-registry.d.ts +34 -25
  55. package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
  56. package/dist/facets/wasm-swap-registry.js +62 -56
  57. package/dist/facets/ws-terminal.d.ts +4 -4
  58. package/dist/facets/ws-terminal.d.ts.map +1 -1
  59. package/dist/facets/ws-terminal.js +4 -5
  60. package/dist/git/commands.d.ts +33 -10
  61. package/dist/git/commands.d.ts.map +1 -1
  62. package/dist/git/commands.js +1891 -197
  63. package/dist/git/network-facet.d.ts +12 -2
  64. package/dist/git/network-facet.d.ts.map +1 -1
  65. package/dist/git/network-facet.js +69 -18
  66. package/dist/git/unified-diff.d.ts +74 -0
  67. package/dist/git/unified-diff.d.ts.map +1 -0
  68. package/dist/git/unified-diff.js +676 -0
  69. package/dist/git-bundle.generated.d.ts +7 -11
  70. package/dist/git-bundle.generated.d.ts.map +1 -1
  71. package/dist/git-bundle.generated.js +7 -11
  72. package/dist/hosted/commands.d.ts.map +1 -1
  73. package/dist/hosted/commands.js +64 -245
  74. package/dist/hosted/runtime.d.ts +22 -15
  75. package/dist/hosted/runtime.d.ts.map +1 -1
  76. package/dist/hosted/runtime.js +72 -14
  77. package/dist/hosted/services.d.ts +8 -1
  78. package/dist/hosted/services.d.ts.map +1 -1
  79. package/dist/hosted/services.js +12 -13
  80. package/dist/hosted/session.d.ts +165 -0
  81. package/dist/hosted/session.d.ts.map +1 -0
  82. package/dist/hosted/session.js +132 -0
  83. package/dist/loaders/generated-workers.d.ts +6 -3
  84. package/dist/loaders/generated-workers.d.ts.map +1 -1
  85. package/dist/loaders/generated-workers.js +8 -5
  86. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
  87. package/dist/loaders/npm-resolve-preamble.js +0 -27
  88. package/dist/loaders/pre-bundle-preamble.d.ts +6 -3
  89. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -1
  90. package/dist/loaders/pre-bundle-preamble.js +13 -8
  91. package/dist/node-shims-artifact.generated.d.ts +13 -4
  92. package/dist/node-shims-artifact.generated.d.ts.map +1 -1
  93. package/dist/node-shims-artifact.generated.js +16 -7
  94. package/dist/npm/bin-links.d.ts +3 -1
  95. package/dist/npm/bin-links.d.ts.map +1 -1
  96. package/dist/npm/bin-links.js +32 -8
  97. package/dist/npm/cache.d.ts +11 -1
  98. package/dist/npm/cache.d.ts.map +1 -1
  99. package/dist/npm/cache.js +21 -7
  100. package/dist/npm/install-batch-facet.d.ts +4 -2
  101. package/dist/npm/install-batch-facet.d.ts.map +1 -1
  102. package/dist/npm/install-batch-facet.js +32 -18
  103. package/dist/npm/installer.d.ts +23 -3
  104. package/dist/npm/installer.d.ts.map +1 -1
  105. package/dist/npm/installer.js +330 -131
  106. package/dist/npm/npx-install.d.ts +3 -1
  107. package/dist/npm/npx-install.d.ts.map +1 -1
  108. package/dist/npm/npx-install.js +4 -1
  109. package/dist/npm/package-lock.d.ts +32 -0
  110. package/dist/npm/package-lock.d.ts.map +1 -0
  111. package/dist/npm/package-lock.js +65 -0
  112. package/dist/npm/placement.d.ts +16 -0
  113. package/dist/npm/placement.d.ts.map +1 -0
  114. package/dist/npm/placement.js +33 -0
  115. package/dist/npm/pre-bundle-facet.d.ts +1 -30
  116. package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
  117. package/dist/npm/pre-bundle-facet.js +3 -5
  118. package/dist/npm/r2-cache.d.ts +12 -6
  119. package/dist/npm/r2-cache.d.ts.map +1 -1
  120. package/dist/npm/r2-cache.js +34 -16
  121. package/dist/npm/resolve-one-facet.d.ts +3 -0
  122. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  123. package/dist/npm/resolve-one-facet.js +15 -3
  124. package/dist/npm/resolver.d.ts +11 -13
  125. package/dist/npm/resolver.d.ts.map +1 -1
  126. package/dist/npm/resolver.js +12 -25
  127. package/dist/opencode-artifact.generated.js +2 -2
  128. package/dist/replica/routing.d.ts +2 -38
  129. package/dist/replica/routing.d.ts.map +1 -1
  130. package/dist/replica/routing.js +3 -55
  131. package/dist/router/index.d.ts.map +1 -1
  132. package/dist/router/index.js +15 -2
  133. package/dist/router/public-directory.d.ts +18 -0
  134. package/dist/router/public-directory.d.ts.map +1 -1
  135. package/dist/router/public-directory.js +1 -1
  136. package/dist/router/remote-api.d.ts +3 -1
  137. package/dist/router/remote-api.d.ts.map +1 -1
  138. package/dist/router/remote-api.js +42 -79
  139. package/dist/runtime/bash-repl.js +2 -2
  140. package/dist/runtime/bun-repl.d.ts.map +1 -1
  141. package/dist/runtime/bun-repl.js +2 -13
  142. package/dist/runtime/cpython-resident.d.ts.map +1 -1
  143. package/dist/runtime/cpython-resident.js +2 -10
  144. package/dist/runtime/esbuild-wasm-bytes.d.ts +37 -18
  145. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -1
  146. package/dist/runtime/esbuild-wasm-bytes.js +66 -92
  147. package/dist/runtime/facet-loader-host.d.ts.map +1 -1
  148. package/dist/runtime/facet-loader-host.js +0 -7
  149. package/dist/runtime/git-bundle-artifact.d.ts +17 -0
  150. package/dist/runtime/git-bundle-artifact.d.ts.map +1 -0
  151. package/dist/runtime/git-bundle-artifact.js +25 -0
  152. package/dist/runtime/node-repl.d.ts.map +1 -1
  153. package/dist/runtime/node-repl.js +2 -13
  154. package/dist/runtime/node-shims-artifact.d.ts +22 -23
  155. package/dist/runtime/node-shims-artifact.d.ts.map +1 -1
  156. package/dist/runtime/node-shims-artifact.js +48 -78
  157. package/dist/runtime/node-shims.d.ts.map +1 -1
  158. package/dist/runtime/node-shims.js +2358 -996
  159. package/dist/runtime/opencode-artifact.d.ts.map +1 -1
  160. package/dist/runtime/opencode-artifact.js +17 -53
  161. package/dist/runtime/opencode-facet-runner.d.ts +3 -6
  162. package/dist/runtime/opencode-facet-runner.d.ts.map +1 -1
  163. package/dist/runtime/opencode-facet-runner.js +45 -10
  164. package/dist/runtime/opentui-wasm-bytes.d.ts.map +1 -1
  165. package/dist/runtime/opentui-wasm-bytes.js +16 -49
  166. package/dist/runtime/package-manager.d.ts +0 -2
  167. package/dist/runtime/package-manager.d.ts.map +1 -1
  168. package/dist/runtime/package-manager.js +0 -3
  169. package/dist/runtime/python-repl.d.ts.map +1 -1
  170. package/dist/runtime/python-repl.js +4 -35
  171. package/dist/runtime/repl-session.d.ts +10 -0
  172. package/dist/runtime/repl-session.d.ts.map +1 -1
  173. package/dist/runtime/repl-session.js +7 -0
  174. package/dist/runtime/ruby-repl.d.ts.map +1 -1
  175. package/dist/runtime/ruby-repl.js +2 -2
  176. package/dist/runtime/ruby-resident.d.ts.map +1 -1
  177. package/dist/runtime/ruby-resident.js +41 -51
  178. package/dist/runtime/runtime-catalog.d.ts +10 -3
  179. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  180. package/dist/runtime/runtime-catalog.js +125 -15
  181. package/dist/runtime/sqlite-wasm-bytes.d.ts +4 -4
  182. package/dist/runtime/sqlite-wasm-bytes.d.ts.map +1 -1
  183. package/dist/runtime/sqlite-wasm-bytes.js +21 -57
  184. package/dist/runtime/staged-source.d.ts +67 -0
  185. package/dist/runtime/staged-source.d.ts.map +1 -0
  186. package/dist/runtime/staged-source.js +113 -0
  187. package/dist/runtime/wasi/preamble.d.ts +0 -22
  188. package/dist/runtime/wasi/preamble.d.ts.map +1 -1
  189. package/dist/runtime/wasi/preamble.js +98 -1425
  190. package/dist/runtime-catalog.generated.js +1 -1
  191. package/dist/session/agent.d.ts +14 -2
  192. package/dist/session/agent.d.ts.map +1 -1
  193. package/dist/session/agent.js +57 -19
  194. package/dist/session/ai.d.ts +0 -11
  195. package/dist/session/ai.d.ts.map +1 -1
  196. package/dist/session/ai.js +0 -4
  197. package/dist/session/fs-watch.d.ts +0 -11
  198. package/dist/session/fs-watch.d.ts.map +1 -1
  199. package/dist/session/fs-watch.js +0 -21
  200. package/dist/session/hibernation.d.ts +68 -2
  201. package/dist/session/hibernation.d.ts.map +1 -1
  202. package/dist/session/hibernation.js +95 -1
  203. package/dist/session/init-phases.d.ts +1 -2
  204. package/dist/session/init-phases.d.ts.map +1 -1
  205. package/dist/session/init-phases.js +1 -2
  206. package/dist/session/init.d.ts.map +1 -1
  207. package/dist/session/init.js +7 -20
  208. package/dist/session/keys.d.ts +0 -3
  209. package/dist/session/keys.d.ts.map +1 -1
  210. package/dist/session/keys.js +0 -3
  211. package/dist/session/legacy-reset.d.ts +11 -0
  212. package/dist/session/legacy-reset.d.ts.map +1 -0
  213. package/dist/session/legacy-reset.js +16 -0
  214. package/dist/session/nimbus-session.d.ts +50 -16
  215. package/dist/session/nimbus-session.d.ts.map +1 -1
  216. package/dist/session/nimbus-session.js +77 -71
  217. package/dist/session/npm-install-port.d.ts.map +1 -1
  218. package/dist/session/npm-install-port.js +2 -0
  219. package/dist/session/programmatic.d.ts +13 -18
  220. package/dist/session/programmatic.d.ts.map +1 -1
  221. package/dist/session/programmatic.js +53 -39
  222. package/dist/session/replica-routes.d.ts +2 -3
  223. package/dist/session/replica-routes.d.ts.map +1 -1
  224. package/dist/session/replica-routes.js +3 -10
  225. package/dist/session/routes.d.ts.map +1 -1
  226. package/dist/session/routes.js +11 -12
  227. package/dist/session/rpc.d.ts +108 -21
  228. package/dist/session/rpc.d.ts.map +1 -1
  229. package/dist/session/rpc.js +194 -39
  230. package/dist/session/start-real-vite.js +2 -2
  231. package/dist/session/state-store.d.ts +1 -17
  232. package/dist/session/state-store.d.ts.map +1 -1
  233. package/dist/session/state-store.js +3 -53
  234. package/dist/session/supervisor-op.d.ts +7 -0
  235. package/dist/session/supervisor-op.d.ts.map +1 -1
  236. package/dist/session/supervisor-op.js +6 -1
  237. package/dist/session/supervisor-rpc.d.ts +116 -19
  238. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  239. package/dist/session/supervisor-rpc.js +194 -84
  240. package/dist/session/vite-command.d.ts.map +1 -1
  241. package/dist/session/vite-command.js +17 -14
  242. package/dist/session/ws.d.ts.map +1 -1
  243. package/dist/session/ws.js +20 -8
  244. package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
  245. package/dist/shell/npm-bin-entrypoints.js +30 -5
  246. package/dist/vfs/facet-resident-limits.d.ts +33 -0
  247. package/dist/vfs/facet-resident-limits.d.ts.map +1 -0
  248. package/dist/vfs/facet-resident-limits.js +33 -0
  249. package/dist/vfs/facet-resident-store.d.ts +2 -10
  250. package/dist/vfs/facet-resident-store.d.ts.map +1 -1
  251. package/dist/vfs/facet-resident-store.js +1594 -219
  252. package/dist/workspace-host.d.ts +3 -1
  253. package/dist/workspace-host.d.ts.map +1 -1
  254. package/dist/workspace-host.js +2 -0
  255. package/dist/wrangler/nimbus-wrangler.d.ts +0 -2
  256. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -1
  257. package/dist/wrangler/nimbus-wrangler.js +8 -22
  258. package/package.json +34 -7
  259. package/public/_assets/esbuild-0.24.2.js +2380 -0
  260. package/public/_assets/opencode/1.16.2/index-attach.js +2 -2
  261. package/public/_assets/runtime/esbuild-cli-c4fda380d52befc1.js +6892 -0
  262. package/public/_assets/runtime/git-de3e60c9f3ff006a.js +103 -0
  263. package/public/_assets/runtime/{node-shims-acaa037e6d26ec0d.js → node-shims-06565b121555c194.js} +2879 -992
  264. package/public/_assets/runtime/resident-store-6ffb1939c53d982f.js +2264 -0
  265. package/public/_assets/runtime/vfs-write-ledger-e501e8fc793bc2c1.js +889 -0
  266. package/scripts/build-opencode-attach-entry.mjs +51 -1
  267. package/scripts/bundle-esbuild-wasm.mjs +55 -39
  268. package/scripts/bundle-facet-workers.mjs +159 -10
  269. package/scripts/bundle-git.mjs +88 -27
  270. package/scripts/bundle-node-shims.mjs +72 -46
  271. package/scripts/bundle-runtime.mjs +18 -421
  272. package/scripts/cf-git-patch.mjs +137 -0
  273. package/scripts/patch-install-deps.mjs +49 -96
  274. package/scripts/runtime-specs.mjs +435 -0
  275. package/vendor/git-http.generated.d.ts +82 -0
  276. package/vendor/git-upstream.generated.d.ts +4378 -0
  277. package/vendor/git.LICENSE +7 -0
  278. package/vendor/git.generated.d.mts +21 -0
  279. package/vendor/git.generated.mjs +103 -0
  280. package/dist/replica/suspension.d.ts +0 -36
  281. package/dist/replica/suspension.d.ts.map +0 -1
  282. package/dist/replica/suspension.js +0 -49
  283. package/dist/runtime/static-server.d.ts +0 -3
  284. package/dist/runtime/static-server.d.ts.map +0 -1
  285. package/dist/runtime/static-server.js +0 -133
  286. package/scripts/clean-dist.mjs +0 -7
@@ -8,76 +8,33 @@
8
8
  */
9
9
 
10
10
  import {
11
+ copyFileSync,
11
12
  existsSync,
12
13
  readFileSync,
13
- readdirSync,
14
- realpathSync,
15
14
  symlinkSync,
15
+ unlinkSync,
16
16
  writeFileSync,
17
17
  } from 'node:fs';
18
18
  import { spawnSync } from 'node:child_process';
19
19
  import { join, dirname, resolve, relative } from 'node:path';
20
20
  import { fileURLToPath } from 'node:url';
21
21
 
22
+ import {
23
+ CF_GIT_PATCH,
24
+ cfGitState,
25
+ findCfGitDirs,
26
+ findNodeModules,
27
+ patchImages,
28
+ pristineIndexJs,
29
+ reinstallCommand,
30
+ } from './cf-git-patch.mjs';
31
+
22
32
  const __dirname = dirname(fileURLToPath(import.meta.url));
23
33
  // The script lives at packages/worker/scripts/. Walk up to the repo
24
34
  // root so we can patch every node_modules tree below it.
25
35
  const repoRoot = resolve(__dirname, '..', '..', '..');
26
- const cfGitPatch = resolve(
27
- __dirname,
28
- '..',
29
- 'patches',
30
- '@ashishkumar472+cf-git+1.0.5.patch',
31
- );
32
-
33
- // Walk every node_modules tree and patch cf-git copies.
34
- function walkForNodeModules(base, depth = 0) {
35
- if (depth > 5) return []; // safety
36
- if (!existsSync(base)) return [];
37
- const out = [];
38
- let entries;
39
- try { entries = readdirSync(base, { withFileTypes: true }); }
40
- catch { return []; }
41
- for (const ent of entries) {
42
- if (!ent.isDirectory()) continue;
43
- if (ent.name === 'node_modules') {
44
- out.push(join(base, ent.name));
45
- } else if (ent.name === 'packages' || ent.name === 'apps') {
46
- // recurse one level into packages/* and apps/*
47
- for (const sub of readdirSync(join(base, ent.name), { withFileTypes: true })) {
48
- if (sub.isDirectory()) {
49
- out.push(...walkForNodeModules(join(base, ent.name, sub.name), depth + 1));
50
- }
51
- }
52
- }
53
- }
54
- return out;
55
- }
56
-
57
- const nmDirs = walkForNodeModules(repoRoot);
58
- const cfGitDirs = new Set();
59
-
60
- for (const nm of nmDirs) {
61
- for (const packagePath of [
62
- join(nm, 'isomorphic-git', 'package.json'),
63
- join(nm, '@ashishkumar472', 'cf-git', 'package.json'),
64
- join(
65
- nm,
66
- '.bun',
67
- '@ashishkumar472+cf-git@1.0.5',
68
- 'node_modules',
69
- '@ashishkumar472',
70
- 'cf-git',
71
- 'package.json',
72
- ),
73
- ]) {
74
- if (!existsSync(packagePath)) continue;
75
- const pkg = JSON.parse(readFileSync(packagePath, 'utf8'));
76
- if (pkg.name === '@ashishkumar472/cf-git' && pkg.version === '1.0.5') {
77
- cfGitDirs.add(realpathSync(dirname(packagePath)));
78
- }
79
- }
80
- }
36
+ const nmDirs = findNodeModules(repoRoot);
37
+ const cfGitDirs = findCfGitDirs(repoRoot);
81
38
 
82
39
  for (const nm of nmDirs) {
83
40
  const igPkgPath = join(nm, 'isomorphic-git', 'package.json');
@@ -107,6 +64,8 @@ for (const nm of nmDirs) {
107
64
  };
108
65
  }
109
66
  pkg.main = './src/index.js';
67
+ // bun hardlinks package.json from its cache: a new file, never a write through the link.
68
+ unlinkSync(igPkgPath);
110
69
  writeFileSync(igPkgPath, JSON.stringify(pkg, null, 2) + '\n');
111
70
  console.log(`[patch] cf-git exports patched: ${igPkgPath}`);
112
71
  }
@@ -146,56 +105,50 @@ for (const nm of nmDirs) {
146
105
  }
147
106
  }
148
107
 
149
- if (!existsSync(cfGitPatch)) {
150
- throw new Error(`Missing tracked cf-git patch: ${cfGitPatch}`);
151
- }
108
+ const images = patchImages();
152
109
  if (cfGitDirs.size === 0) {
153
110
  throw new Error('No @ashishkumar472/cf-git@1.0.5 installation found to patch');
154
111
  }
155
112
 
156
- function runGitApply(cwd, args) {
157
- return spawnSync(
158
- 'git',
159
- ['apply', '--no-index', '--unidiff-zero', ...args, cfGitPatch],
160
- {
161
- cwd,
162
- encoding: 'utf8',
163
- env: {
164
- ...process.env,
165
- GIT_CEILING_DIRECTORIES: dirname(cwd),
166
- },
167
- },
168
- );
169
- }
170
-
171
- function gitApplyFailure(result) {
172
- return (
173
- result.error?.message ||
174
- result.stderr?.trim() ||
175
- result.stdout?.trim() ||
176
- 'unknown error'
177
- );
113
+ function gitApply(cwd) {
114
+ const result = spawnSync('git', ['apply', '--no-index', '--unidiff-zero', CF_GIT_PATCH], {
115
+ cwd,
116
+ encoding: 'utf8',
117
+ env: { ...process.env, GIT_CEILING_DIRECTORIES: dirname(cwd) },
118
+ });
119
+ if (result.status === 0) return;
120
+ const why = result.error?.message || result.stderr?.trim() || result.stdout?.trim() || 'unknown error';
121
+ throw new Error(`Failed to apply cf-git checkout repairs at ${cwd}: ${why}`);
178
122
  }
179
123
 
124
+ // Each copy's index.js is identified by its blob id against the patch's
125
+ // `index <pre>..<post>` header. bun's isolated linker hardlinks installed
126
+ // files from its cache, so nothing here writes into an existing index.js:
127
+ // git apply writes its result as a new file in place of the old one (a new
128
+ // inode; tests/unit/cf-git-patch-state.mjs holds it), and a restore unlinks the installed file before copying.
180
129
  for (const cfGitDir of cfGitDirs) {
181
- const reverseCheck = runGitApply(cfGitDir, ['--reverse', '--check']);
182
- if (reverseCheck.status === 0) {
130
+ const state = cfGitState(cfGitDir, images);
131
+ if (state === 'patched') {
183
132
  console.log(`[patch] cf-git checkout repairs already applied: ${cfGitDir}`);
184
133
  continue;
185
134
  }
186
-
187
- const forwardCheck = runGitApply(cfGitDir, ['--check']);
188
- if (forwardCheck.status !== 0) {
189
- throw new Error(
190
- `Cannot apply cf-git checkout repairs at ${cfGitDir}: ${gitApplyFailure(forwardCheck)}`,
191
- );
135
+ if (state !== 'pristine') {
136
+ // Another revision of the patch (or a hand edit): start again from bun's cached copy.
137
+ const pristine = pristineIndexJs(images);
138
+ if (state === 'missing' || !pristine) {
139
+ throw new Error(
140
+ `cf-git at ${cfGitDir} is neither pristine nor patched with the tracked patch (index.js ${images.pre}..${images.post}), `
141
+ + `and bun's cache holds no pristine copy to restore. Reinstall it: ${reinstallCommand(cfGitDir, repoRoot)}`,
142
+ );
143
+ }
144
+ const indexJs = join(cfGitDir, 'index.js');
145
+ unlinkSync(indexJs);
146
+ copyFileSync(pristine, indexJs);
147
+ console.log(`[patch] cf-git index.js restored from bun's cache (${pristine}): ${cfGitDir}`);
192
148
  }
193
-
194
- const apply = runGitApply(cfGitDir, []);
195
- if (apply.status !== 0) {
196
- throw new Error(
197
- `Failed to apply cf-git checkout repairs at ${cfGitDir}: ${gitApplyFailure(apply)}`,
198
- );
149
+ gitApply(cfGitDir);
150
+ if (cfGitState(cfGitDir, images) !== 'patched') {
151
+ throw new Error(`cf-git at ${cfGitDir} does not match the tracked patch's post-image ${images.post} after applying it`);
199
152
  }
200
153
  console.log(`[patch] cf-git checkout repairs applied: ${cfGitDir}`);
201
154
  }
@@ -0,0 +1,435 @@
1
+ /**
2
+ * runtime-specs.mjs — every runtime Nimbus publishes, and how.
3
+ *
4
+ * One table, two readers: `bundle-runtime.mjs` stages a spec into R2 or into
5
+ * an npm package directory, and `packages/core/scripts/check-runtime-packages.mjs`
6
+ * refuses a core release while any spec with an `npm` entry is not on npm as
7
+ * the `latest` build. A runtime joins the npm set by gaining an `npm` entry.
8
+ */
9
+
10
+ import { BASH_RUNNER } from '@nimbus-sh/core/runtime/os-contracts.js';
11
+
12
+ /**
13
+ * Static per-runtime spec. Each entry says where to fetch the upstream
14
+ * file from and how to map it into the per-user VFS at install time.
15
+ *
16
+ * For `clang binji-2020`:
17
+ * - VFS path `bin/clang` ← upstream `clang` (31.2 MB)
18
+ * - VFS path `bin/wasm-ld` ← upstream `lld` (19.5 MB)
19
+ * - VFS path `share/clang/sysroot.tar`← upstream `sysroot.tar` (9.3 MB)
20
+ * - VFS path `LICENSE` ← bundled APACHE-2.0 text
21
+ */
22
+ export const SPECS = {
23
+ 'clang/binji-2020': {
24
+ license: 'Apache-2.0-with-LLVM-exception',
25
+ wasi_namespace: 'wasi_unstable',
26
+ upstream_base: 'https://raw.githubusercontent.com/binji/wasm-clang/master',
27
+ npm: {
28
+ name: '@nimbus-sh/runtime-clang',
29
+ summary: 'clang 8.0.1 and wasm-ld for wasm32-wasi, with a wasi-libc sysroot',
30
+ // npm demands semver and this runtime's Nimbus version is a channel
31
+ // name, so the compiler's own version is what the package carries. The
32
+ // two namespaces stay separate: the manifest still says `binji-2020`,
33
+ // and that is what the install root under ~/.nimbus/runtimes is named.
34
+ version: '8.0.1',
35
+ },
36
+ files: [
37
+ { src: 'clang', vfs: 'bin/clang', mode: 'exec', runner: 'clang-runner', binName: 'clang' },
38
+ { src: 'lld', vfs: 'bin/wasm-ld', mode: 'exec', runner: 'clang-runner', binName: 'wasm-ld', kind: 'linker' },
39
+ { src: 'sysroot.tar', vfs: 'share/clang/sysroot.tar' },
40
+ ],
41
+ // Bundled LICENSE text — Apache 2.0 with LLVM exception (full text below).
42
+ // Source: https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT
43
+ license_text: APACHE_2_LLVM_LICENSE_TEXT(),
44
+ },
45
+ // ── Ruby (v1, 2026-05-11) ────────────────────────────────────────
46
+ // ruby.wasm 2.9.3-2.9.4 from npm @ruby/3.3-wasm-wasi (Ruby 3.3.x
47
+ // built on WASI). We bundle ONLY the `ruby+stdlib.wasm` artifact
48
+ // (34.3 MiB) — it's self-contained, stdlib is packed via wasi-vfs
49
+ // into the wasm. No separate stdlib zip transport needed (unlike
50
+ // Pyodide which ships python_stdlib.zip alongside the asm.js).
51
+ //
52
+ // Upstream channel: npm tarball — the script downloads the tarball
53
+ // (`upstream_base + '/' + src`) and extracts the wasm by file
54
+ // name via the `tarball_extract` flag. Each spec.files entry's
55
+ // `src` is interpreted as the path INSIDE the extracted tarball.
56
+ //
57
+ // See /workspace/.seal-internal/2026-05-11-ruby-v1/audit.md for
58
+ // the full artifact audit + import/export breakdown.
59
+ 'ruby/3.3.4': {
60
+ license: 'Ruby+BSD-2-Clause',
61
+ wasi_namespace: 'wasi_snapshot_preview1',
62
+ upstream_base: 'https://registry.npmjs.org/@ruby/3.3-wasm-wasi/-/3.3-wasm-wasi-2.9.3-2.9.4.tgz',
63
+ npm: {
64
+ name: '@nimbus-sh/runtime-ruby',
65
+ summary: 'Ruby 3.3.4 (ruby.wasm) for wasm32-wasi, with its stdlib packed in',
66
+ },
67
+ tarball_extract: 'package/dist', // strip this prefix from src paths inside the tarball
68
+ files: [
69
+ // The Ruby wasm — includes Ruby 3.3.x interpreter + stdlib packed
70
+ // via wasi-vfs. ruby-runner instantiates this at child-facet
71
+ // module-init time and drives it via the Ruby ABI exports
72
+ // (`ruby-init`, `ruby-init-loadpath`, `rb-eval-string-protect`).
73
+ { src: 'ruby+stdlib.wasm', vfs: 'share/ruby/ruby+stdlib.wasm' },
74
+ // User-facing bin entries. The shell registry dispatches `ruby`
75
+ // and `ruby3` to ruby-runner; this file is a marker, not exec.
76
+ { src: 'BIN_MARKER', vfs: 'bin/ruby', mode: 'exec', runner: 'ruby-runner', binName: 'ruby' },
77
+ { src: 'BIN_MARKER', vfs: 'bin/ruby3', mode: 'exec', runner: 'ruby-runner', binName: 'ruby3' },
78
+ ],
79
+ synthetic_files: {
80
+ 'BIN_MARKER': Buffer.from(
81
+ '# Nimbus ruby-runner launcher marker. The actual Ruby wasm\n' +
82
+ '# lives in share/ruby/. This file is here only so `which ruby`\n' +
83
+ '# and `ls bin/` find a regular file at the expected path. The\n' +
84
+ '# shell-registry dispatches `ruby` directly to the ruby-runner\n' +
85
+ '# factory; this file is not read or executed by Nimbus.\n',
86
+ 'utf8',
87
+ ),
88
+ },
89
+ license_text: RUBY_LICENSE_TEXT(),
90
+ },
91
+ // ── GNU bash (fork runtime, 2026-07-20) ──────────────────────────
92
+ // bash 5.2.37 cross-compiled to wasm32-wasi with the Nimbus process
93
+ // overlay (nimbus-proc.{h,c}: fork/exec/wait/pipe over nimbus_proc.*
94
+ // imports + asyncify-native setjmp) and asyncify-instrumented.
95
+ // There is NO upstream binary channel — the artifacts are built from
96
+ // source by packages/worker/wasm/bash/build-bash.sh (bash) and
97
+ // coreutils/build-busybox.sh (BusyBox 1.37.0, the plain-WASI multicall
98
+ // exec target providing ls/cat/cp/mv/rm/grep/sed/awk/find/... — see
99
+ // busybox.applets), then staged from the local build tree via
100
+ // `local_base`. The bash-runner aliases every applet name in
101
+ // busybox.applets onto the busybox module so bash's PATH lookup finds
102
+ // them in /bin and /usr/bin.
103
+ //
104
+ // The version is `<upstream>-<build>`: the build number advances with
105
+ // every rebuild, and the entrypoint names the runner contract the build
106
+ // was made for (BASH_RUNNER), so a deployment whose preamble predates it
107
+ // never binds it. 5.2.37 is build 1, published under `bash-runner`.
108
+ 'bash/5.2.37-3': {
109
+ license: 'GPL-3.0-or-later AND GPL-2.0-only',
110
+ wasi_namespace: 'wasi_snapshot_preview1',
111
+ local_base: '../wasm/bash',
112
+ auxiliary_bins: 'coreutils/busybox.applets',
113
+ npm: {
114
+ name: '@nimbus-sh/runtime-bash',
115
+ summary: 'GNU bash 5.2.37 and BusyBox 1.37.0, cross-compiled to wasm32-wasi',
116
+ // Runner @3 queries the guest signal disposition before delivery.
117
+ core: '>=0.13.0',
118
+ },
119
+ files: [
120
+ { src: 'bash.async.wasm', vfs: 'share/bash/bash.async.wasm' },
121
+ { src: 'coreutils/busybox.wasm', vfs: 'share/bash/coreutils/busybox.wasm' },
122
+ { src: 'coreutils/busybox.applets', vfs: 'share/bash/coreutils/busybox.applets' },
123
+ { src: 'BIN_MARKER', vfs: 'bin/bash', mode: 'exec', runner: BASH_RUNNER, binName: 'bash' },
124
+ ],
125
+ synthetic_files: {
126
+ 'BIN_MARKER': Buffer.from(
127
+ '# Nimbus bash-runner launcher marker. The real GNU bash wasm\n' +
128
+ '# lives in share/bash/. The shell registry dispatches `bash`\n' +
129
+ '# (and #!/bin/bash shebangs) to the bash-runner factory; this\n' +
130
+ '# file exists so `which bash` and `ls bin/` find a regular,\n' +
131
+ '# executable file at the expected path.\n',
132
+ 'utf8',
133
+ ),
134
+ },
135
+ license_text: GPL_3_LICENSE_NOTICE(),
136
+ },
137
+ 'python/0.29.4': {
138
+ license: 'MPL-2.0',
139
+ wasi_namespace: null, // Pyodide is Emscripten, not WASI
140
+ upstream_base: 'https://cdn.jsdelivr.net/pyodide/v0.29.4/full',
141
+ files: [
142
+ // The wasm module Pyodide instantiates. Goes to share/ so the
143
+ // user-VFS layout matches binji-clang's convention (bin/ for
144
+ // exec entry, share/<name>/ for runtime-private blobs).
145
+ { src: 'pyodide.asm.wasm', vfs: 'share/pyodide/pyodide.asm.wasm' },
146
+ // The Emscripten JS half. Runtime sync adapts it once for
147
+ // workerd and records that contract in manifest metadata; the
148
+ // Python runner consumes the resulting artifact without patching
149
+ // it during session boot.
150
+ { src: 'pyodide.asm.js', vfs: 'share/pyodide/pyodide.asm.js', transform: 'pyodide-workerd-adapter' },
151
+ // Python 3.13 stdlib. Pyodide writes this into its Emscripten
152
+ // MEMFS at /lib/python313.zip and CPython imports from there
153
+ // via the ZipImporter on sys.path.
154
+ { src: 'python_stdlib.zip', vfs: 'share/pyodide/python_stdlib.zip' },
155
+ // Lockfile — only used by pyodide.loadPackage / micropip (v3
156
+ // scope). We ship it so v3 doesn't need to re-bundle from
157
+ // scratch; v1 ignores its contents.
158
+ { src: 'pyodide-lock.json', vfs: 'share/pyodide/pyodide-lock.json' },
159
+ // The user-facing "bin" — a tiny launcher marker. We don't
160
+ // actually exec this file; the python-runner factory pulls
161
+ // bytes from the share/ entries and ignores bin/python's
162
+ // content. The presence of the entry in entrypoints[] is what
163
+ // wires `python` into the shell registry.
164
+ { src: 'BIN_MARKER', vfs: 'bin/python', mode: 'exec', runner: 'python-runner', binName: 'python' },
165
+ // Second entrypoint — `python3` is conventional on Linux.
166
+ { src: 'BIN_MARKER', vfs: 'bin/python3', mode: 'exec', runner: 'python-runner', binName: 'python3' },
167
+ ],
168
+ license_text: MPL_2_LICENSE_TEXT(),
169
+ /** Source 'BIN_MARKER' is synthesised, not fetched. */
170
+ synthetic_files: {
171
+ 'BIN_MARKER': Buffer.from(
172
+ '# Nimbus python-runner launcher marker. The actual Pyodide\n' +
173
+ '# bootstrap lives in share/pyodide/. This file is here only so\n' +
174
+ '# `which python` and `ls bin/` find a regular file at the\n' +
175
+ '# expected path. The shell-registry dispatches `python`\n' +
176
+ '# directly to the python-runner factory; this file is not\n' +
177
+ '# read or executed by Nimbus.\n',
178
+ 'utf8',
179
+ ),
180
+ },
181
+ python_packages: ['numpy', 'markupsafe'],
182
+ },
183
+
184
+ // CPython 3.13 cross-built for wasm32-wasi by packages/worker/wasm/python/
185
+ // build-python.sh, with the C libraries the published wasm32-wasi artifacts
186
+ // leave out (zlib, bzip2, xz, sqlite, OpenSSL). Unlike the Pyodide entry
187
+ // above this is a real WASI module: it talks to runtime/wasi/preamble.ts, so
188
+ // it has no filesystem of its own to copy in and diff back out.
189
+ //
190
+ // Additive alongside python/0.29.4. Nothing reads these keys until
191
+ // session/init.ts routes `python` at the cpython-runner factory.
192
+ 'cpython/3.13.14': {
193
+ license: 'PSF-2.0',
194
+ wasi_namespace: 'wasi_snapshot_preview1',
195
+ local_base: '../wasm/python',
196
+ npm: {
197
+ name: '@nimbus-sh/runtime-cpython',
198
+ summary: 'CPython 3.13.14, cross-compiled to wasm32-wasi, with its stdlib',
199
+ },
200
+ files: [
201
+ { src: 'python.wasm', vfs: 'share/cpython/python.wasm' },
202
+ // The same interpreter with numpy and markupsafe's C speedups linked in,
203
+ // and their Python half. wasm32-wasi has no dlopen, so a compiled package
204
+ // is either in the binary or unavailable; the runner picks between the two
205
+ // from what the session installed. Both ship because the choice is made
206
+ // per invocation, inside the session, long after the install.
207
+ { src: 'python-sci.wasm', vfs: 'share/cpython/python-sci.wasm' },
208
+ // Beside the stdlib zip on purpose: the runner puts it on sys.path and
209
+ // zipimport reads it out of the session filesystem, so it needs the same
210
+ // treatment as lib/python313.zip and no separate transport.
211
+ { src: 'sci-packages.zip', vfs: 'lib/sci-packages.zip' },
212
+ // The stdlib, pyc-only. Read straight out of the session filesystem by
213
+ // zipimport, which is why it needs no separate transport.
214
+ // Laid out as a Python prefix, so nimbus_py_init can be handed the
215
+ // install root directly. Aliasing lib/ onto some other path would put
216
+ // entries in the guest's filesystem that the supervisor cannot serve,
217
+ // and a manifest entry nobody can fetch is an EIO waiting to happen.
218
+ { src: 'python313.zip', vfs: 'lib/python313.zip' },
219
+ // OpenSSL has no default trust store to fall back on here: there is no
220
+ // /etc/ssl in the session, so ssl.create_default_context() would verify
221
+ // against nothing and every HTTPS fetch would fail. SSL_CERT_FILE points
222
+ // at this. Mozilla's bundle, as published by curl.se.
223
+ { src: 'cacert.pem', vfs: 'etc/ssl/cert.pem' },
224
+ { src: 'STDLIB_MARKER', vfs: 'lib/python3.13/os.py' },
225
+ { src: 'BIN_MARKER', vfs: 'bin/python', mode: 'exec', runner: 'cpython-runner', binName: 'python' },
226
+ { src: 'BIN_MARKER', vfs: 'bin/python3', mode: 'exec', runner: 'cpython-runner', binName: 'python3' },
227
+ ],
228
+ license_text: PSF_LICENSE_NOTICE(),
229
+ /** Source 'BIN_MARKER' is synthesised, not fetched. */
230
+ synthetic_files: {
231
+ 'STDLIB_MARKER': Buffer.from(
232
+ '# Nimbus stdlib marker. Every module is read from ../python313.zip;\n' +
233
+ '# this file exists so the prefix looks like a Python prefix.\n',
234
+ 'utf8',
235
+ ),
236
+ 'BIN_MARKER': Buffer.from(
237
+ '# Nimbus cpython-runner launcher marker. The interpreter itself\n' +
238
+ '# lives in share/cpython/. This file exists so `which python` and\n' +
239
+ '# `ls bin/` find a regular, executable file at the expected path;\n' +
240
+ '# the shell registry dispatches `python` directly to the\n' +
241
+ '# cpython-runner factory and never reads this content.\n',
242
+ 'utf8',
243
+ ),
244
+ },
245
+ },
246
+
247
+ // 2026-05-11 sysroot-prep Phase 0 — R2 ingestion ONLY for the
248
+ // clang-sysroot-swap wave. This entry stages the upstream wasi-sdk-19
249
+ // sysroot in R2 (binji-shape: rootless `include/lib/share` layout) so
250
+ // when the swap wave dispatches, the blob is already present.
251
+ //
252
+ // `ingest_only: true` SUPPRESSES the manifest write AND the catalog
253
+ // auto-flip at the bottom of the script. The swap wave owns those
254
+ // operations (it composes a new manifest that inherits bin/clang,
255
+ // bin/wasm-ld from binji-2020 and references this
256
+ // prep'd sysroot.tar blob, then flips `clang.default`).
257
+ //
258
+ // `repackage` describes a download+extract+retar pre-step that
259
+ // produces a single local `sysroot.tar` file BEFORE the upload loop.
260
+ // The file's `src` value is used as both the cached download filename
261
+ // and (after repackage) the upload basename.
262
+ 'clang/wasi-sdk-19': {
263
+ license: 'Apache-2.0-with-LLVM-exception',
264
+ ingest_only: true,
265
+ files: [
266
+ // The upload loop sees one logical "file" with src='sysroot.tar'.
267
+ // The repackage step below produces it from the upstream tarball
268
+ // and writes it to <workDir>/sysroot.tar before the upload loop
269
+ // runs. `vfs` mirrors the binji-2020 path for the swap wave's
270
+ // manifest composer (kept for documentation only; ignored in
271
+ // ingest_only mode since no manifest is written).
272
+ { src: 'sysroot.tar', vfs: 'share/clang/sysroot.tar' },
273
+ ],
274
+ // Build-time step: fetch the upstream wasi-sdk-19 sysroot tarball,
275
+ // extract, and re-tar in binji-2020 layout (rootless: include/, lib/,
276
+ // share/ as top-level entries, no `wasi-sysroot/` prefix). Runs
277
+ // BEFORE the existing fetch loop sees `sysroot.tar`.
278
+ repackage: {
279
+ upstream_url:
280
+ 'https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sysroot-19.0.tar.gz',
281
+ // sha256 of the upstream .tar.gz, captured 2026-05-11.
282
+ // Falsification: bundle-runtime.mjs verifies this on every run.
283
+ upstream_sha256:
284
+ 'd601c901a26d6cdb158e60c8a981caa189e87875abc23bb071c2c533a39fd143',
285
+ // Subdir inside the extracted tarball whose children become the
286
+ // top-level entries of the produced sysroot.tar.
287
+ strip_prefix: 'wasi-sysroot',
288
+ // Directories at strip_prefix to include in the produced sysroot.tar.
289
+ // Anything else under wasi-sysroot/ is dropped.
290
+ include_dirs: ['include', 'lib', 'share'],
291
+ // Expected sha256 of the *produced* sysroot.tar. Captured from a
292
+ // dry-run inspection at /tmp/sysroot-prep-work/ (see prep audit).
293
+ // Verified before upload; abort on mismatch.
294
+ output_sha256:
295
+ '82f30ed81d39072d54e3ba207305c26bfc29a7726e500230db3cad8abe828be3',
296
+ // Expected raw byte size of the produced sysroot.tar.
297
+ output_size: 11898880,
298
+ },
299
+ // license_text intentionally omitted — ingest_only mode skips the
300
+ // bundled LICENSE write. The swap wave composes a concat-license
301
+ // (binji + wasi-libc) at manifest time.
302
+ },
303
+ };
304
+
305
+ /**
306
+ * The specs published to npm: `runtime`/`version` are the bundle-runtime.mjs
307
+ * arguments, `npmVersion` what the package.json carries.
308
+ */
309
+ export function npmRuntimeSpecs() {
310
+ return Object.entries(SPECS)
311
+ .filter(([, spec]) => spec.npm && !spec.ingest_only)
312
+ .map(([key, spec]) => {
313
+ const [runtime, version] = key.split('/');
314
+ return { runtime, version, name: spec.npm.name, npmVersion: spec.npm.version ?? version };
315
+ });
316
+ }
317
+
318
+ // ── Bundled LICENSE text generator ────────────────────────────────
319
+ function GPL_3_LICENSE_NOTICE() {
320
+ return `GNU bash 5.2.37 — GPL-3.0-or-later
321
+ Copyright (C) Free Software Foundation, Inc.
322
+
323
+ This runtime bundles GNU bash cross-compiled to wasm32-wasi. Full
324
+ license text: https://www.gnu.org/licenses/gpl-3.0.txt
325
+ Corresponding source: https://ftp.gnu.org/gnu/bash/bash-5.2.37.tar.gz
326
+ plus the Nimbus build overlay (packages/worker/wasm/bash/ in the
327
+ Nimbus repository: nimbus-proc.{h,c}, build-bash.sh, coreutils/).
328
+
329
+ BusyBox 1.37.0 — GPL-2.0-only
330
+ Copyright (C) many authors, 1998-2015. See the source distribution.
331
+
332
+ The coreutils exec targets (ls, cat, grep, sed, awk, find, ...) are
333
+ BusyBox cross-compiled to wasm32-wasi as one multicall binary. Full
334
+ license text: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
335
+ Corresponding source: https://busybox.net/downloads/busybox-1.37.0.tar.bz2
336
+ plus the Nimbus build overlay (packages/worker/wasm/bash/coreutils/ in
337
+ the Nimbus repository: build-busybox.sh, wasi-shim.c, overlay/).
338
+ `;
339
+ }
340
+
341
+ function PSF_LICENSE_NOTICE() {
342
+ return [
343
+ 'Python is distributed under the Python Software Foundation License',
344
+ 'Version 2. The full text is at https://docs.python.org/3/license.html',
345
+ 'and is included in the interpreter as Lib/LICENSE.txt.',
346
+ '',
347
+ 'Copyright (c) 2001-2026 Python Software Foundation. All Rights Reserved.',
348
+ '',
349
+ 'This build is CPython 3.13.14 cross-compiled for wasm32-wasi and',
350
+ 'statically linked against zlib (zlib licence), bzip2 (BSD-like), xz',
351
+ 'liblzma (0BSD), SQLite (public domain) and OpenSSL 3.5 (Apache-2.0).',
352
+ 'Each of those carries its own licence, reproduced by its upstream.',
353
+ '',
354
+ ].join('\n');
355
+ }
356
+
357
+ function MPL_2_LICENSE_TEXT() {
358
+ // Mozilla Public License 2.0 — Pyodide is MPL-2.0-licensed. We
359
+ // ship an abbreviated header pointing at the canonical text; the
360
+ // LICENSE file lives next to the runtime install dir as a
361
+ // disclosure to the user.
362
+ return [
363
+ '==============================================================================',
364
+ 'Pyodide is licensed under the Mozilla Public License Version 2.0:',
365
+ '==============================================================================',
366
+ '',
367
+ 'Copyright (c) 2018-present Pyodide contributors.',
368
+ '',
369
+ 'Full license: https://www.mozilla.org/en-US/MPL/2.0/',
370
+ '',
371
+ 'Pyodide source: https://github.com/pyodide/pyodide',
372
+ 'Release tarball: https://cdn.jsdelivr.net/pyodide/v0.29.4/full/',
373
+ '',
374
+ 'Bundled in Nimbus for the `nimbus install python` runtime. Python',
375
+ 'itself is under the PSF License Agreement (https://docs.python.org/3/',
376
+ 'license.html); pyodide.asm.wasm contains CPython 3.13 + selected',
377
+ 'standard-library modules statically linked to wasm32-unknown-emscripten.',
378
+ '',
379
+ ].join('\n');
380
+ }
381
+
382
+ function APACHE_2_LLVM_LICENSE_TEXT() {
383
+ // Apache 2.0 with LLVM exception — abbreviated header pointing at
384
+ // the canonical upstream LICENSE.TXT. We don't redistribute the
385
+ // entire license verbatim here; the LICENSE file in the runtime
386
+ // install dir tells the user where to find the full text.
387
+ return [
388
+ '==============================================================================',
389
+ 'The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:',
390
+ '==============================================================================',
391
+ '',
392
+ 'Copyright (c) The LLVM Project authors.',
393
+ 'Copyright (c) Ben Smith (binji) and contributors to wasm-clang.',
394
+ '',
395
+ 'Full license: https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT',
396
+ '',
397
+ 'binji/wasm-clang source: https://github.com/binji/wasm-clang',
398
+ 'Original CppCon 2019 talk: https://www.youtube.com/watch?v=5N4b-rU-OAA',
399
+ '',
400
+ 'This artifact is a frozen build of LLVM 8.0 from 2018-2020. It is bundled',
401
+ 'in Nimbus under the original LLVM Apache 2.0 + LLVM Exception license.',
402
+ 'See the canonical LICENSE.TXT for the full text including the WebAssembly',
403
+ 'runtime exception clauses.',
404
+ '',
405
+ ].join('\n');
406
+ }
407
+
408
+ function RUBY_LICENSE_TEXT() {
409
+ // Ruby is dual-licensed under the Ruby License + BSD-2-Clause.
410
+ // ruby.wasm packaging adds MIT for the JS bindings (which we
411
+ // re-implement, so we don't redistribute their JS — only the wasm).
412
+ // The wasm itself carries: Ruby License + BSD-2-Clause for the
413
+ // interpreter, plus various permissive licenses for bundled gems
414
+ // and the C extensions in stdlib.
415
+ return [
416
+ '==============================================================================',
417
+ 'Ruby is dual-licensed under the Ruby License (2-clause variant) and BSD-2-Clause:',
418
+ '==============================================================================',
419
+ '',
420
+ 'Copyright (c) Yukihiro Matsumoto. All rights reserved.',
421
+ '',
422
+ 'Ruby License full text: https://www.ruby-lang.org/en/about/license.txt',
423
+ 'BSD-2-Clause full text: https://opensource.org/license/bsd-2-clause/',
424
+ '',
425
+ 'Ruby source: https://github.com/ruby/ruby',
426
+ 'ruby.wasm source: https://github.com/ruby/ruby.wasm',
427
+ 'Release tarball: https://registry.npmjs.org/@ruby/3.3-wasm-wasi/-/3.3-wasm-wasi-2.9.3-2.9.4.tgz',
428
+ '',
429
+ 'Bundled in Nimbus for the `nimbus install ruby` runtime. ruby+stdlib.wasm',
430
+ 'contains Ruby 3.3.x + the standard library packed via wasi-vfs, compiled',
431
+ 'to wasm32-unknown-wasi. The full Ruby standard library license list is in',
432
+ 'the upstream LEGAL file: https://github.com/ruby/ruby/blob/master/LEGAL.',
433
+ '',
434
+ ].join('\n');
435
+ }