@nimbus-sh/worker 0.8.0 → 0.10.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 (124) hide show
  1. package/dist/esbuild-wasm-bundle.generated.d.ts +24 -24
  2. package/dist/esbuild-wasm-bundle.generated.d.ts.map +1 -1
  3. package/dist/esbuild-wasm-bundle.generated.js +24 -24
  4. package/dist/facets/cirrus-real.js +3 -3
  5. package/dist/facets/compose.d.ts +3 -0
  6. package/dist/facets/compose.d.ts.map +1 -1
  7. package/dist/facets/compose.js +10 -3
  8. package/dist/facets/esbuild-bundle-pool.d.ts +1 -1
  9. package/dist/facets/esbuild-bundle-pool.js +3 -3
  10. package/dist/facets/esbuild-transform.d.ts +6 -2
  11. package/dist/facets/esbuild-transform.d.ts.map +1 -1
  12. package/dist/facets/esbuild-transform.js +8 -4
  13. package/dist/facets/manager.d.ts +54 -15
  14. package/dist/facets/manager.d.ts.map +1 -1
  15. package/dist/facets/manager.js +227 -144
  16. package/dist/facets/real-vite-hmr.d.ts +2 -0
  17. package/dist/facets/real-vite-hmr.d.ts.map +1 -1
  18. package/dist/facets/real-vite-hmr.js +3 -2
  19. package/dist/git/commands.d.ts +17 -1
  20. package/dist/git/commands.d.ts.map +1 -1
  21. package/dist/git/commands.js +73 -9
  22. package/dist/git/network-facet.d.ts +2 -0
  23. package/dist/git/network-facet.d.ts.map +1 -1
  24. package/dist/git/network-facet.js +10 -5
  25. package/dist/hosted/commands.d.ts.map +1 -1
  26. package/dist/hosted/commands.js +28 -39
  27. package/dist/hosted/runtime.d.ts +24 -2
  28. package/dist/hosted/runtime.d.ts.map +1 -1
  29. package/dist/hosted/runtime.js +70 -13
  30. package/dist/hosted/services.d.ts +14 -2
  31. package/dist/hosted/services.d.ts.map +1 -1
  32. package/dist/hosted/services.js +15 -2
  33. package/dist/loaders/generated-workers.d.ts +2 -2
  34. package/dist/loaders/generated-workers.d.ts.map +1 -1
  35. package/dist/loaders/generated-workers.js +4 -4
  36. package/dist/loaders/pre-bundle-preamble.d.ts +6 -3
  37. package/dist/loaders/pre-bundle-preamble.d.ts.map +1 -1
  38. package/dist/loaders/pre-bundle-preamble.js +13 -8
  39. package/dist/node-shims-artifact.generated.js +3 -3
  40. package/dist/npm/cache.d.ts +6 -1
  41. package/dist/npm/cache.d.ts.map +1 -1
  42. package/dist/npm/cache.js +8 -6
  43. package/dist/npm/install-batch-facet.d.ts +2 -0
  44. package/dist/npm/install-batch-facet.d.ts.map +1 -1
  45. package/dist/npm/install-batch-facet.js +29 -15
  46. package/dist/npm/installer.d.ts +8 -4
  47. package/dist/npm/installer.d.ts.map +1 -1
  48. package/dist/npm/installer.js +173 -113
  49. package/dist/npm/npx-install.d.ts +3 -1
  50. package/dist/npm/npx-install.d.ts.map +1 -1
  51. package/dist/npm/npx-install.js +4 -1
  52. package/dist/npm/placement.d.ts +16 -0
  53. package/dist/npm/placement.d.ts.map +1 -0
  54. package/dist/npm/placement.js +33 -0
  55. package/dist/npm/r2-cache.d.ts +10 -6
  56. package/dist/npm/r2-cache.d.ts.map +1 -1
  57. package/dist/npm/r2-cache.js +32 -16
  58. package/dist/npm/resolve-one-facet.d.ts +3 -0
  59. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  60. package/dist/npm/resolve-one-facet.js +1 -0
  61. package/dist/npm/resolver.d.ts +11 -6
  62. package/dist/npm/resolver.d.ts.map +1 -1
  63. package/dist/npm/resolver.js +12 -3
  64. package/dist/runtime/bash-repl.d.ts +5 -3
  65. package/dist/runtime/bash-repl.d.ts.map +1 -1
  66. package/dist/runtime/bash-repl.js +8 -3
  67. package/dist/runtime/cpython-resident.d.ts.map +1 -1
  68. package/dist/runtime/cpython-resident.js +2 -10
  69. package/dist/runtime/esbuild-wasm-bytes.d.ts +25 -18
  70. package/dist/runtime/esbuild-wasm-bytes.d.ts.map +1 -1
  71. package/dist/runtime/esbuild-wasm-bytes.js +55 -30
  72. package/dist/runtime/facet-loader-host.d.ts.map +1 -1
  73. package/dist/runtime/facet-loader-host.js +0 -9
  74. package/dist/runtime/node-shims.d.ts.map +1 -1
  75. package/dist/runtime/node-shims.js +853 -181
  76. package/dist/runtime/python-repl.d.ts +4 -3
  77. package/dist/runtime/python-repl.d.ts.map +1 -1
  78. package/dist/runtime/python-repl.js +10 -39
  79. package/dist/runtime/ruby-repl.d.ts +3 -2
  80. package/dist/runtime/ruby-repl.d.ts.map +1 -1
  81. package/dist/runtime/ruby-repl.js +7 -6
  82. package/dist/runtime/ruby-resident.d.ts.map +1 -1
  83. package/dist/runtime/ruby-resident.js +5 -16
  84. package/dist/runtime/runtime-catalog.js +1 -1
  85. package/dist/runtime/wasi/preamble.d.ts +0 -22
  86. package/dist/runtime/wasi/preamble.d.ts.map +1 -1
  87. package/dist/runtime/wasi/preamble.js +160 -1445
  88. package/dist/runtime-catalog.generated.js +1 -1
  89. package/dist/session/hibernation.d.ts +45 -2
  90. package/dist/session/hibernation.d.ts.map +1 -1
  91. package/dist/session/hibernation.js +78 -1
  92. package/dist/session/init.d.ts.map +1 -1
  93. package/dist/session/init.js +1 -0
  94. package/dist/session/nimbus-session.d.ts +16 -23
  95. package/dist/session/nimbus-session.d.ts.map +1 -1
  96. package/dist/session/nimbus-session.js +25 -36
  97. package/dist/session/npm-install-port.d.ts.map +1 -1
  98. package/dist/session/npm-install-port.js +1 -0
  99. package/dist/session/port-capability.d.ts.map +1 -1
  100. package/dist/session/port-capability.js +11 -1
  101. package/dist/session/programmatic.js +2 -2
  102. package/dist/session/routes.d.ts.map +1 -1
  103. package/dist/session/routes.js +4 -2
  104. package/dist/session/rpc.d.ts +7 -44
  105. package/dist/session/rpc.d.ts.map +1 -1
  106. package/dist/session/rpc.js +17 -67
  107. package/dist/session/supervisor-op.d.ts +8 -3
  108. package/dist/session/supervisor-op.d.ts.map +1 -1
  109. package/dist/session/supervisor-op.js +10 -45
  110. package/dist/session/supervisor-rpc.d.ts +47 -22
  111. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  112. package/dist/session/supervisor-rpc.js +64 -26
  113. package/dist/vfs/facet-resident-store.d.ts.map +1 -1
  114. package/dist/vfs/facet-resident-store.js +4 -2
  115. package/dist/workspace-host.d.ts +2 -1
  116. package/dist/workspace-host.d.ts.map +1 -1
  117. package/dist/wrangler/nimbus-wrangler.d.ts.map +1 -1
  118. package/dist/wrangler/nimbus-wrangler.js +3 -0
  119. package/package.json +30 -4
  120. package/public/_assets/esbuild-0.24.2.js +2380 -0
  121. package/public/_assets/runtime/{node-shims-8f8c64edd2a1f0f5.js → node-shims-7b4dd7a76d95d21e.js} +852 -180
  122. package/scripts/bundle-esbuild-wasm.mjs +55 -39
  123. package/scripts/bundle-facet-workers.mjs +45 -7
  124. package/scripts/bundle-runtime.mjs +35 -8
