@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
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/hosted/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAsB5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGvE,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,EACnD,oBAAoB,GAAG,gBAAgB,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAAc,GAAG,WAAW,GAAG,iBAAiB,GAAG,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,0BAA0B,CAClV,GAAG;IACF,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,sBAAsB,EAAE,eAAe,CAAC,wBAAwB,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA2rDhH"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/hosted/commands.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAuB5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGvE,oFAAoF;AACpF,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,EACnD,oBAAoB,GAAG,gBAAgB,GAAG,cAAc,GAAG,eAAe,GAAG,YAAY,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAAc,GAAG,WAAW,GAAG,iBAAiB,GAAG,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,0BAA0B,CAClV,GAAG;IACF,QAAQ,CAAC,GAAG,EAAE,kBAAkB,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,iBAAiB,CAAC;IAChC,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,sBAAsB,EAAE,eAAe,CAAC,wBAAwB,CAAC,CAAC;CACnE,CAAC;AAEF,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,kBAAkB,EAAE,SAAS,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6qDhH"}
@@ -1,7 +1,8 @@
1
1
  import { Shell, createCurlCommand, createNpmCommand, NPM_VERSION, createTopCommand, createWatchCommand, createHelpCommand, rehydrateGlobalPackages } from '@nimbus-sh/core/substrate/lifo/index.js';
2
2
  import { createKillCommand } from '@nimbus-sh/core/substrate/lifo/commands/system/kill.js';
3
3
  import { textSink } from '@nimbus-sh/core/_shared/bytes.js';
