@nimbus-sh/core 0.1.0 → 0.2.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 (60) hide show
  1. package/dist/index.d.ts +2 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -0
  4. package/dist/runtime/bash-runner.d.ts +63 -0
  5. package/dist/runtime/bash-runner.d.ts.map +1 -0
  6. package/dist/runtime/bash-runner.generated.d.ts +14 -0
  7. package/dist/runtime/bash-runner.generated.d.ts.map +1 -0
  8. package/dist/runtime/bash-runner.generated.js +13 -0
  9. package/dist/runtime/bash-runner.js +290 -0
  10. package/dist/runtime/cpython-runner.d.ts +86 -0
  11. package/dist/runtime/cpython-runner.d.ts.map +1 -0
  12. package/dist/runtime/cpython-runner.js +425 -0
  13. package/dist/runtime/facet-host.d.ts +159 -0
  14. package/dist/runtime/facet-host.d.ts.map +1 -0
  15. package/dist/runtime/facet-host.js +22 -0
  16. package/dist/runtime/installed-runtimes.d.ts +99 -0
  17. package/dist/runtime/installed-runtimes.d.ts.map +1 -0
  18. package/dist/runtime/installed-runtimes.js +162 -0
  19. package/dist/runtime/local-facet-host.d.ts +38 -0
  20. package/dist/runtime/local-facet-host.d.ts.map +1 -0
  21. package/dist/runtime/local-facet-host.js +171 -0
  22. package/dist/runtime/python-pip.d.ts +38 -0
  23. package/dist/runtime/python-pip.d.ts.map +1 -0
  24. package/dist/runtime/python-pip.js +1063 -0
  25. package/dist/runtime/runtime-manifest.d.ts +86 -0
  26. package/dist/runtime/runtime-manifest.d.ts.map +1 -0
  27. package/dist/runtime/runtime-manifest.js +72 -0
  28. package/dist/runtime/runtime-registry.d.ts +161 -0
  29. package/dist/runtime/runtime-registry.d.ts.map +1 -0
  30. package/dist/runtime/runtime-registry.js +363 -0
  31. package/dist/runtime/vfs-snapshot.d.ts.map +1 -1
  32. package/dist/runtime/vfs-snapshot.js +15 -1
  33. package/dist/runtime/vfs-supervisor.d.ts +22 -0
  34. package/dist/runtime/vfs-supervisor.d.ts.map +1 -0
  35. package/dist/runtime/vfs-supervisor.js +65 -0
  36. package/dist/runtime/virtual-socket-kernel.generated.d.ts +14 -0
  37. package/dist/runtime/virtual-socket-kernel.generated.d.ts.map +1 -0
  38. package/dist/runtime/virtual-socket-kernel.generated.js +13 -0
  39. package/dist/runtime/wasm-runner.d.ts +80 -0
  40. package/dist/runtime/wasm-runner.d.ts.map +1 -0
  41. package/dist/runtime/wasm-runner.js +686 -0
  42. package/dist/workspace/nimbus-workspace.d.ts +16 -0
  43. package/dist/workspace/nimbus-workspace.d.ts.map +1 -1
  44. package/dist/workspace/nimbus-workspace.js +57 -2
  45. package/package.json +4 -2
  46. package/src/index.ts +9 -0
  47. package/src/runtime/bash-runner.generated.ts +14 -0
  48. package/src/runtime/bash-runner.ts +347 -0
  49. package/src/runtime/cpython-runner.ts +504 -0
  50. package/src/runtime/facet-host.ts +170 -0
  51. package/src/runtime/installed-runtimes.ts +235 -0
  52. package/src/runtime/local-facet-host.ts +205 -0
  53. package/src/runtime/python-pip.ts +1211 -0
  54. package/src/runtime/runtime-manifest.ts +155 -0
  55. package/src/runtime/runtime-registry.ts +510 -0
  56. package/src/runtime/vfs-snapshot.ts +15 -1
  57. package/src/runtime/vfs-supervisor.ts +67 -0
  58. package/src/runtime/virtual-socket-kernel.generated.ts +14 -0
  59. package/src/runtime/wasm-runner.ts +835 -0
  60. package/src/workspace/nimbus-workspace.ts +102 -3
@@ -25,12 +25,18 @@ import { SqliteVFS, SqliteVFSProvider } from '../vfs/sqlite-vfs.js';
25
25
  import { DEFAULT_MOUNT_POINTS, DEFAULT_PATH } from '../constants.js';
26
26
  import { CRED_KERNEL, CRED_SESSION_USER } from '../runtime/os-contracts.js';
27
27
  import type { SqlDatabase, TransactionHost } from '../runtime/os-contracts.js';
28
+ import { PID_GEN_STRIDE } from '../runtime/process-table.js';
29
+ import { SessionProcessSupervisor } from '../runtime/session-process-supervisor.js';
30
+ import type { FacetHost } from '../runtime/facet-host.js';
31
+ import {
32
+ rehydrateInstalledRuntimesView,
33
+ type RunnerFactory,
34
+ } from '../runtime/installed-runtimes.js';
35
+ import type { CommandRegistry } from '../substrate/lifo/commands/registry.js';
36
+ import type { EsbuildService } from '../runtime/esbuild-service.js';
28
37
  import { registerUnixCommands } from '../shell/unix-commands.js';
29
38
  import { installPathExecResolver } from '../shell/exec-dispatch.js';
30
39
 
