@nimbus-sh/worker 0.8.0 → 0.9.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 (59) hide show
  1. package/dist/facets/compose.d.ts +3 -0
  2. package/dist/facets/compose.d.ts.map +1 -1
  3. package/dist/facets/compose.js +1 -1
  4. package/dist/facets/manager.d.ts +26 -15
  5. package/dist/facets/manager.d.ts.map +1 -1
  6. package/dist/facets/manager.js +138 -107
  7. package/dist/hosted/commands.d.ts.map +1 -1
  8. package/dist/hosted/commands.js +27 -38
  9. package/dist/hosted/runtime.d.ts +22 -1
  10. package/dist/hosted/runtime.d.ts.map +1 -1
  11. package/dist/hosted/runtime.js +69 -13
  12. package/dist/hosted/services.d.ts +6 -2
  13. package/dist/hosted/services.d.ts.map +1 -1
  14. package/dist/hosted/services.js +12 -2
  15. package/dist/loaders/generated-workers.d.ts +1 -1
  16. package/dist/loaders/generated-workers.d.ts.map +1 -1
  17. package/dist/loaders/generated-workers.js +2 -2
  18. package/dist/node-shims-artifact.generated.js +3 -3
  19. package/dist/runtime/bash-repl.d.ts +5 -3
  20. package/dist/runtime/bash-repl.d.ts.map +1 -1
  21. package/dist/runtime/bash-repl.js +8 -3
  22. package/dist/runtime/facet-loader-host.d.ts.map +1 -1
  23. package/dist/runtime/facet-loader-host.js +1 -3
  24. package/dist/runtime/node-shims.d.ts.map +1 -1
  25. package/dist/runtime/node-shims.js +14 -1
  26. package/dist/runtime/python-repl.d.ts +4 -3
  27. package/dist/runtime/python-repl.d.ts.map +1 -1
  28. package/dist/runtime/python-repl.js +10 -8
  29. package/dist/runtime/ruby-repl.d.ts +3 -2
  30. package/dist/runtime/ruby-repl.d.ts.map +1 -1
  31. package/dist/runtime/ruby-repl.js +7 -6
  32. package/dist/runtime/runtime-catalog.js +1 -1
  33. package/dist/runtime/wasi/preamble.d.ts.map +1 -1
  34. package/dist/runtime/wasi/preamble.js +74 -56
  35. package/dist/runtime-catalog.generated.js +1 -1
  36. package/dist/session/init.d.ts.map +1 -1
  37. package/dist/session/init.js +1 -0
  38. package/dist/session/nimbus-session.d.ts +6 -21
  39. package/dist/session/nimbus-session.d.ts.map +1 -1
  40. package/dist/session/nimbus-session.js +12 -35
  41. package/dist/session/port-capability.d.ts.map +1 -1
  42. package/dist/session/port-capability.js +11 -1
  43. package/dist/session/programmatic.js +2 -2
  44. package/dist/session/rpc.d.ts +3 -43
  45. package/dist/session/rpc.d.ts.map +1 -1
  46. package/dist/session/rpc.js +7 -65
  47. package/dist/session/supervisor-op.d.ts +8 -3
  48. package/dist/session/supervisor-op.d.ts.map +1 -1
  49. package/dist/session/supervisor-op.js +10 -45
  50. package/dist/session/supervisor-rpc.d.ts +33 -16
  51. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  52. package/dist/session/supervisor-rpc.js +49 -4
  53. package/dist/vfs/facet-resident-store.d.ts.map +1 -1
  54. package/dist/vfs/facet-resident-store.js +4 -2
  55. package/dist/workspace-host.d.ts +2 -1
  56. package/dist/workspace-host.d.ts.map +1 -1
  57. package/package.json +4 -4
  58. package/public/_assets/runtime/{node-shims-8f8c64edd2a1f0f5.js → node-shims-acaa037e6d26ec0d.js} +14 -1
  59. package/scripts/bundle-runtime.mjs +35 -8
@@ -151,8 +151,8 @@ export class SupervisorRPC extends WorkerEntrypoint {
151
151
  // Uint8Array transparently; downstream _rpcWriteFile also accepts
152
152
  return this._call(this._fsOp('writeFile', [path, content]));
153
153
  }