@@ -20,13 +20,14 @@ import type { Shell } from '@nimbus-sh/core/substrate/lifo/shell/Shell.js';
20
20
  * so `1 + 1` prints `2` and `x = 1` prints nothing, with no wrapper of ours
21
21
  * deciding what counts as a result.
22
22
  */
23
- import type { SqliteVFS } from '@nimbus-sh/core/vfs/sqlite-vfs.js';
24
23
  import type { FacetManager } from '../facets/manager.js';
25
24
  import type { WebSocketTerminal } from '../facets/ws-terminal.js';
26
25
  import type { RuntimeManifest } from '@nimbus-sh/core/runtime/runtime-manifest.js';
26
+ import { type NimbusFilesystemAuthority } from '@nimbus-sh/core/runtime/os-contracts.js';
27
27
  export interface PythonReplDeps {
28
28
  facetMgr: FacetManager;
29
- vfs: SqliteVFS;
29
+ /** Owns the installed interpreter blobs the prompt is booted from. */
30
+ authority: NimbusFilesystemAuthority;
30
31
  terminal: WebSocketTerminal;
31
32
  /** Per-user-VFS install dir, e.g. 'home/user/.nimbus/runtimes/cpython/3.13.14'. */
32
33
  installRoot: string;
@@ -58,5 +59,5 @@ export declare function runPythonRepl(deps: PythonReplDeps): Promise<number>;
58
59
  * Pay the interpreter's boot before the user asks for a prompt. Pushing empty
59
60
  * source compiles to a no-op, so the only thing it does is bring the facet up.
60
61
  */
61
- export declare function warmPythonRepl(deps: Pick<PythonReplDeps, 'facetMgr' | 'vfs' | 'installRoot' | 'manifest'>): Promise<void>;
62
+ export declare function warmPythonRepl(deps: Pick<PythonReplDeps, 'facetMgr' | 'authority' | 'installRoot' | 'manifest'>): Promise<void>;
62
63
  //# sourceMappingURL=python-repl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"python-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/python-repl.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,+CAA+C,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAoBnF,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACvC;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAySD,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAIzE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,KAAK,GAAG,aAAa,GAAG,UAAU,CAAC,GAC1E,OAAO,CAAC,IAAI,CAAC,CAIf"}
1
+ {"version":3,"file":"python-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/python-repl.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,+CAA+C,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAMnF,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AActG,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,YAAY,CAAC;IACvB,sEAAsE;IACtE,SAAS,EAAE,yBAAyB,CAAC;IACrC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,eAAe,CAAC;IAC1B;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACvC;;;;;;;;OAQG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAgRD,wBAAsB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAIzE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,UAAU,GAAG,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC,GAChF,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -1,5 +1,5 @@
1
1
  import { IsolatePool } from '@nimbus-sh/fabric/isolate-pool.js';
2
- import { manifestVfs } from '@nimbus-sh/core/runtime/vfs-manifest.js';
2
+ import { withHostFilesystem } from '@nimbus-sh/core/shell/execution-fs.js';
3
3
  import { z } from 'zod/v4';
4
4
  import { ReplSession } from './repl-session.js';
5
5
  import { sessionUsesSciVariant } from '@nimbus-sh/core/runtime/python-pip.js';
@@ -75,7 +75,6 @@ class PythonReplAdapter {
75
75
  poolUsesSci = false;
76
76
  deps;
77
77
  wasmBytes = null;
78
- fsSnapshot = null;
79
78
  pythonHome = '/usr/local';
80
79
  ps1 = '>>> ';
81
80
  ps2 = '... ';
@@ -150,7 +149,6 @@ class PythonReplAdapter {
150
149
  const pool = this.pool;
151
150
  this.pool = null;
152
151
  this.wasmBytes = null;
153
- this.fsSnapshot = null;
154
152
  pool?.dispose();
155
153
  }
156
154
  async interrupt() {
@@ -164,9 +162,11 @@ class PythonReplAdapter {
164
162
  }
165
163
  }
166
164
  async ensurePool() {
167
- const vfsForVariant = this.deps.vfs.as(CRED_KERNEL);
165
+ await withHostFilesystem(this.deps.authority, CRED_KERNEL, (vfs) => this.ensurePoolFrom(vfs));
166
+ }
167
+ async ensurePoolFrom(vfs) {
168
168
  const sciPath = `${this.deps.installRoot}/${CPYTHON_SCI_WASM_REL}`;
169
- const wantsSci = sessionUsesSciVariant(vfsForVariant) && vfsForVariant.exists(sciPath);
169
+ const wantsSci = (await sessionUsesSciVariant(vfs)) && (await vfs.exists(sciPath));
170
170
  // A prompt that was open before `pip install numpy` is holding the
171
171
  // interpreter that does not have it. Dropping the pool rebuilds on the next
172
172
  // statement, which is the facet restart EXTENSIONS.md says this costs.
@@ -177,35 +177,15 @@ class PythonReplAdapter {
177
177
  return;
178
178
  this.poolUsesSci = wantsSci;
179
179
  const { installRoot, facetMgr } = this.deps;
180
- const vfs = vfsForVariant;
181
180
  const wasmPath = wantsSci ? sciPath : `${installRoot}/${CPYTHON_WASM_REL}`;
182
181
  const stdlibPath = `${installRoot}/${CPYTHON_STDLIB_REL}`;
183
- if (!vfs.exists(wasmPath)) {
182
+ if (!(await vfs.exists(wasmPath))) {
184
183
  throw new Error(`python.wasm missing at ${wasmPath} (run 'nimbus install python')`);
185
184
  }
186
- if (!vfs.exists(stdlibPath)) {
185
+ if (!(await vfs.exists(stdlibPath))) {
187
186
  throw new Error(`python313.zip missing at ${stdlibPath} (run 'nimbus install python')`);
188
187
  }
189
- this.wasmBytes = toArrayBuffer(vfs.readFile(wasmPath));
190
- // The install root is the Python prefix, so the manifest covers lib/ and
191
- // etc/ as they are — nothing is aliased into a path the supervisor could
192
- // not serve.
193
- const built = manifestVfs(vfs, 'home/user', { extraRoots: [installRoot.replace(/^\/+/, '')] });
194
- if ('error' in built)
195
- throw new Error(built.error);
196
- // Same workaround as cpython-runner, and it belongs to the same open
197
- // defect: the guest cannot consume the stdlib as a manifest-only
198
- // demand-load, though the transport delivers it byte-identically. Seeding
199
- // it by value is what makes the interpreter start. Remove both together.
200
- const snapshot = built.snapshot;
201
- const zipBytes = vfs.readFile(stdlibPath);
202
- let bin = '';
203
- const CH = 32768;
204
- for (let i = 0; i < zipBytes.length; i += CH) {
205
- bin += String.fromCharCode.apply(null, Array.from(zipBytes.subarray(i, i + CH)));
206
- }
207
- snapshot.files[stdlibPath.replace(/^\/+/, '')] = btoa(bin);
208
- this.fsSnapshot = snapshot;
188
+ this.wasmBytes = toArrayBuffer(await vfs.readFile(wasmPath));
209
189
  this.pythonHome = `/${installRoot.replace(/^\/+/, '')}`;
210
190
  const host = getFacetManagerLoaderHost(facetMgr);
211
191
  // A prompt where `open(path, "w")` silently does nothing is worse than one
@@ -234,7 +214,7 @@ class PythonReplAdapter {
234
214
  active = null;
235
215
  async submit(userCode, signal) {
236
216
  const pool = this.pool;
237
- if (!pool || !this.fsSnapshot)
217
+ if (!pool)
238
218
  throw new Error('Python REPL is not initialized');
239
219
  const response = await pool.submitRequest(pythonReplStepRequestFn, new Request('https://facet.internal/python-repl-step', {
240
220
  method: 'POST',
@@ -245,7 +225,6 @@ class PythonReplAdapter {
245
225
  userEnv: { HOME: '/home/user', PYTHONUNBUFFERED: '1' },
246
226
  progName: 'python',
247
227
  cwd: '/home/user',
248
- fsSnapshot: this.fsSnapshot,
249
228
  }),
250
229
  signal,
251
230
  }), { timeoutMs: 60_000 });
@@ -279,7 +258,6 @@ async function pythonReplStepRequestFn(request, facetEnv) {
279
258
  });
280
259
  }
281
260
  const adopt = Reflect.get(globalThis, '__wasiAdoptSupervisor');
282
- const drain = Reflect.get(globalThis, '__wasiDrainPersist');
283
261
  const supervisor = facetEnv && facetEnv.SUPERVISOR;
284
262
  // Published where the boot re-adopts it after the mount, because
285
263
  // __wasiInitFS clears the adoption on purpose. Omitting this here — while
@@ -289,14 +267,7 @@ async function pythonReplStepRequestFn(request, facetEnv) {
289
267
  Reflect.set(globalThis, '__nimbusPySupervisor', supervisor);
290
268
  if (typeof adopt === 'function')
291
269
  Reflect.apply(adopt, undefined, [supervisor ?? null]);
292
- try {
293
- return Response.json(await run(args));
294
- }
295
- finally {
296
- // A line that wrote a file and then raised still wrote the file.
297
- if (typeof drain === 'function')
298
- await drain();
299
- }
270
+ return Response.json(await run(args));
300
271
  }
301
272
  export async function runPythonRepl(deps) {
302
273
  const adapter = new PythonReplAdapter(deps);
@@ -24,12 +24,13 @@
24
24
  * - Ctrl-C mid-execution.
25
25
  * - irb history pickling.
26
26
  */
27
- import type { SqliteVFS } from '@nimbus-sh/core/vfs/sqlite-vfs.js';
28
27
  import type { FacetManager } from '../facets/manager.js';
29
28
  import type { WebSocketTerminal } from '../facets/ws-terminal.js';
29
+ import { type NimbusFilesystemAuthority } from '@nimbus-sh/core/runtime/os-contracts.js';
30
30
  export interface RubyReplDeps {
31
31
  facetMgr: FacetManager;
32
- vfs: SqliteVFS;
32
+ /** Owns the installed interpreter blob the prompt is booted from. */
33
+ authority: NimbusFilesystemAuthority;
33
34
  terminal: WebSocketTerminal;
34
35
  /** Per-user-VFS install dir for the ruby blob. */
35
36
  installRoot: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ruby-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAMlE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,SAAS,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;CACrB;AA8MD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrE"}
1
+ {"version":3,"file":"ruby-repl.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-repl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,OAAO,EAAe,KAAK,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AAGtG,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,CAAC;IACvB,qEAAqE;IACrE,SAAS,EAAE,yBAAyB,CAAC;IACrC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;CACrB;AA8MD;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrE"}
@@ -27,6 +27,7 @@
27
27
  import { ReplSession } from './repl-session.js';
28
28
  import { buildRubyPreamble } from '@nimbus-sh/core/runtime/ruby-runner.js';
29
29
  import { CRED_KERNEL } from '@nimbus-sh/core/runtime/os-contracts.js';
30
+ import { withHostFilesystem } from '@nimbus-sh/core/shell/execution-fs.js';
30
31
  class RubyReplAdapter {
31
32
  pool = null;
32
33
  deps;
@@ -145,13 +146,13 @@ class RubyReplAdapter {
145
146
  if (this.pool)
146
147
  return;
147
148
  const { installRoot, facetMgr } = this.deps;
148
- const vfs = this.deps.vfs.as(CRED_KERNEL);
149
149
  const wasmPath = `${installRoot}/share/ruby/ruby+stdlib.wasm`;
150
- if (!vfs.exists(wasmPath)) {
151
- throw new Error(`ruby+stdlib.wasm missing at ${wasmPath} (run 'nimbus install ruby')`);
152
- }
153
- const wasmBytes = vfs.readFile(wasmPath);
154
- this.wasmBytesAB = toAB(wasmBytes);
150
+ this.wasmBytesAB = toAB(await withHostFilesystem(this.deps.authority, CRED_KERNEL, async (vfs) => {
151
+ if (!(await vfs.exists(wasmPath))) {
152
+ throw new Error(`ruby+stdlib.wasm missing at ${wasmPath} (run 'nimbus install ruby')`);
153
+ }
154
+ return vfs.readFile(wasmPath);
155
+ }));
155
156
  // The one canonical Ruby facet preamble. A hand-rolled copy here once
156
157
  // drifted (it lacked the language-prelude const __rubyRun requires, so
157
158
  // every REPL eval died on boot) — compose it in exactly one place.
@@ -1 +1 @@
1
- {"version":3,"file":"ruby-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAezD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,iBAAiB,CAgF3E;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiLrE"}
1
+ {"version":3,"file":"ruby-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAezD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,iBAAiB,CAgF3E;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsKrE"}
@@ -216,7 +216,6 @@ export function buildRubySocketProcessWorker(preamble) {
216
216
  ' userEnv: args.userEnv || {},',
217
217
  ' progName: args.progName || "ruby",',
218
218
  ' cwd: args.cwd || "/home/user",',
219
- ' fsSnapshot: args.fsSnapshot,',
220
219
  ' };',
221
220
  ' globalThis.__nimbusRubyProcessPromise = globalThis.__rubyRun(globalThis.__nimbusRubyProcessArgs).then((result) => {',
222
221
  ' globalThis.__nimbusRubyProcessResult = result;',
@@ -244,25 +243,15 @@ export function buildRubySocketProcessWorker(preamble) {
244
243
  'function __nimbusAdoptRubySupervisor(env) {',
245
244
  ' const supervisor = env && env.SUPERVISOR;',
246
245
  ' if (supervisor) globalThis.__nimbusRubySupervisor = supervisor;',
247
- // The WASI filesystem takes the same stub. That is what turns the
248
- // spawn-time seed into a cache over the session VFS, so a server that
249
- // never exits still persists its writes instead of losing them entirely.
246
+ // The WASI filesystem takes the same stub: every file syscall the server
247
+ // makes reads and writes the session VFS directly, so a server that never
248
+ // exits has nothing to flush between requests.
250
249
  ' __wasiAdoptSupervisor(supervisor);',
251
250
  '}',
252
- // A resident process parks between requests, and parking is the only
253
- // moment "durable while running" can be made true: by the time the caller
254
- // holds a response, everything the request wrote has reached the VFS.
255
- 'async function __nimbusParkRuby(value) {',
256
- // Revalidate drains first, then spends ONE round trip on the subtree
257
- // revision. An unchanged subtree keeps the whole cache; a changed one
258
- // drops the clean half so the next read sees another process's writes.
259
- ' await __wasiRevalidateFS();',
260
- ' return value;',
261
- '}',
262
251
  'export class NimbusProcess extends DurableObject {',
263
252
  ' async startProcess(args) {',
264
253
  ' __nimbusAdoptRubySupervisor(this.env);',
265
- ' return __nimbusParkRuby(await __nimbusStartRubyProcess(args || {}));',
254
+ ' return __nimbusStartRubyProcess(args || {});',
266
255
  ' }',
267
256
  ' async fetch(request) {',
268
257
  ' __nimbusAdoptRubySupervisor(this.env);',
@@ -273,7 +262,7 @@ export function buildRubySocketProcessWorker(preamble) {
273
262
  ' const hinted = Number(request.headers.get("X-Nimbus-Port") || 0);',
274
263
  ' const port = hinted || Array.from(globalThis.__nimbusVirtualSockets.listeners.keys())[0];',
275
264
  ' if (!port) return new Response("Nimbus Ruby process has no listening virtual socket", { status: 502 });',
276
- ' return __nimbusParkRuby(await globalThis.__nimbusVirtualSockets.handleHttpRequest(port, request));',
265
+ ' return globalThis.__nimbusVirtualSockets.handleHttpRequest(port, request);',
277
266
  ' }',
278
267
  '}',
279
268
  ].join('\n');
@@ -218,8 +218,8 @@ export function runtimeCatalogSource(env) {
218
218
  name,
219
219
  abi: runtimeAbiForCatalogName(name),
220
220
  defaultVersion: entry.default,
221
+ // The publisher appends; the catalog's own order is publish order.
221
222
  versions: Object.entries(entry.versions)
222
- .sort(([a], [b]) => a.localeCompare(b))
223
223
  .map(([version, v]) => ({
224
224
  version,
225
225
  sizeBytes: v.size_bytes,
@@ -1,28 +1,6 @@
1
1
  import type { FdEntry, WasiInitOptions, WasiInstanceBundle, WasiMakeImportsOptions, WasiRunResult, WasiStartInstance, WasiSupervisorStub } from '@nimbus-sh/core/runtime/wasi/types.js';
2
2
  export declare function __wasiAdoptSupervisor(sup: WasiSupervisorStub | null): void;
3
- /**
4
- * Re-sync the cache with the session VFS. A resident process (a server) must
5
- * see files that other processes created or changed after it spawned, so the
6
- * cached content is dropped and metadata re-read on next access.
7
- */
8
- export declare function __wasiRevalidateFS(): Promise<string[]>;
9
- /**
10
- * Await every queued mutation. Callers drain before returning a result to the
11
- * supervisor and before any live read, so the supervisor's view always
12
- * includes this process's own writes.
13
- */
14
- export declare function __wasiDrainPersist(): Promise<void>;
15
3
  export declare function __wasiInitFS(opts: WasiInitOptions): void;
16
- /**
17
- * Read named files back out as base64.
18
- *
19
- * A process with a supervisor has already written everything through as it
20
- * happened and never calls this. A SEALED one — no supervisor, by design,
21
- * because it must not be able to reach the session VFS at all — has no other
22
- * channel, so its caller names the paths it wants and gets exactly those.
23
- * A path with no file is simply absent from the result.
24
- */
25
- export declare function __wasiReadFilesB64(paths: string[]): Record<string, string>;
26
4
  export declare const fdTable: Map<number, FdEntry>;
27
5
  export declare function __wasiMakeImports(opts: WasiMakeImportsOptions): WasiInstanceBundle;
28
6
  export declare function __wasiRunStart(instance: WasiStartInstance, ctx?: unknown): WasiRunResult;
@@ -1 +1 @@
1
- {"version":3,"file":"preamble.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi/preamble.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAGV,OAAO,EAOP,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EAGtB,aAAa,EAEb,iBAAiB,EACjB,kBAAkB,EAInB,MAAM,uCAAuC,CAAC;AAwL/C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAE1E;AAsHD;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAgB5D;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAOxD;AA+CD,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAkGxD;AAgPD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc1E;AAeD,eAAO,MAAM,OAAO,sBAA6B,CAAC;AAiMlD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,kBAAkB,CAwwDlF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,aAAa,CAcxF;AAeD,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAyB5G"}
1
+ {"version":3,"file":"preamble.d.ts","sourceRoot":"","sources":["../../../src/runtime/wasi/preamble.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAEV,OAAO,EAMP,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EAGtB,aAAa,EAEb,iBAAiB,EACjB,kBAAkB,EAInB,MAAM,uCAAuC,CAAC;AAmJ/C,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAE1E;AAiBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA0BxD;AAwOD,eAAO,MAAM,OAAO,sBAA6B,CAAC;AAsElD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,kBAAkB,CAikClF;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,aAAa,CAcxF;AAeD,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CAyB5G"}