31
- /** Pids are `generation * PID_GEN_STRIDE + seq`; mirrors process-table.ts. */
32
- const PID_GEN_STRIDE = 1_000_000;
33
-
34
40
  export interface NimbusWorkspaceOptions {
35
41
  /** The host's SQLite. In a Durable Object: `ctx.storage.sql`. */
36
42
  readonly sql: SqlDatabase;
@@ -55,6 +61,21 @@ export interface NimbusWorkspaceOptions {
55
61
  readonly cwd?: string;
56
62
  /** Absent means headless: `.exec` captures output and nothing is drawn. */
57
63
  readonly terminal?: ITerminal;
64
+ /**
65
+ * Where WebAssembly runs.
66
+ *
67
+ * Absent, the workspace is the JavaScript half of Nimbus: the durable
68
+ * filesystem, the shell and the coreutils, and `bash` or `./prog.wasm` is
69
+ * "command not found" — not disabled, ABSENT, because nothing has been
70
+ * supplied that could compile a module or run one. Supplied, the wasm
71
+ * runtimes already installed in this filesystem become invokable commands
72
+ * and `wasm-runner` joins them, which is what makes a `\0asm` file on the
73
+ * PATH executable (see shell/exec-dispatch.ts).
74
+ *
75
+ * A Durable Object passes the workerd host (`@nimbus-sh/worker`'s
76
+ * `loaderFacetHost`); a plain process passes `localFacetHost()`.
77
+ */
78
+ readonly facets?: FacetHost;
58
79
  }
59
80
 
60
81
  /**
@@ -116,6 +137,16 @@ export class NimbusWorkspace {
116
137
  registerUnixCommands(sandbox.commands.registry, vfs);
117
138
  installPathExecResolver(sandbox.commands.registry, vfs.as(CRED_SESSION_USER), () => sandbox.shell.getCwd());
118
139
 
140
+ if (options.facets) {
141
+ await registerWasmRuntimes({
142
+ facets: options.facets,
143
+ vfs,
144
+ registry: sandbox.commands.registry,
145
+ generation: options.generation ?? 1,
146
+ home: options.env?.HOME ?? '/home/user',
147
+ });
148
+ }
149
+
119
150
  return new NimbusWorkspace(sandbox, vfs, options.sql);
120
151
  }
121
152
 
@@ -150,6 +181,74 @@ export class NimbusWorkspace {
150
181
  }
151
182
  }
152
183
 
184
+ /**
185
+ * Turn a facet host into commands: the runtimes this filesystem already holds,
186
+ * plus `wasm-runner` for everything else with a `\0asm` header.
187
+ *
188
+ * The runner factories are held here rather than in the process-global table
189
+ * `nimbus install` writes to, because each one closes over THIS workspace's
190
+ * filesystem and THIS workspace's facet host — a second workspace in the same
191
+ * process would otherwise silently retarget the first one's bash.
192
+ *
193
+ * Imported on demand: the runners carry the WASI shim and the bash scheduler as
194
+ * source strings, and a workspace with no facet host must not pay to parse
195
+ * them.
196
+ */
197
+ async function registerWasmRuntimes(deps: {
198
+ facets: FacetHost;
199
+ vfs: SqliteVFS;
200
+ registry: CommandRegistry;
201
+ generation: number;
202
+ home: string;
203
+ }): Promise<void> {
204
+ const [
205
+ { makeBashRunnerFactory },
206
+ { makeCPythonRunnerFactory },
207
+ { wasmRunnerSpec },
208
+ { buildRuntimeHandler },
209
+ esbuildModule,
210
+ ] = await Promise.all([
211
+ import('../runtime/bash-runner.js'),
212
+ import('../runtime/cpython-runner.js'),
213
+ import('../runtime/wasm-runner.js'),
214
+ import('../runtime/runtime-registry.js'),
215
+ import('../runtime/esbuild-service.js'),
216
+ ]);
217
+
218
+ // wasm-runner allocates pids for what it runs, so it needs a process table
219
+ // whose pid space is this generation's — the same rule the append writers
220
+ // above are revoked by.
221
+ const processes = new SessionProcessSupervisor();
222
+ processes.setPidBase(deps.generation * PID_GEN_STRIDE);
223
+
224
+ let esbuild: EsbuildService | null = null;
225
+ deps.registry.register('wasm-runner', buildRuntimeHandler(
226
+ wasmRunnerSpec({ vfs: deps.vfs, facets: deps.facets, processes }),
227
+ {
228
+ vfs: deps.vfs,
229
+ getEsbuild: () => {
230
+ if (!esbuild) esbuild = new esbuildModule.EsbuildService(deps.vfs);
231
+ return esbuild;
232
+ },
233
+ registry: deps.registry,
234
+ },
235
+ ));
236
+
237
+ const runners: Record<string, RunnerFactory> = {
238
+ 'bash-runner': makeBashRunnerFactory({ facets: deps.facets, vfs: deps.vfs }),
239
+ // No `startResident`: a workspace owns no actor that could outlive the
240
+ // call, so a program that keeps serving is refused by name rather than
241
+ // run as a one-shot that dies with it.
242
+ 'cpython-runner': makeCPythonRunnerFactory({ facets: deps.facets, vfs: deps.vfs }),
243
+ };
244
+ rehydrateInstalledRuntimesView(
245
+ deps.vfs.as(CRED_KERNEL),
246
+ deps.registry,
247
+ deps.home,
248
+ (key) => runners[key],
249
+ );
250
+ }
251
+
153
252
  /**
154
253
  * Every table the filesystem creates.
155
254
  *