154
- async stat(path) {
155
- return this._call(this._fsOp('stat', [path]));
154
+ async stat(path, options) {
155
+ return this._call(this._fsOp('stat', [path, options]));
156
156
  }
157
157
  async lstat(path) {
158
158
  return this._call(this._fsOp('lstat', [path]));
@@ -181,8 +181,8 @@ export class SupervisorRPC extends WorkerEntrypoint {
181
181
  async exists(path) {
182
182
  return this._call(this._fsOp('exists', [path]));
183
183
  }
184
- async mkdir(path) {
185
- return this._call(this._fsOp('mkdir', [path]));
184
+ async mkdir(path, options) {
185
+ return this._call(this._fsOp('mkdir', [path, options]));
186
186
  }
187
187
  async rmdir(path) {
188
188
  return this._call(this._fsOp('rmdir', [path]));
@@ -265,6 +265,51 @@ export class SupervisorRPC extends WorkerEntrypoint {
265
265
  async fsWrite(handleId, offset, bytes) {
266
266
  return this._call(this._fsOp('fsWrite', [handleId, offset, bytes]));
267
267
  }
268
+ async fsFstat(...args) {
269
+ return this._call(this._fsOp('fsFstat', args));
270
+ }
271
+ async fsDup(...args) {
272
+ return this._call(this._fsOp('fsDup', args));
273
+ }
274
+ async fsSeek(...args) {
275
+ return this._call(this._fsOp('fsSeek', args));
276
+ }
277
+ async fsSetStatus(...args) {
278
+ return this._call(this._fsOp('fsSetStatus', args));
279
+ }
280
+ async fsReaddirHandle(...args) {
281
+ return this._call(this._fsOp('fsReaddirHandle', args));
282
+ }
283
+ async fsFtruncate(...args) {
284
+ return this._call(this._fsOp('fsFtruncate', args));
285
+ }
286
+ async fsFchmod(...args) {
287
+ return this._call(this._fsOp('fsFchmod', args));
288
+ }
289
+ async fsFchown(...args) {
290
+ return this._call(this._fsOp('fsFchown', args));
291
+ }
292
+ async fsFutimes(...args) {
293
+ return this._call(this._fsOp('fsFutimes', args));
294
+ }
295
+ async fsSync(...args) {
296
+ return this._call(this._fsOp('fsSync', args));
297
+ }
298
+ async fsRealpath(...args) {
299
+ return this._call(this._fsOp('fsRealpath', args));
300
+ }
301
+ async fsRemove(...args) {
302
+ return this._call(this._fsOp('fsRemove', args));
303
+ }
304
+ async fsCopyFile(...args) {
305
+ return this._call(this._fsOp('fsCopyFile', args));
306
+ }
307
+ async fsAcquireExclusiveMutation(...args) {
308
+ return this._call(this._fsOp('fsAcquireExclusiveMutation', args));
309
+ }
310
+ async fsReleaseExclusiveMutation(...args) {
311
+ return this._call(this._fsOp('fsReleaseExclusiveMutation', args));
312
+ }
268
313
  async fsClose(handleId) {
269
314
  return this._call(this._fsOp('fsClose', [handleId]));
270
315
  }
@@ -1 +1 @@
1
- {"version":3,"file":"facet-resident-store.d.ts","sourceRoot":"","sources":["../../src/vfs/facet-resident-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqLG;AAQH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,OAA2B,CAAC;AAClE,eAAO,MAAM,yBAAyB,QAA8B,CAAC;AAErE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,QAk3BhC,CAAC;AAET,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE"}
1
+ {"version":3,"file":"facet-resident-store.d.ts","sourceRoot":"","sources":["../../src/vfs/facet-resident-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqLG;AAQH;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAE9C;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,OAA2B,CAAC;AAClE,eAAO,MAAM,yBAAyB,QAA8B,CAAC;AAErE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,2BAA2B,QAo3BhC,CAAC;AAET,iFAAiF;AACjF,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAErE;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CACjE"}
@@ -795,7 +795,7 @@ async function __residentEnumerate(supervisor) {
795
795
  if (!Number.isSafeInteger(size) || size < 0 || !Number.isSafeInteger(rev) || rev < 0) {
796
796
  throw new Error("Nimbus: fsList returned unusable metadata for '" + path + "'");
797
797
  }
798
- entries.push({ path, size, rev });
798
+ entries.push({ path, size, rev, epoch: cursor.epoch });
799
799
  }
800
800
  if (listed.next === null || listed.next === undefined) {
801
801
  return { entries, cursor, complete: true, reason: null };
@@ -844,6 +844,7 @@ async function __residentFetchFiles(supervisor, files) {
844
844
  ranges.push({
845
845
  path: file.path,
846
846
  rev: file.rev,
847
+ epoch: file.epoch,
847
848
  part,
848
849
  parts,
849
850
  offset,
@@ -874,7 +875,7 @@ async function __residentFetchFiles(supervisor, files) {
874
875
  let results;
875
876
  try {
876
877
  results = await supervisor.fsReadBatch(
877
- batch.map((r) => ({ path: r.path, offset: r.offset, length: r.length }))
878
+ batch.map((r) => ({ path: r.path, offset: r.offset, length: r.length, expectedEpoch: r.epoch, expectedRevision: r.rev }))
878
879
  );
879
880
  } catch {
880
881
  for (const r of batch) failedPaths.add(r.path);
@@ -896,6 +897,7 @@ async function __residentFetchFiles(supervisor, files) {
896
897
  }
897
898
  if (entry.bytes === null || entry.bytes === undefined) { failedPaths.add(range.path); continue; }
898
899
  const chunk = __residentBytes(entry.bytes);
900
+ if (chunk.byteLength !== range.length) { failedPaths.add(range.path); continue; }
899
901
  fetchedBytes += chunk.byteLength;
900
902
  __residentPutChunk(__residentSql, range.path, range.part, chunk);
901
903
  const seen = (landed.get(range.path) || 0) + 1;
@@ -1,4 +1,5 @@
1
- export { composeFacetManager, type FacetManagerDeps, type ComposedFacetManager } from './facets/compose.js';
1
+ export { composeFacetManager, type FacetManagerDeps, type FacetManagerHostHooks, type ComposedFacetManager } from './facets/compose.js';
2
+ export type { WorkerRecipe, ResolvedWorkerLaunch } from './facets/manager.js';
2
3
  export { composeHostedRuntime, type HostedRuntime, type HostedRuntimeOptions, type HostedRuntimeLifecycle, type HostedRuntimeTask, type RuntimeFiles } from './hosted/runtime.js';
3
4
  export { runtimeCatalogSource } from './runtime/runtime-catalog.js';
4
5
  export { SupervisorRPC } from './session/supervisor-rpc.js';
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-host.d.ts","sourceRoot":"","sources":["../src/workspace-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC5G,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClL,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"workspace-host.d.ts","sourceRoot":"","sources":["../src/workspace-host.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxI,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAClL,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimbus-sh/worker",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Nimbus runtime package for Cloudflare Workers, re-exported publicly through @nimbus-sh/sdk/worker.",
5
5
  "keywords": [
6
6
  "cloudflare",
@@ -109,9 +109,9 @@
109
109
  },
110
110
  "dependencies": {
111
111
  "@ai-sdk/openai-compatible": "^2.0.41",
112
- "@nimbus-sh/core": "^0.10.0",
113
- "@nimbus-sh/fabric": "^0.6.0",
114
- "@nimbus-sh/platform": "^0.4.0",
112
+ "@nimbus-sh/core": "^0.11.0",
113
+ "@nimbus-sh/fabric": "^0.7.0",
114
+ "@nimbus-sh/platform": "^0.5.0",
115
115
  "@renovatebot/pep440": "^5.0.0",
116
116
  "ai": "^6.0.182",
117
117
  "clean-git-ref": "^2.0.1",
@@ -7712,7 +7712,20 @@ builtins.tty = {
7712
7712
  // core and must not be reported as such — a package that sniffs this list
7713
7713
  // would otherwise conclude e.g. undici ships with node.
7714
7714
  const __nimbusFacetProvidedPackages = new Set(["undici"]);
7715
- builtins.module = { get builtinModules() { return Object.keys(builtins).filter((n) => !__nimbusFacetProvidedPackages.has(n)); }, createRequire: (specifier) => __makeRequire(__requireBaseDir(specifier)), _resolveFilename: (id) => id, _cache: {} };
7715
+ builtins.module = {
7716
+ get builtinModules() { return Object.keys(builtins).filter((n) => !__nimbusFacetProvidedPackages.has(n)); },
7717
+ createRequire: (specifier) => __makeRequire(__requireBaseDir(specifier)),
7718
+ isBuiltin: (specifier) => Object.hasOwn(builtins, String(specifier).replace(/^node:/, '')) && !__nimbusFacetProvidedPackages.has(String(specifier).replace(/^node:/, '')),
7719
+ // Node 22.1's on-disk compile cache. There is no disk to cache into and
7720
+ // nothing to compile ahead: callers (pi's CLI entry calls it
7721
+ // unconditionally) get Node's own answer for a cache that is off.
7722
+ enableCompileCache: () => ({ status: 3, message: 'compile cache is not available in this runtime' }),
7723
+ getCompileCacheDir: () => undefined,
7724
+ flushCompileCache: () => {},
7725
+ constants: { compileCacheStatus: { FAILED: 0, ENABLED: 1, ALREADY_ENABLED: 2, DISABLED: 3 } },
7726
+ _resolveFilename: (id) => id,
7727
+ _cache: {},
7728
+ };
7716
7729
  // Bind to globalThis: workerd's timer globals throw "Illegal invocation"
7717
7730
  // when called with a receiver other than globalThis (i.e. as
7718
7731
  // timers.setInterval(...)), which clack's spinner — used by
@@ -7,7 +7,7 @@
7
7
  * node scripts/bundle-runtime.mjs clang binji-2020 [--bucket nimbus-runtime-cache]
8
8
  * node scripts/bundle-runtime.mjs python 0.29.4 [--bucket nimbus-runtime-cache]
9
9
  * node scripts/bundle-runtime.mjs --pin-catalog (read-only; publishes nothing)
10
- * node scripts/bundle-runtime.mjs bash 5.2.37 --npm-package <dir> (local; no R2)
10
+ * node scripts/bundle-runtime.mjs bash 5.2.37-2 --npm-package <dir> (local; no R2)
11
11
  *
12
12
  * `--npm-package` is the SECOND publisher for the same artifacts: it stages
13
13
  * exactly what the R2 path stages, composes the same manifest bytes, and lays
@@ -50,6 +50,7 @@ import { mkdirSync, readFileSync, writeFileSync, existsSync, rmSync, openSync, c
50
50
  import { execFileSync, execSync, spawnSync } from 'node:child_process';
51
51
  import { tmpdir } from 'node:os';
52
52
  import { basename, dirname, join } from 'node:path';
53
+ import { BASH_RUNNER } from '@nimbus-sh/core/runtime/os-contracts.js';
53
54
 
54
55
  const ACCOUNT = process.env.CLOUDFLARE_ACCOUNT_ID;
55
56
  // Resolve the wrangler bin from either the package-local or the
@@ -64,9 +65,14 @@ const PYODIDE_WORKERD_ADAPTER = JSON.parse(
64
65
  );
65
66
 
66
67
  const USAGE =
67
- 'usage: bundle-runtime.mjs <name> <version> [--bucket <bucket>]\n' +
68
+ 'usage: bundle-runtime.mjs <name> <version> [--bucket <bucket>] [--keep-default]\n' +
68
69
  ' bundle-runtime.mjs <name> <version> --npm-package <dir>\n' +
69
- ' bundle-runtime.mjs --pin-catalog [--bucket <bucket>]';
70
+ ' bundle-runtime.mjs --pin-catalog [--bucket <bucket>]\n' +
71
+ '\n' +
72
+ ' --keep-default add the version to the catalog without making it the\n' +
73
+ ' default: for a build whose runner contract a deployment\n' +
74
+ ' still reading the catalog cannot bind yet. Re-run without\n' +
75
+ ' the flag once every deployment can; the re-run is idempotent.';
70
76
 
71
77
  /** The bucket the deployed Worker's NIMBUS_RUNTIME_CACHE binding points at.
72
78
  * Only a publish to THIS bucket may rewrite the catalog pin: the pin
@@ -78,6 +84,7 @@ const rawArgs = process.argv.slice(2);
78
84
  const positionalArgs = [];
79
85
  let BUCKET = process.env.NIMBUS_RUNTIME_BUCKET || PRODUCTION_BUCKET;
80
86
  let PIN_ONLY = false;
87
+ let KEEP_DEFAULT = false;
81
88
  let NPM_OUT_DIR = null;
82
89
  for (let i = 0; i < rawArgs.length; i++) {
83
90
  const arg = rawArgs[i];
@@ -85,6 +92,10 @@ for (let i = 0; i < rawArgs.length; i++) {
85
92
  PIN_ONLY = true;
86
93
  continue;
87
94
  }
95
+ if (arg === '--keep-default') {
96
+ KEEP_DEFAULT = true;
97
+ continue;
98
+ }
88
99
  if (arg === '--npm-package') {
89
100
  NPM_OUT_DIR = rawArgs[++i];
90
101
  if (!NPM_OUT_DIR) {
@@ -226,10 +237,16 @@ const SPECS = {
226
237
  // `local_base`. The bash-runner aliases every applet name in
227
238
  // busybox.applets onto the busybox module so bash's PATH lookup finds
228
239
  // them in /bin and /usr/bin.
229
- 'bash/5.2.37': {
240
+ //
241
+ // The version is `<upstream>-<build>`: the build number advances with
242
+ // every rebuild, and the entrypoint names the runner contract the build
243
+ // was made for (BASH_RUNNER), so a deployment whose preamble predates it
244
+ // never binds it. 5.2.37 is build 1, published under `bash-runner`.
245
+ 'bash/5.2.37-2': {
230
246
  license: 'GPL-3.0-or-later AND GPL-2.0-only',
231
247
  wasi_namespace: 'wasi_snapshot_preview1',
232
248
  local_base: '../wasm/bash',
249
+ auxiliary_bins: 'coreutils/busybox.applets',
233
250
  npm: {
234
251
  name: '@nimbus-sh/runtime-bash',
235
252
  summary: 'GNU bash 5.2.37 and BusyBox 1.37.0, cross-compiled to wasm32-wasi',
@@ -238,7 +255,7 @@ const SPECS = {
238
255
  { src: 'bash.async.wasm', vfs: 'share/bash/bash.async.wasm' },
239
256
  { src: 'coreutils/busybox.wasm', vfs: 'share/bash/coreutils/busybox.wasm' },
240
257
  { src: 'coreutils/busybox.applets', vfs: 'share/bash/coreutils/busybox.applets' },
241
- { src: 'BIN_MARKER', vfs: 'bin/bash', mode: 'exec', runner: 'bash-runner', binName: 'bash' },
258
+ { src: 'BIN_MARKER', vfs: 'bin/bash', mode: 'exec', runner: BASH_RUNNER, binName: 'bash' },
242
259
  ],
243
260
  synthetic_files: {
244
261
  'BIN_MARKER': Buffer.from(
@@ -427,6 +444,15 @@ if (!spec) {
427
444
  console.error(`known: ${Object.keys(SPECS).join(', ')}`);
428
445
  process.exit(2);
429
446
  }
447
+ if (spec.auxiliary_bins) {
448
+ const list = new URL(`${spec.local_base}/${spec.auxiliary_bins}`, import.meta.url);
449
+ const names = readFileSync(list, 'utf8').split('\n').filter(Boolean);
450
+ spec.synthetic_files.NIMBUS_AUX_BIN = Buffer.from('Nimbus WASI multicall entry\n');
451
+ for (const name of names) {
452
+ if (name.includes('/') || name === '.' || name === '..') throw new Error(`Invalid multicall entry: ${name}`);
453
+ spec.files.push({ src: 'NIMBUS_AUX_BIN', vfs: `bin/${name}`, mode: 'exec' });
454
+ }
455
+ }
430
456
  // Checked before anything is staged: which runtimes we publish to npm is a
431
457
  // decision, and a spec that has not made it should cost nothing to find out.
432
458
  if (NPM_OUT_DIR) {
@@ -617,8 +643,9 @@ if (spec.ingest_only) {
617
643
  license: spec.license,
618
644
  };
619
645
  // Update default to the just-uploaded version (idempotent — if it was
620
- // already the default, no-op).
621
- catalog.runtimes[RUNTIME].default = VERSION;
646
+ // already the default, no-op), unless the publisher asked to hold it for
647
+ // deployments that cannot bind this build yet.
648
+ if (!KEEP_DEFAULT) catalog.runtimes[RUNTIME].default = VERSION;
622
649
 
623
650
  // The catalog indexes every runtime, so an update that drops one is a
624
651
  // publish that unregisters somebody else's. Cheap to assert, and it catches
@@ -644,7 +671,7 @@ if (spec.ingest_only) {
644
671
  console.log(`\n[bundle-runtime] DONE`);
645
672
  console.log(`[bundle-runtime] uploaded ${downloaded.length} files (${totalMb} MiB) for ${RUNTIME}@${VERSION}`);
646
673
  console.log(`[bundle-runtime] manifest: r2://${BUCKET}/${manifestR2Key}`);
647
- console.log(`[bundle-runtime] catalog: r2://${BUCKET}/${catalogR2Key}`);
674
+ console.log(`[bundle-runtime] catalog: r2://${BUCKET}/${catalogR2Key} (default ${catalog.runtimes[RUNTIME].default})`);
648
675
  }
649
676
 
650
677
  /**