4
- import { CRED_KERNEL, requireVfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
4
+ import { BASH_RUNNER, CRED_KERNEL, requireVfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
5
+ import { ExecutionFs } from '@nimbus-sh/core/shell/execution-fs.js';
5
6
  import { EsbuildService } from '@nimbus-sh/core/runtime/esbuild-service.js';
6
7
  import { runFresh } from '../runtime/node-runner.js';
7
8
  import { runBunScript, BUN_VERSION } from '../runtime/bun-runner.js';
@@ -45,7 +46,7 @@ export async function registerHostedCommands(self, workspace) {
45
46
  });
46
47
  self._setCpRegistry(registry);
47
48
  registry.register('chsh', makeChshCommand({
48
- isBashInstalled: (home) => listInstalledRuntimes(sqliteFs, home).some((runtime) => runtime.name === 'bash'),
49
+ isBashInstalled: async (home) => (await listInstalledRuntimes(sqliteFs, home)).some((runtime) => runtime.name === 'bash'),
49
50
  }));
50
51
  // ── Git integration (isomorphic-git) ──
51
52
  // ctx + env are passed for clone/fetch/pull which run in a facet to avoid
@@ -67,7 +68,7 @@ export async function registerHostedCommands(self, workspace) {
67
68
  workspace.runtimes.registerRunner('clang-runner', (manifest, installRoot, binName, binKind) => async (ctx) => {
68
69
  const { makeClangRunnerFactory } = await import('@nimbus-sh/core/runtime/clang-runner.js');
69
70
  const { facetHostForManager } = await import('../runtime/facet-loader-host.js');
70
- return await makeClangRunnerFactory({ facets: facetHostForManager(facetMgr), vfs: sqliteFs })(manifest, installRoot, binName, binKind)(ctx);
71
+ return await makeClangRunnerFactory({ facets: facetHostForManager(facetMgr), filesystem: workspace.filesystem })(manifest, installRoot, binName, binKind)(ctx);
71
72
  });
72
73
  // Pyodide v1 — Python 3.13 via the same R2-package-manager
73
74
  // substrate that ships clang. Manifest entrypoints `python` and
@@ -88,7 +89,7 @@ export async function registerHostedCommands(self, workspace) {
88
89
  const { runPythonRepl } = await import('../runtime/python-repl.js');
89
90
  return await runPythonRepl({
90
91
  facetMgr,
91
- vfs: sqliteFs,
92
+ authority: workspace.filesystem,
92
93
  terminal: terminal,
93
94
  installRoot,
94
95
  manifest,
@@ -108,7 +109,6 @@ export async function registerHostedCommands(self, workspace) {
108
109
  const { cpythonResidentStart } = await import('../runtime/cpython-resident.js');
109
110
  return await makeCPythonRunnerFactory({
110
111
  facets: facetHostForManager(facetMgr),
111
- vfs: sqliteFs,
112
112
  startResident: cpythonResidentStart(facetMgr),
113
113
  })(manifest, installRoot, binName, binKind)(ctx);
114
114
  });
@@ -127,7 +127,7 @@ export async function registerHostedCommands(self, workspace) {
127
127
  const { runRubyRepl } = await import('../runtime/ruby-repl.js');
128
128
  return await runRubyRepl({
129
129
  facetMgr,
130
- vfs: sqliteFs,
130
+ authority: workspace.filesystem,
131
131
  terminal: terminal,
132
132
  installRoot,
133
133
  });
@@ -135,19 +135,20 @@ export async function registerHostedCommands(self, workspace) {
135
135
  const { makeRubyRunnerFactory } = await import('@nimbus-sh/core/runtime/ruby-runner.js');
136
136
  const { facetHostForManager } = await import('../runtime/facet-loader-host.js');
137
137
  const { rubyResidentStart } = await import('../runtime/ruby-resident.js');
138
- return await makeRubyRunnerFactory({
138
+ const runner = await makeRubyRunnerFactory({
139
139
  facets: facetHostForManager(facetMgr),
140
- vfs: sqliteFs,
140
+ filesystem: workspace.filesystem,
141
141
  registry,
142
142
  startResident: rubyResidentStart(facetMgr),
143
- })(manifest, installRoot, binName, binKind)(ctx);
143
+ })(manifest, installRoot, binName, binKind);
144
+ return runner(ctx);
144
145
  });
145
146
  // GNU bash 5.2.37 (wasm32-wasi, asyncified) — dedicated facet
146
147
  // runner driving the fork/pipe/exec/setjmp scheduler (fork M1-M3
147
148
  // mechanisms). Interactive terminal invocations use the shared
148
149
  // ReplSession line editor; -c, scripts, and piped stdin retain the
149
150
  // canonical one-shot handler.
150
- workspace.runtimes.registerRunner('bash-runner', (manifest, installRoot, binName, binKind) => async (ctx) => {
151
+ workspace.runtimes.registerRunner(BASH_RUNNER, (manifest, installRoot, binName, binKind) => async (ctx) => {
151
152
  const argv = ctx.args || [];
152
153
  const explicitInteractive = argv.includes('-i');
153
154
  const terminalStdin = ctx.isFdTerminal?.(0) ?? !ctx.stdin;
@@ -155,11 +156,13 @@ export async function registerHostedCommands(self, workspace) {
155
156
  const { runBashRepl } = await import('../runtime/bash-repl.js');
156
157
  return await runBashRepl({
157
158
  facetMgr,
158
- vfs: sqliteFs,
159
+ authority: workspace.filesystem,
159
160
  terminal: terminal,
160
161
  installRoot,
161
162
  manifest,
162
163
  cred: ctx.cred,
164
+ pid: ctx.pid,
165
+ filesystem: workspace.filesystem.bind({ pid: ctx.pid, cred: ctx.cred, signal: ctx.signal }),
163
166
  env: ctx.env,
164
167
  cwd: ctx.cwd || '/home/user',
165
168
  shell: shell ?? undefined,
@@ -167,7 +170,7 @@ export async function registerHostedCommands(self, workspace) {
167
170
  }
168
171
  const { makeBashRunnerFactory } = await import('@nimbus-sh/core/runtime/bash-runner.js');
169
172
  const { facetHostForManager } = await import('../runtime/facet-loader-host.js');
170
- return await makeBashRunnerFactory({ facets: facetHostForManager(facetMgr), vfs: sqliteFs })(manifest, installRoot, binName, binKind)(ctx);
173
+ return await makeBashRunnerFactory({ facets: facetHostForManager(facetMgr), filesystem: workspace.filesystem })(manifest, installRoot, binName, binKind)(ctx);
171
174
  });
172
175
  {
173
176
  // Cast registry to the minimal package-manager shape. CommandRegistry
@@ -198,24 +201,16 @@ export async function registerHostedCommands(self, workspace) {
198
201
  const stderr = { write: (s) => { stderrText.push(String(s)); } };
199
202
  const py = await registry.resolve('python');
200
203
  if (py) {
201
- const pid = 'pid' in ctx ? ctx.pid : undefined;
202
- const setUmask = 'setUmask' in ctx ? ctx.setUmask : undefined;
203
- const runAs = 'runAs' in ctx ? ctx.runAs : undefined;
204
- if (typeof pid !== 'number'
205
- || typeof setUmask !== 'function'
206
- || typeof runAs !== 'function'
207
- || kernel === null) {
208
- throw new Error('python warm-up requires a process identity');
209
- }
210
- const cred = requireVfsCred('cred' in ctx ? ctx.cred : undefined, 'python warm-up');
204
+ const pid = ctx.pid;
205
+ const cred = requireVfsCred(ctx.cred, 'python warm-up');
211
206
  const code = await py({
212
207
  ...ctx,
213
208
  args: ['-c', 'pass'],
214
209
  pid,
215
210
  cred,
216
- setUmask: (mask) => setUmask(mask),
217
- runAs: (targetCred, argv) => runAs(targetCred, argv),
218
- vfs: kernel.vfs,
211
+ setUmask: (mask) => ctx.setUmask(mask),
212
+ runAs: (targetCred, argv) => ctx.runAs(targetCred, argv),
213
+ vfs: new ExecutionFs(workspace.filesystem.bind({ pid, cred })),
219
214
  signal: new AbortController().signal,
220
215
  stdout,
221
216
  stderr,
@@ -227,7 +222,7 @@ export async function registerHostedCommands(self, workspace) {
227
222
  const { warmPythonRepl } = await import('../runtime/python-repl.js');
228
223
  await warmPythonRepl({
229
224
  facetMgr,
230
- vfs: sqliteFs,
225
+ authority: workspace.filesystem,
231
226
  installRoot: target.root,
232
227
  manifest: target.manifest,
233
228
  });
@@ -284,7 +279,6 @@ export async function registerHostedCommands(self, workspace) {
284
279
  };
285
280
  {
286
281
  const oneShotNode = buildRuntimeHandler(nodeSpec, {
287
- vfs: sqliteFs,
288
282
  getEsbuild: () => {
289
283
  if (!self.esbuildService) {
290
284
  self.ensureSqliteFs();
@@ -418,9 +412,9 @@ export async function registerHostedCommands(self, workspace) {
418
412
  return 1;
419
413
  }
420
414
  }
421
- const resolved = resolveRuntimeScriptPath(kernelFs, cwd, target, {
415
+ const resolved = (await resolveRuntimeScriptPath(kernelFs, cwd, target, {
422
416
  preferModuleField: true,
423
- });
417
+ }));
424
418
  if (resolved === null) {
425
419
  ctx.stderr.write(pathShaped
426
420
  ? `error: Module not found "${target}"\n`
@@ -433,7 +427,6 @@ export async function registerHostedCommands(self, workspace) {
433
427
  };
434
428
  {
435
429
  const oneShotBun = buildRuntimeHandler(bunSpec, {
436
- vfs: sqliteFs,
437
430
  getEsbuild: () => {
438
431
  if (!self.esbuildService) {
439
432
  self.ensureSqliteFs();
@@ -473,15 +466,11 @@ export async function registerHostedCommands(self, workspace) {
473
466
  const { wasmRunnerSpec } = await import('@nimbus-sh/core/runtime/wasm-runner.js');
474
467
  const { loaderFacetHost } = await import('../runtime/facet-loader-host.js');
475
468
  const wasmSpec = wasmRunnerSpec({
476
- // filesystem WASI: extended VFS surface for WASI file-IO. The
477
- // wasm-runner snapshots a session subtree into the facet, flushes
478
- // the diff back via this surface after _start returns.
479
- vfs: sqliteFs,
469
+ filesystem: workspace.filesystem,
480
470
  facets: loaderFacetHost(self.env, self.ctx),
481
471
  processes: self.processes,
482
472
  });
483
473
  wasmHandler = buildRuntimeHandler(wasmSpec, {
484
- vfs: sqliteFs,
485
474
  getEsbuild: () => {
486
475
  if (!self.esbuildService) {
487
476
  self.ensureSqliteFs();
@@ -896,7 +885,7 @@ export async function registerHostedCommands(self, workspace) {
896
885
  try {
897
886
  const identity = commandIdentityFor(childProcess.pid);
898
887
  const terminal = new HeadlessTerminal();
899
- const childShell = new Shell(terminal, kernel.vfs, registry, { ...env, ...(options?.env || {}) }, processRegistry, identity);
888
+ const childShell = new Shell(terminal, workspace.filesystem, registry, { ...env, ...(options?.env || {}) }, processRegistry, identity);
900
889
  HeredocHandler.install(childShell, terminal);
901
890
  if (options?.cwd)
902
891
  childShell.setCwd(options.cwd);
@@ -918,7 +907,7 @@ export async function registerHostedCommands(self, workspace) {
918
907
  }
919
908
  },
920
909
  };
921
- registerShellEntrypointCommands(registry, shellEntrypointExecutor, kernelFs);
910
+ registerShellEntrypointCommands(registry, shellEntrypointExecutor);
922
911
  // Shell scripts that execute through the local shell still need the same
923
912
  // process-table and log-store contract as facet-backed processes.
924
913
  const shellExecuteTracked = async (cmd, cmdCtx, opts = {}) => {
@@ -1385,7 +1374,7 @@ export async function registerHostedCommands(self, workspace) {
1385
1374
  await self.ensureNpmInstaller((msg) => ctx.stdout.write('[npm] ' + msg + '\n'));
1386
1375
  self.ensureSqliteFs();
1387
1376
  const installer = self.npmInstaller;
1388
- const resolveResult = await resolveNpxBinary(installer, sqliteFs.as(requireVfsCred('cred' in ctx ? ctx.cred : undefined, 'npx')), ctx.cwd || '/home/user', npxArgs, (msg) => ctx.stdout.write(msg + '\n'), ctx.pid);
1377
+ const resolveResult = await resolveNpxBinary(installer, sqliteFs.as(requireVfsCred(ctx.cred, 'npx')), ctx.cwd || '/home/user', npxArgs, (msg) => ctx.stdout.write(msg + '\n'), ctx.pid);
1389
1378
  if (resolveResult.ok && resolveResult.binPath) {
1390
1379
  const nodeCmd = await registry.resolve('node');
1391
1380
  if (nodeCmd) {
@@ -4,6 +4,7 @@ import type { ProcessLogReadOptions } from '@nimbus-sh/core/runtime/process-logs
4
4
  import type { VfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
5
5
  import type { SandboxFs } from '@nimbus-sh/core/substrate/lifo/sandbox/types.js';
6
6
  import { type SupervisorOpEnvelope } from '@nimbus-sh/core/workspace/supervisor-op.js';
7
+ import type { FacetManagerHostHooks } from '../facets/compose.js';
7
8
  import { WebSocketTerminal } from '../facets/ws-terminal.js';
8
9
  import * as operations from '../session/programmatic.js';
9
10
  import * as services from './services.js';
@@ -25,6 +26,7 @@ export interface HostedRuntimeOptions {
25
26
  env: services.HostedRuntimeEnv;
26
27
  ports: PortRegistry;
27
28
  lifecycle: HostedRuntimeLifecycle;
29
+ resolveWorkerLaunch?: FacetManagerHostHooks['resolveWorkerLaunch'];
28
30
  basePath?: string;
29
31
  origin?: string;
30
32
  }
@@ -80,6 +82,25 @@ export declare function composeHostedRuntime(options: HostedRuntimeOptions): Pro
80
82
  }>;
81
83
  listPorts: () => Promise<operations.SerializedPort[]>;
82
84
  listApps: () => Promise<operations.ListedApp[]>;
85
+ ensureDurableApp: (input: {
86
+ owner: string;
87
+ preferredPort?: number;
88
+ visibility?: "scoped" | "public";
89
+ name?: string;
90
+ }) => Promise<{
91
+ port: number;
92
+ capability: string | null;
93
+ visibility: "scoped" | "public";
94
+ }>;
95
+ unexposePort: (port: number) => Promise<{
96
+ port: number;
97
+ ok: boolean;
98
+ }>;
99
+ removeDurableApp: (owner: string) => Promise<{
100
+ owner: string;
101
+ removed: boolean;
102
+ port: number | null;
103
+ }>;
83
104
  exposeApp: (target: operations.AppTarget, options?: {
84
105
  visibility?: "scoped" | "public";
85
106
  name?: string;
@@ -101,7 +122,7 @@ export declare function composeHostedRuntime(options: HostedRuntimeOptions): Pro
101
122
  available: import("@nimbus-sh/core/runtime/runtime-package.js").RuntimeAvailability[];
102
123
  }>;
103
124
  spawnWorker: (workerCode: string, command: string, cwd: string, opts?: import("../facets/manager.js").LongRunningWorkerSpawnOptions | undefined) => Promise<import("../facets/manager.js").SpawnedWorker>;
104
- routeCapabilityPort: (port: number, capability: string, request: Request<unknown, CfProperties<unknown>>, pathname: string) => Promise<Response>;
125
+ routeCapabilityPort: (port: number, capability: string, request: Request<unknown, CfProperties<unknown>>, innerPath: string) => Promise<Response>;
105
126
  supervisorOp: (envelope: SupervisorOpEnvelope) => Promise<unknown>;
106
127
  onScheduled: (task: HostedRuntimeTask) => Promise<void>;
107
128
  attachTerminal: (ws: WebSocket) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/hosted/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAGvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iDAAiD,CAAC;AACjF,OAAO,EAAwB,KAAK,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAW7G,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAO7D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,QAAA,MAAM,UAAU;;;;EAA0D,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,GAAG,EAAE,kBAAkB,CAAC;IACxB,GAAG,EAAE,QAAQ,CAAC,gBAAgB,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,sBAAsB,CAAC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;CACjC;AAsOD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkBjD,MAAM,YAAY,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAWjC,oBAAoB;wBACzB,iBAAiB;yBAChB,SAAS;wBACV,SAAS,WAAW,MAAM,GAAG,WAAW;wBACxC,SAAS;;GAGhC;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/hosted/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAA6B,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAIlG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iDAAiD,CAAC;AACjF,OAAO,EAAqD,KAAK,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAE1I,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AASxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAO7D,OAAO,KAAK,UAAU,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAI3B,QAAA,MAAM,UAAU;;;;EAA0D,CAAC;AAC3E,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAE3D,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,eAAe,CAAC;IAC3B,GAAG,EAAE,kBAAkB,CAAC;IACxB,GAAG,EAAE,QAAQ,CAAC,gBAAgB,CAAC;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,sBAAsB,CAAC;IAClC,mBAAmB,CAAC,EAAE,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC7C,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,CAAC;CACjC;AAqRD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkBjD,MAAM,YAAY,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAiBjC,oBAAoB;wBACzB,iBAAiB;yBAChB,SAAS;wBACV,SAAS,WAAW,MAAM,GAAG,WAAW;wBACxC,SAAS;;GAGhC;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { requireVfsCred } from '@nimbus-sh/core/runtime/os-contracts.js';
2
2
  import { SandboxFsImpl } from '@nimbus-sh/core/substrate/lifo/sandbox/SandboxFs.js';
3
- import { SUPERVISOR_OP_ROUTES } from '@nimbus-sh/core/workspace/supervisor-op.js';
3
+ import { ExecutionFs } from '@nimbus-sh/core/shell/execution-fs.js';
4
+ import { SUPERVISOR_OP_ROUTES, createSupervisorBridgeStore } from '@nimbus-sh/core/workspace/supervisor-op.js';
4
5
  import { WebSocketTerminal } from '../facets/ws-terminal.js';
5
6
  import { buildSessionSupervisorOps } from '../session/supervisor-op.js';
6
7
  import { installLogPersistence } from '../session/hibernation.js';
@@ -48,6 +49,8 @@ class RuntimeOwner {
48
49
  flushScheduled = false;
49
50
  janitorScheduled = false;
50
51
  recoveryNotice = false;
52
+ scheduling = new Set();
53
+ fileLeases = new Map();
51
54
  services;
52
55
  constructor(options) {
53
56
  this.options = options;
@@ -68,6 +71,8 @@ class RuntimeOwner {
68
71
  env: options.env,
69
72
  notify: (line) => this._notifySession(line),
70
73
  requestLaunchTurn: (at) => this._scheduleLaunchTurn(at),
74
+ resolveWorkerLaunch: options.resolveWorkerLaunch,
75
+ filesystem: () => options.workspace.filesystem,
71
76
  });
72
77
  options.workspace.shell.bindTerminal(this.terminal);
73
78
  installLogPersistence(this, options.ctx, () => this.scheduleLogs());
@@ -122,9 +127,25 @@ class RuntimeOwner {
122
127
  throw new Error('Nimbus runtime cannot replace the workspace registry');
123
128
  }
124
129
  _notifySession(line) { this.terminal.write(`${line}\r\n`); }
125
- async _scheduleLaunchTurn(notBefore = Date.now()) {
126
- await this.options.lifecycle.schedule('resident-launch', Math.max(Date.now(), notBefore));
127
- return true;
130
+ _scheduleLaunchTurn(notBefore = Date.now()) {
131
+ const pending = this.schedule('resident-launch', Math.max(Date.now(), notBefore));
132
+ this.options.lifecycle.waitUntil(pending);
133
+ return pending;
134
+ }
135
+ schedule(reason, at) {
136
+ if (this._w1SessionDestroyed)
137
+ return Promise.reject(new Error('Nimbus runtime is closed'));
138
+ // Registered before the deferred call runs, so close() waits for a turn
139
+ // issued in the same tick; the second closed check keeps that turn from
140
+ // arming an alarm the shutdown has already decided against.
141
+ const pending = Promise.resolve().then(() => {
142
+ if (this._w1SessionDestroyed)
143
+ return;
144
+ return this.options.lifecycle.schedule(reason, at);
145
+ });
146
+ this.scheduling.add(pending);
147
+ void pending.then(() => this.scheduling.delete(pending), () => this.scheduling.delete(pending));
148
+ return pending;
128
149
  }
129
150
  _reportExternalExit(pid, code, reason) { return rpc._reportExternalExit(this, pid, code, reason); }
130
151
  _emitExitDump(pid, code) { return rpc._emitExitDump(this, pid, code); }
@@ -132,7 +153,11 @@ class RuntimeOwner {
132
153
  _rpcStdout(pid, data) { return rpc._rpcStdout(this, pid, data); }
133
154
  _rpcStderr(pid, data) { return rpc._rpcStderr(this, pid, data); }
134
155
  supervisorOps() {
135
- this.supervisor ??= buildSessionSupervisorOps(this, undefined, Object.fromEntries(Object.values(SUPERVISOR_OP_ROUTES).map(({ method }) => {
156
+ this.supervisor ??= buildSessionSupervisorOps(this, createSupervisorBridgeStore({
157
+ vfs: this.options.workspace.vfs,
158
+ filesystem: this.options.workspace.filesystem,
159
+ processes: this.processes,
160
+ }), Object.fromEntries(Object.values(SUPERVISOR_OP_ROUTES).map(({ method }) => {
136
161
  const handler = Reflect.get(rpc, method);
137
162
  if (typeof handler !== 'function')
138
163
  throw new Error(`Missing Nimbus supervisor implementation: ${method}`);
@@ -151,11 +176,17 @@ class RuntimeOwner {
151
176
  return;
152
177
  if (!this.flushScheduled) {
153
178
  this.flushScheduled = true;
154
- this.options.lifecycle.waitUntil(this.options.lifecycle.schedule('log-flush', Date.now() + 250));
179
+ this.options.lifecycle.waitUntil(this.schedule('log-flush', Date.now() + 250).catch((error) => {
180
+ this.flushScheduled = false;
181
+ throw error;
182
+ }));
155
183
  }
156
184
  if (!this.janitorScheduled) {
157
185
  this.janitorScheduled = true;
158
- this.options.lifecycle.waitUntil(this.options.lifecycle.schedule('log-janitor', Date.now() + 60_000));
186
+ this.options.lifecycle.waitUntil(this.schedule('log-janitor', Date.now() + 60_000).catch((error) => {
187
+ this.janitorScheduled = false;
188
+ throw error;
189
+ }));
159
190
  }
160
191
  }
161
192
  async onScheduled(task) {
@@ -206,6 +237,22 @@ class RuntimeOwner {
206
237
  this.terminal.detach();
207
238
  this.processes.flushLogs();
208
239
  }
240
+ files(cred) {
241
+ this.assertOpen();
242
+ const workspace = this.options.workspace;
243
+ const identity = requireVfsCred(cred, 'runtime files');
244
+ // One host lease per credential, not per `.as()` call: the descriptor
245
+ // scope behind a lease lives until close(), so re-deriving a view for an
246
+ // identity the runtime already opened must reuse that scope.
247
+ const key = `${identity.uid}:${identity.gid}:${identity.groups.join(',')}:${identity.umask}`;
248
+ let lease = this.fileLeases.get(key);
249
+ if (!lease) {
250
+ lease = workspace.filesystem.openHost(identity);
251
+ this.fileLeases.set(key, lease);
252
+ }
253
+ const view = new SandboxFsImpl(new ExecutionFs(lease.fs), () => workspace.shell.getCwd());
254
+ return Object.assign(view, { as: (next) => this.files(next) });
255
+ }
209
256
  close() {
210
257
  this.closing ??= Promise.resolve().then(async () => {
211
258
  const failures = [];
@@ -237,6 +284,13 @@ class RuntimeOwner {
237
284
  for (const ws of this.ctx.getWebSockets('process-logs')) {
238
285
  await clean(() => ws.close(1000, 'runtime closed'));
239
286
  }
287
+ await clean(() => this.facetManager?.closeLaunches());
288
+ await Promise.allSettled(this.scheduling);
289
+ await clean(() => this.supervisor?.dispose());
290
+ for (const lease of this.fileLeases.values())
291
+ await clean(() => lease.dispose());
292
+ this.fileLeases.clear();
293
+ await clean(() => this.options.workspace.close());
240
294
  for (const task of HostedTask.options)
241
295
  await clean(() => this.options.lifecycle.cancel(task));
242
296
  if (failures.length > 0)
@@ -245,17 +299,13 @@ class RuntimeOwner {
245
299
  return this.closing;
246
300
  }
247
301
  }
248
- function runtimeFiles(workspace, cred) {
249
- const view = new SandboxFsImpl(workspace.kernel.vfs.as(cred), () => workspace.shell.getCwd());
250
- return Object.assign(view, { as: (next) => runtimeFiles(workspace, requireVfsCred(next, 'runtime files')) });
251
- }
252
302
  export async function composeHostedRuntime(options) {
253
303
  const owner = new RuntimeOwner(options);
254
304
  await owner.ensureRuntimeReady();
255
305
  return {
256
306
  workspace: options.workspace,
257
307
  terminal: owner.terminal,
258
- files: runtimeFiles(options.workspace, owner.processes.cred(owner.shellProcessPid)),
308
+ files: owner.files(owner.processes.cred(owner.shellProcessPid)),
259
309
  runtimes: owner.runtimeManager,
260
310
  ready: operations.ensureProgrammaticReady.bind(null, owner),
261
311
  exec: operations.rpcExec.bind(null, owner),
@@ -270,6 +320,9 @@ export async function composeHostedRuntime(options) {
270
320
  processLogs: (pid, options) => operations.rpcProcessLogs(owner, pid, options),
271
321
  listPorts: operations.rpcListPorts.bind(null, owner),
272
322
  listApps: operations.rpcListApps.bind(null, owner),
323
+ ensureDurableApp: operations.rpcEnsureDurableApp.bind(null, owner),
324
+ unexposePort: operations.rpcUnexposePort.bind(null, owner),
325
+ removeDurableApp: operations.rpcRemoveDurableApp.bind(null, owner),
273
326
  exposeApp: operations.rpcExposeApp.bind(null, owner),
274
327
  removeApp: operations.rpcRemoveApp.bind(null, owner),
275
328
  rotateLink: operations.rpcRotateLink.bind(null, owner),
@@ -277,7 +330,10 @@ export async function composeHostedRuntime(options) {
277
330
  ensureRuntimes: operations.rpcEnsureRuntimes.bind(null, owner),
278
331
  listRuntimes: operations.rpcListRuntimes.bind(null, owner),
279
332
  spawnWorker: operations.rpcSpawnWorker.bind(null, owner),
280
- routeCapabilityPort: operations.rpcRouteCapabilityPort.bind(null, owner),
333
+ routeCapabilityPort: async (...args) => {
334
+ await operations.ensureProgrammaticReady(owner);
335
+ return owner.ensureFacetManager().apps.routeCapabilityPort(...args);
336
+ },
281
337
  supervisorOp: (envelope) => owner.supervisorOp(envelope),
282
338
  onScheduled: (task) => owner.onScheduled(task),
283
339
  attachTerminal: (ws) => owner.attachTerminal(ws),
@@ -1,4 +1,5 @@
1
- import { type ComposedFacetManager } from "../facets/compose.js";
1
+ import { type ComposedFacetManager, type FacetManagerHostHooks } from "../facets/compose.js";
2
+ import { type NimbusFilesystemAuthority } from "@nimbus-sh/core/runtime/os-contracts.js";
2
3
  import { EsbuildBundlePool } from "../facets/esbuild-bundle-pool.js";
3
4
  import type { NpmInstaller } from "../npm/installer.js";
4
5
  import { WebSocketRelay } from "../session/ws-relay.js";
@@ -15,7 +16,10 @@ export interface RuntimeServiceContext {
15
16
  readonly ctx: DurableObjectState;
16
17
  readonly env: HostedRuntimeEnv;
17
18
  notify(line: string): void;
18
- requestLaunchTurn(notBefore?: number): Promise<boolean>;
19
+ requestLaunchTurn(notBefore?: number): Promise<void>;
20
+ resolveWorkerLaunch?: FacetManagerHostHooks['resolveWorkerLaunch'];
21
+ /** The host's own authority: a session has exactly one, and this is it. */
22
+ filesystem: () => NimbusFilesystemAuthority;
19
23
  }
20
24
  export declare function ensureBundlePool(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): EsbuildBundlePool;
21
25
  export declare function ensureFacetManager(self: RuntimeServiceHost, runtimeContext: RuntimeServiceContext): ComposedFacetManager;
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/hosted/services.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/hosted/services.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import { composeFacetManager } from "../facets/compose.js";
3
3
  import { FacetProcessManager, textBytes } from "../facets/process.js";
4
4
  import { ChildProcessSpawnPool } from "../loaders/child-process/spawn-pool.js";
5
5
  import { CRED_KERNEL, CRED_SESSION_USER } from "@nimbus-sh/core/runtime/os-contracts.js";
6
+ import { SqliteFilesystemAuthority } from "@nimbus-sh/core/runtime/filesystem-authority.js";
6
7
  import { EsbuildBundlePool } from "../facets/esbuild-bundle-pool.js";
7
8
  import { EsbuildService } from "@nimbus-sh/core/runtime/esbuild-service.js";
8
9
  import { CF_COMPAT_DATE } from "@nimbus-sh/core/constants.js";
@@ -64,16 +65,25 @@ export function ensureFacetManager(self, runtimeContext) {
64
65
  // first. Cheap and idempotent; every caller already stood it up or is
65
66
  // about to.
66
67
  self.ensureSqliteFs();
68
+ const filesystem = runtimeContext.filesystem();
69
+ // The manager reaches the disk behind the authority (boot images, the
70
+ // launch journal), so a host that credentials something other than this
71
+ // session's SQLite filesystem cannot compose one.
72
+ if (!(filesystem instanceof SqliteFilesystemAuthority)) {
73
+ throw new Error('Nimbus: the facet manager needs the session SqliteFilesystemAuthority, not a foreign filesystem authority');
74
+ }
67
75
  self.facetManagerComposed = composeFacetManager({
68
76
  ctx: runtimeContext.ctx,
69
77
  env: runtimeContext.env,
70
78
  processes: self.processes,
71
79
  portRegistry: self.portRegistry,
72
- vfs: self.sqliteFs,
80
+ vfs: filesystem.vfs,
81
+ filesystem,
73
82
  ...(self.esbuildService ? { esbuild: self.esbuildService } : {}),
74
83
  hooks: {
75
84
  onExternalExit: (pid, code, reason) => self._reportExternalExit(pid, code, reason),
76
- requestLaunchTurn: (notBefore) => { void runtimeContext.requestLaunchTurn(notBefore); },
85
+ requestLaunchTurn: (notBefore) => runtimeContext.requestLaunchTurn(notBefore),
86
+ resolveWorkerLaunch: runtimeContext.resolveWorkerLaunch,
77
87
  notify: (line) => runtimeContext.notify(line),
78
88
  onSpawn: (pid, command, longRunning) => {
79
89
  const attachedTty = self.processes.get(pid)?.attachedTty === true;
@@ -16,7 +16,7 @@
16
16
  * W7_MAGIC, W7_MAX_RECORD_BYTES.
17
17
  *
18
18
  * Tar size: 4.62 KiB
19
- * W7 size: 28.97 KiB
19
+ * W7 size: 29.55 KiB
20
20
  */
21
21
  export declare const TAR_STREAM_PREAMBLE: string;
22
22
  export declare const W7_FRAME_PREAMBLE: string;
@@ -1 +1 @@
1
- {"version":3,"file":"generated-workers.d.ts","sourceRoot":"","sources":["../../src/loaders/generated-workers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,mBAAmB,EAAE,MAAk1J,CAAC;AAEr3J,eAAO,MAAM,iBAAiB,EAAE,MAA4/7B,CAAC"}
1
+ {"version":3,"file":"generated-workers.d.ts","sourceRoot":"","sources":["../../src/loaders/generated-workers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,eAAO,MAAM,mBAAmB,EAAE,MAAk1J,CAAC;AAEr3J,eAAO,MAAM,iBAAiB,EAAE,MAAwm9B,CAAC"}