@nimbus-sh/worker 0.7.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 (102) 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 +154 -112
  7. package/dist/facets/real-vite-hmr.d.ts +3 -1
  8. package/dist/facets/real-vite-hmr.d.ts.map +1 -1
  9. package/dist/facets/real-vite-hmr.js +18 -8
  10. package/dist/facets/ws-terminal.d.ts +9 -31
  11. package/dist/facets/ws-terminal.d.ts.map +1 -1
  12. package/dist/facets/ws-terminal.js +58 -51
  13. package/dist/hosted/commands.d.ts +12 -0
  14. package/dist/hosted/commands.d.ts.map +1 -0
  15. package/dist/hosted/commands.js +1647 -0
  16. package/dist/hosted/runtime.d.ts +135 -0
  17. package/dist/hosted/runtime.d.ts.map +1 -0
  18. package/dist/hosted/runtime.js +344 -0
  19. package/dist/hosted/services.d.ts +44 -0
  20. package/dist/hosted/services.d.ts.map +1 -0
  21. package/dist/hosted/services.js +522 -0
  22. package/dist/loaders/generated-workers.d.ts +1 -1
  23. package/dist/loaders/generated-workers.d.ts.map +1 -1
  24. package/dist/loaders/generated-workers.js +2 -2
  25. package/dist/node-shims-artifact.generated.js +3 -3
  26. package/dist/runtime/bash-repl.d.ts +6 -4
  27. package/dist/runtime/bash-repl.d.ts.map +1 -1
  28. package/dist/runtime/bash-repl.js +46 -7
  29. package/dist/runtime/bun-runner.js +1 -1
  30. package/dist/runtime/facet-loader-host.d.ts.map +1 -1
  31. package/dist/runtime/facet-loader-host.js +1 -3
  32. package/dist/runtime/node-runner.d.ts +1 -1
  33. package/dist/runtime/node-runner.d.ts.map +1 -1
  34. package/dist/runtime/node-runner.js +2 -2
  35. package/dist/runtime/node-shims.d.ts.map +1 -1
  36. package/dist/runtime/node-shims.js +14 -1
  37. package/dist/runtime/opencode-facet-runner.js +14 -14
  38. package/dist/runtime/package-manager.d.ts +35 -122
  39. package/dist/runtime/package-manager.d.ts.map +1 -1
  40. package/dist/runtime/package-manager.js +61 -596
  41. package/dist/runtime/process-logs-api.d.ts +1 -1
  42. package/dist/runtime/process-logs-api.d.ts.map +1 -1
  43. package/dist/runtime/process-logs-api.js +1 -1
  44. package/dist/runtime/python-repl.d.ts +6 -4
  45. package/dist/runtime/python-repl.d.ts.map +1 -1
  46. package/dist/runtime/python-repl.js +92 -67
  47. package/dist/runtime/repl-session.d.ts +9 -47
  48. package/dist/runtime/repl-session.d.ts.map +1 -1
  49. package/dist/runtime/repl-session.js +105 -105
  50. package/dist/runtime/ruby-repl.d.ts +3 -2
  51. package/dist/runtime/ruby-repl.d.ts.map +1 -1
  52. package/dist/runtime/ruby-repl.js +7 -6
  53. package/dist/runtime/runtime-catalog.d.ts +13 -0
  54. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  55. package/dist/runtime/runtime-catalog.js +88 -0
  56. package/dist/runtime/wasi/preamble.d.ts.map +1 -1
  57. package/dist/runtime/wasi/preamble.js +74 -56
  58. package/dist/runtime-catalog.generated.js +1 -1
  59. package/dist/session/agent.d.ts +1 -21
  60. package/dist/session/agent.d.ts.map +1 -1
  61. package/dist/session/ai.d.ts +5 -1
  62. package/dist/session/ai.d.ts.map +1 -1
  63. package/dist/session/ai.js +7 -0
  64. package/dist/session/hibernation.d.ts +2 -1
  65. package/dist/session/hibernation.d.ts.map +1 -1
  66. package/dist/session/hibernation.js +7 -4
  67. package/dist/session/init.d.ts +1 -36
  68. package/dist/session/init.d.ts.map +1 -1
  69. package/dist/session/init.js +18 -1773
  70. package/dist/session/loopback.d.ts +2 -29
  71. package/dist/session/loopback.d.ts.map +1 -1
  72. package/dist/session/loopback.js +3 -27
  73. package/dist/session/nimbus-session.d.ts +28 -34
  74. package/dist/session/nimbus-session.d.ts.map +1 -1
  75. package/dist/session/nimbus-session.js +78 -518
  76. package/dist/session/npm-install-port.d.ts +3 -1
  77. package/dist/session/npm-install-port.d.ts.map +1 -1
  78. package/dist/session/port-capability.d.ts.map +1 -1
  79. package/dist/session/port-capability.js +11 -1
  80. package/dist/session/programmatic.d.ts +5 -38
  81. package/dist/session/programmatic.d.ts.map +1 -1
  82. package/dist/session/programmatic.js +17 -49
  83. package/dist/session/rpc.d.ts +3 -43
  84. package/dist/session/rpc.d.ts.map +1 -1
  85. package/dist/session/rpc.js +8 -67
  86. package/dist/session/supervisor-op.d.ts +10 -5
  87. package/dist/session/supervisor-op.d.ts.map +1 -1
  88. package/dist/session/supervisor-op.js +21 -48
  89. package/dist/session/supervisor-rpc.d.ts +33 -16
  90. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  91. package/dist/session/supervisor-rpc.js +49 -4
  92. package/dist/vfs/facet-resident-store.d.ts.map +1 -1
  93. package/dist/vfs/facet-resident-store.js +4 -2
  94. package/dist/workspace-host.d.ts +7 -0
  95. package/dist/workspace-host.d.ts.map +1 -0
  96. package/dist/workspace-host.js +5 -0
  97. package/dist/workspace.d.ts +2 -0
  98. package/dist/workspace.d.ts.map +1 -0
  99. package/dist/workspace.js +1 -0
  100. package/package.json +17 -12
  101. package/public/_assets/runtime/{node-shims-8f8c64edd2a1f0f5.js → node-shims-acaa037e6d26ec0d.js} +14 -1
  102. package/scripts/bundle-runtime.mjs +35 -8
@@ -1,3 +1,6 @@
1
+ import { installAuthorityFilesystem, WASI_ACCEPTED_PATH_PREFIX, WASI_LISTEN_PATH_PREFIX, WASI_TCP_PATH_PREFIX, } from '@nimbus-sh/core/runtime/wasi/filesystem.js';
2
+ import { supervisorFilesystem } from '@nimbus-sh/core/runtime/vfs-supervisor.js';
3
+ import { WASI_RESIDENT_FILE_CAP_BYTES } from '@nimbus-sh/core/constants.js';
1
4
  // errno constants
2
5
  const __WASI_ESUCCESS = 0;
3
6
  const __WASI_EAGAIN = 6;
@@ -65,21 +68,6 @@ const __WASI_EVENTTYPE_CLOCK = 0;
65
68
  const __WASI_EVENTTYPE_FD_READ = 1;
66
69
  const __WASI_EVENTTYPE_FD_WRITE = 2;
67
70
  const __WASI_SUBCLOCKFLAGS_ABSTIME = 1; // SUBSCRIPTION_CLOCK_ABSTIME
68
- // WASI socket and polling support B7: synthetic-path prefix recognised by path_open as a request
69
- // to open a TCP socket. Mirrors bash's /dev/tcp/<host>/<port> convention
70
- // (https://www.gnu.org/software/bash/manual/html_node/Redirections.html).
71
- const __WASI_TCP_PATH_PREFIX = '/dev/tcp/';
72
- // The accept half of the same synthetic-socket family: binds a connection the
73
- // virtual socket kernel has already accepted to a file descriptor. It has to go
74
- // through path_open like the dial half - guests layered over wasi-vfs
75
- // (ruby.wasm) resolve descriptors through their own fd table, so a descriptor
76
- // handed to them out of band is not one they can use.
77
- const __WASI_ACCEPTED_PATH_PREFIX = '/dev/nimbus/socket/';
78
- // A listening socket, as a descriptor. Reading it is accept(2): the read
79
- // suspends until a connection is queued and yields that connection's id, so a
80
- // server's accept loop is an ordinary blocking read and needs no cooperative
81
- // pump driving it from outside.
82
- const __WASI_LISTEN_PATH_PREFIX = '/dev/nimbus/listen/';
83
71
  // WASI socket and polling support B7: resolved at preamble module-init via dynamic import.
84
72
  // CF docs: "TCP sockets cannot be created in global scope and shared
85
73
  // across requests" — so we only IMPORT the module here (cheap symbol
@@ -139,7 +127,7 @@ function __wasiEmptyFS() {
139
127
  root: '',
140
128
  files: new Map(), dirs: new Set(), times: new Map(), symlinks: new Map(),
141
129
  modes: new Map(), sizes: new Map(), origFiles: new Map(),
142
- residentFileCap: 8 * 1024 * 1024,
130
+ residentFileCap: WASI_RESIDENT_FILE_CAP_BYTES,
143
131
  enumeratedRoots: [],
144
132
  revision: null,
145
133
  };
@@ -456,7 +444,7 @@ export function __wasiInitFS(opts) {
456
444
  origFiles,
457
445
  // Files at or above this size are never held whole; reads window through
458
446
  // the supervisor instead. Keeps a 200 MiB blob from ending the isolate.
459
- residentFileCap: Number(opts.residentFileCap ?? (8 * 1024 * 1024)),
447
+ residentFileCap: Number(opts.residentFileCap ?? WASI_RESIDENT_FILE_CAP_BYTES),
460
448
  // Roots the seed claims to have listed COMPLETELY. Only a producer that
461
449
  // walked a subtree without exclusions may claim one. Inside such a root a
462
450
  // path the manifest lacks is genuinely absent, so the miss is answered
@@ -470,6 +458,9 @@ export function __wasiInitFS(opts) {
470
458
  revision: opts.revision ?? null,
471
459
  };
472
460
  // Reset fd table baseline; install preopens as fd 3, 4, 5, ...
461
+ // Emptied rather than replaced: the authority codec and the socket helpers
462
+ // are handed this Map, and a swap would leave half of them writing into a
463
+ // table nothing reads.
473
464
  __wasiPreopens = [];
474
465
  fdTable.clear();
475
466
  fdTable.set(0, { kind: 'stdin' });
@@ -477,7 +468,7 @@ export function __wasiInitFS(opts) {
477
468
  fdTable.set(2, { kind: 'stderr' });
478
469
  nextFd = 3;
479
470
  for (const po of (opts.preopens || [])) {
480
- const fd = nextFd++;
471
+ const fd = __wasiAllocateFd();
481
472
  const vfsPath = __wasiCanonicalize(po.vfsPath);
482
473
  fdTable.set(fd, { kind: 'preopen', wasiPath: po.wasiPath, vfsPath });
483
474
  __wasiPreopens.push({ fd, wasiPath: po.wasiPath, vfsPath });
@@ -565,7 +556,7 @@ function __wasiConnectRemote(host, port) {
565
556
  // Returns a WASI errno and writes the new fd to fdOutPtr.
566
557
  function __wasiOpenTcpSocket(pathArg, fdflags, fdOutPtr, writeU32LE) {
567
558
  // pathArg shape: "/dev/tcp/<host>/<port>".
568
- const tail = pathArg.substring(__WASI_TCP_PATH_PREFIX.length);
559
+ const tail = pathArg.substring(WASI_TCP_PATH_PREFIX.length);
569
560
  const slashIdx = tail.lastIndexOf('/');
570
561
  if (slashIdx <= 0 || slashIdx === tail.length - 1)
571
562
  return __WASI_EINVAL;
@@ -593,7 +584,7 @@ function __wasiKernelOrNull(what) {
593
584
  // Open a listening socket as a descriptor. The port must already be bound; the
594
585
  // descriptor is the accept queue, not the bind.
595
586
  function __wasiOpenListener(pathArg, fdflags, fdOutPtr, writeU32LE) {
596
- const port = parseInt(pathArg.substring(__WASI_LISTEN_PATH_PREFIX.length), 10);
587
+ const port = parseInt(pathArg.substring(WASI_LISTEN_PATH_PREFIX.length), 10);
597
588
  if (!Number.isInteger(port) || port <= 0 || port >= 65536)
598
589
  return __WASI_EINVAL;
599
590
  const kernel = __wasiKernelOrNull('ports cannot be listened on');
@@ -620,7 +611,7 @@ function __wasiOpenListener(pathArg, fdflags, fdOutPtr, writeU32LE) {
620
611
  if (typeof announce === 'function')
621
612
  announce(port);
622
613
  }
623
- const fd = nextFd++;
614
+ const fd = __wasiAllocateFd();
624
615
  fdTable.set(fd, { kind: 'listener', port, fdflags: fdflags | 0 });
625
616
  writeU32LE(fdOutPtr, fd);
626
617
  return __WASI_ESUCCESS;
@@ -670,7 +661,7 @@ async function __wasiAcceptRead(entry, iovsPtr, iovsLen, nreadPtr, writeU32LE, v
670
661
  // Bind an already-accepted kernel connection to a file descriptor, so a
671
662
  // server's accepted socket is the same kind of fd as a client's dialed one.
672
663
  function __wasiOpenAcceptedSocket(pathArg, fdflags, fdOutPtr, writeU32LE) {
673
- const id = parseInt(pathArg.substring(__WASI_ACCEPTED_PATH_PREFIX.length), 10);
664
+ const id = parseInt(pathArg.substring(WASI_ACCEPTED_PATH_PREFIX.length), 10);
674
665
  if (!Number.isInteger(id) || id <= 0)
675
666
  return __WASI_EINVAL;
676
667
  const kernel = globalThis.__nimbusVirtualSockets;
@@ -695,7 +686,7 @@ function __wasiOpenAcceptedSocket(pathArg, fdflags, fdOutPtr, writeU32LE) {
695
686
  // connection, or an accepted one. Every socket fd in the table comes from here,
696
687
  // which is why nothing downstream has to tell them apart.
697
688
  function __wasiAdoptSocket(socket, fdflags) {
698
- const fd = nextFd++;
689
+ const fd = __wasiAllocateFd();
699
690
  fdTable.set(fd, {
700
691
  kind: 'socket',
701
692
  socket,
@@ -776,6 +767,10 @@ export function __wasiReadFilesB64(paths) {
776
767
  // rights checks in v1 — single-tenant facet, no untrusted callers).
777
768
  export const fdTable = new Map();
778
769
  let nextFd = 3;
770
+ // The only source of descriptor numbers. A second counter — one for files, one
771
+ // for sockets — hands the same number out twice and the later open silently
772
+ // destroys the earlier fd's entry.
773
+ function __wasiAllocateFd() { return nextFd++; }
779
774
  // Resolve a WASI path against a preopen fd; returns the canonical VFS path
780
775
  // WITHOUT following symlinks. WASI socket and polling support kept this name compatible with all
781
776
  // existing call sites (~10 of them inside the imports object).
@@ -1102,7 +1097,9 @@ export function __wasiMakeImports(opts) {
1102
1097
  await __wasiDrainPersist();
1103
1098
  if (size <= __wasiFS.residentFileCap) {
1104
1099
  const whole = await __wasiSup.fsReadRange(vfsPath, 0, size);
1105
- const bytes = whole instanceof Uint8Array ? whole : new Uint8Array(whole);
1100
+ if (whole === null)
1101
+ throw new Error('ENOENT: ' + vfsPath);
1102
+ const bytes = whole;
1106
1103
  __wasiFS.files.set(vfsPath, bytes);
1107
1104
  // The diff-back mirror must agree, or a demand-loaded file would be
1108
1105
  // reported as newly written by every runner still using the diff.
@@ -1115,7 +1112,9 @@ export function __wasiMakeImports(opts) {
1115
1112
  if (want === 0)
1116
1113
  return new Uint8Array(0);
1117
1114
  const win = await __wasiSup.fsReadRange(vfsPath, offset, want);
1118
- return win instanceof Uint8Array ? win : new Uint8Array(win);
1115
+ if (win === null)
1116
+ throw new Error('ENOENT: ' + vfsPath);
1117
+ return win;
1119
1118
  })();
1120
1119
  }
1121
1120
  /** Scatter the given bytes across the iovec list; returns bytes consumed. */
@@ -1583,13 +1582,13 @@ export function __wasiMakeImports(opts) {
1583
1582
  // the in-memory FS — __wasiResolvePath would canonicalize it but
1584
1583
  // not find any entry.
1585
1584
  const guestPath = __wasiGuestPath(baseFd, pathArg);
1586
- if (guestPath.startsWith(__WASI_TCP_PATH_PREFIX)) {
1585
+ if (guestPath.startsWith(WASI_TCP_PATH_PREFIX)) {
1587
1586
  return __wasiOpenTcpSocket(guestPath, fdflags, fdOutPtr, writeU32LE);
1588
1587
  }
1589
- if (guestPath.startsWith(__WASI_ACCEPTED_PATH_PREFIX)) {
1588
+ if (guestPath.startsWith(WASI_ACCEPTED_PATH_PREFIX)) {
1590
1589
  return __wasiOpenAcceptedSocket(guestPath, fdflags, fdOutPtr, writeU32LE);
1591
1590
  }
1592
- if (guestPath.startsWith(__WASI_LISTEN_PATH_PREFIX)) {
1591
+ if (guestPath.startsWith(WASI_LISTEN_PATH_PREFIX)) {
1593
1592
  return __wasiOpenListener(guestPath, fdflags, fdOutPtr, writeU32LE);
1594
1593
  }
1595
1594
  // Honor LOOKUPFLAGS_SYMLINK_FOLLOW strictly: bit 0 set → follow.
@@ -1624,7 +1623,7 @@ export function __wasiMakeImports(opts) {
1624
1623
  const access = __wasiCheckMode(resolved, 1);
1625
1624
  if (access !== __WASI_ESUCCESS)
1626
1625
  return access;
1627
- const fd = nextFd++;
1626
+ const fd = __wasiAllocateFd();
1628
1627
  fdTable.set(fd, { kind: 'dir', vfsPath: resolved, readdirEntries: null, cookie: 0n, oflags, fdflags });
1629
1628
  writeU32LE(fdOutPtr, fd);
1630
1629
  return __WASI_ESUCCESS;
@@ -1665,7 +1664,7 @@ export function __wasiMakeImports(opts) {
1665
1664
  if (access !== __WASI_ESUCCESS)
1666
1665
  return access;
1667
1666
  }
1668
- const fd = nextFd++;
1667
+ const fd = __wasiAllocateFd();
1669
1668
  fdTable.set(fd, { kind: 'file', vfsPath: resolved, offset: 0, oflags, fdflags });
1670
1669
  writeU32LE(fdOutPtr, fd);
1671
1670
  return __WASI_ESUCCESS;
@@ -2196,7 +2195,7 @@ export function __wasiMakeImports(opts) {
2196
2195
  writeU32LE(bufusedPtr, written);
2197
2196
  return __WASI_ESUCCESS;
2198
2197
  },
2199
- fd_advise() { return __WASI_ESUCCESS; },
2198
+ fd_advise(_fd, _offset, _len, _advice) { return __WASI_ESUCCESS; },
2200
2199
  // WASI socket and polling support B4: real fd_allocate. Extends the file's byte buffer with
2201
2200
  // zeros so [offset, offset+len) is allocated. POSIX posix_fallocate
2202
2201
  // semantics. ENOSPC is not reachable in our in-memory FS (the
@@ -2428,9 +2427,11 @@ export function __wasiMakeImports(opts) {
2428
2427
  });
2429
2428
  }
2430
2429
  // Regular files, dirs, stdio: always ready (POSIX: regular files
2431
- // never block — read returns immediately even if at EOF).
2430
+ // never block — read returns immediately even if at EOF). A file the
2431
+ // authority owns is a regular file too; leaving 'authority' out made
2432
+ // polling one EBADF, which a guest reads as "this fd is gone".
2432
2433
  if (entry.kind === 'file' || entry.kind === 'dir' ||
2433
- entry.kind === 'preopen' ||
2434
+ entry.kind === 'preopen' || entry.kind === 'authority' ||
2434
2435
  entry.kind === 'stdin' || entry.kind === 'stdout' || entry.kind === 'stderr') {
2435
2436
  let nbytes = 0n;
2436
2437
  if (entry.kind === 'file' && s.tag === __WASI_EVENTTYPE_FD_READ) {
@@ -2843,6 +2844,15 @@ export function __wasiMakeImports(opts) {
2843
2844
  }
2844
2845
  },
2845
2846
  };
2847
+ installAuthorityFilesystem(imports, {
2848
+ fs: () => __wasiSup ? supervisorFilesystem(__wasiSup, opts.parking === 'none' ? __wasiSup.synchronous : undefined) : null,
2849
+ memory: opts.getMemory,
2850
+ fds: fdTable,
2851
+ allocateFd: __wasiAllocateFd,
2852
+ abi: opts.abi,
2853
+ synchronous: opts.parking === 'none',
2854
+ residentBytes: __wasiFS.residentFileCap,
2855
+ });
2846
2856
  // Raw async socket bodies, captured BEFORE JSPI-wrapping so fd_read /
2847
2857
  // fd_write can route socket fds through them (wasi-libc maps read(2)/
2848
2858
  // write(2) to fd_read/fd_write for every fd kind, sockets included).
@@ -2858,7 +2868,13 @@ export function __wasiMakeImports(opts) {
2858
2868
  // Every import that can park.
2859
2869
  const parkable = [
2860
2870
  'sock_send', 'sock_recv', 'sock_shutdown', 'sock_accept', 'poll_oneoff',
2861
- 'fd_read', 'fd_write', 'fd_pread', 'path_filestat_get',
2871
+ 'fd_read', 'fd_write', 'fd_pread', 'fd_pwrite', 'path_filestat_get',
2872
+ 'path_open', 'fd_close', 'fd_renumber', 'fd_seek', 'fd_tell', 'fd_filestat_get',
2873
+ 'fd_fdstat_set_flags', 'fd_fdstat_set_rights', 'fd_filestat_set_size',
2874
+ 'fd_sync', 'fd_datasync', 'fd_allocate', 'fd_advise', 'fd_readdir',
2875
+ 'path_create_directory', 'path_remove_directory', 'path_unlink_file',
2876
+ 'path_rename', 'path_symlink', 'path_readlink', 'path_link',
2877
+ 'fd_filestat_set_times', 'path_filestat_set_times',
2862
2878
  ];
2863
2879
  // Applied before Suspending wraps them.
2864
2880
  for (const name of parkable) {
@@ -2908,33 +2924,35 @@ export function __wasiMakeImports(opts) {
2908
2924
  imports.sock_recv = new WebAssembly.Suspending(imports.sock_recv);
2909
2925
  imports.sock_shutdown = new WebAssembly.Suspending(imports.sock_shutdown);
2910
2926
  imports.sock_accept = new WebAssembly.Suspending(imports.sock_accept);
2911
- // WASI socket and polling support B8: poll_oneoff also needs JSPI to support CLOCK
2912
- // subscriptions (await setTimeout) and socket-fd readiness
2913
- // (await reader.read()). Same Suspending shape as sock_*.
2914
2927
  imports.poll_oneoff = new WebAssembly.Suspending(imports.poll_oneoff);
2915
- // fd_read/fd_write become suspending too: a socket fd routes to the
2916
- // async sock bodies (Promise → JSPI suspends). File/stdio ops return a
2917
- // plain errno number, which JSPI passes through UNDER AN ACTIVE
2918
- // SUSPENDER. There is no passthrough without one: V8 traps ANY call
2919
- // into a Suspending import off a non-promising stack with SuspendError
2920
- // "trying to suspend without WebAssembly.promising", even when the
2921
- // import returns a plain number (measured on workerd, compat
2922
- // 2026-04-01). Every export that can reach these imports must be
2923
- // entered via WebAssembly.promising — assuming sync callers were
2924
- // unaffected is exactly how the Ruby VM boot went dark.
2925
2928
  imports.fd_read = new WebAssembly.Suspending(imports.fd_read);
2926
2929
  imports.fd_write = new WebAssembly.Suspending(imports.fd_write);
2927
- // fd_pread reaches the same file bodies as fd_read and so can equally
2928
- // land on a cache miss that must go to the supervisor. Leaving it
2929
- // unwrapped would trap the guest the first time a demand load happened
2930
- // to arrive through pread(2) rather than read(2).
2931
2930
  imports.fd_pread = new WebAssembly.Suspending(imports.fd_pread);
2932
- // path_filestat_get resolves a path the seed manifest never listed by
2933
- // asking the supervisor, so it too can return a Promise.
2931
+ imports.fd_pwrite = new WebAssembly.Suspending(imports.fd_pwrite);
2934
2932
  imports.path_filestat_get = new WebAssembly.Suspending(imports.path_filestat_get);
2935
- // sched_yield parks only in a threaded process, so it is wrapped only for
2936
- // one: every other guest keeps the plain i32 return it has today, and no
2937
- // existing runtime changes shape.
2933
+ imports.path_open = new WebAssembly.Suspending(imports.path_open);
2934
+ imports.fd_close = new WebAssembly.Suspending(imports.fd_close);
2935
+ imports.fd_renumber = new WebAssembly.Suspending(imports.fd_renumber);
2936
+ imports.fd_seek = new WebAssembly.Suspending(imports.fd_seek);
2937
+ imports.fd_tell = new WebAssembly.Suspending(imports.fd_tell);
2938
+ imports.fd_filestat_get = new WebAssembly.Suspending(imports.fd_filestat_get);
2939
+ imports.fd_fdstat_set_flags = new WebAssembly.Suspending(imports.fd_fdstat_set_flags);
2940
+ imports.fd_fdstat_set_rights = new WebAssembly.Suspending(imports.fd_fdstat_set_rights);
2941
+ imports.fd_filestat_set_size = new WebAssembly.Suspending(imports.fd_filestat_set_size);
2942
+ imports.fd_sync = new WebAssembly.Suspending(imports.fd_sync);
2943
+ imports.fd_datasync = new WebAssembly.Suspending(imports.fd_datasync);
2944
+ imports.fd_allocate = new WebAssembly.Suspending(imports.fd_allocate);
2945
+ imports.fd_advise = new WebAssembly.Suspending(imports.fd_advise);
2946
+ imports.fd_readdir = new WebAssembly.Suspending(imports.fd_readdir);
2947
+ imports.path_create_directory = new WebAssembly.Suspending(imports.path_create_directory);
2948
+ imports.path_remove_directory = new WebAssembly.Suspending(imports.path_remove_directory);
2949
+ imports.path_unlink_file = new WebAssembly.Suspending(imports.path_unlink_file);
2950
+ imports.path_rename = new WebAssembly.Suspending(imports.path_rename);
2951
+ imports.path_symlink = new WebAssembly.Suspending(imports.path_symlink);
2952
+ imports.path_readlink = new WebAssembly.Suspending(imports.path_readlink);
2953
+ imports.path_link = new WebAssembly.Suspending(imports.path_link);
2954
+ imports.fd_filestat_set_times = new WebAssembly.Suspending(imports.fd_filestat_set_times);
2955
+ imports.path_filestat_set_times = new WebAssembly.Suspending(imports.path_filestat_set_times);
2938
2956
  if (opts.threads)
2939
2957
  imports.sched_yield = new WebAssembly.Suspending(imports.sched_yield);
2940
2958
  }
@@ -24,4 +24,4 @@
24
24
  * The empty string means "not pinned yet" — the catalog stays out of L2 and
25
25
  * the supervisor warns once per isolate.
26
26
  */
27
- export const RUNTIME_CATALOG_SHA256 = "de5f40e035887976ba2fd4611cada83c4fcbff774637eb7c954c55dd1d1c5eae";
27
+ export const RUNTIME_CATALOG_SHA256 = "9cdc9cc0d96667234c6fed2adc81e7890fef96b3afe5bd80dd80612e822d3d3a";
@@ -9,28 +9,8 @@
9
9
  */
10
10
  import { type SessionAiHost } from './ai.js';
11
11
  import { type ProgrammaticHost } from './programmatic.js';
12
- interface AgentStorage {
13
- get(key: string): Promise<unknown>;
14
- put(key: string, value: unknown): Promise<void>;
15
- delete(key: string): Promise<void>;
16
- deleteAll(): Promise<void>;
17
- deleteAlarm(): Promise<void>;
18
- list<T = unknown>(options: {
19
- prefix: string;
20
- }): Promise<Map<string, T>>;
21
- transaction<T>(body: (txn: {
22
- get(key: string): Promise<unknown>;
23
- put(key: string, value: unknown): Promise<void>;
24
- delete(key: string): Promise<unknown>;
25
- list<T2 = unknown>(options: {
26
- prefix: string;
27
- }): Promise<Map<string, T2>>;
28
- }) => Promise<T>): Promise<T>;
29
- }
30
12
  interface Host extends ProgrammaticHost, SessionAiHost {
31
- ctx: {
32
- storage: AgentStorage;
33
- };
13
+ ctx: ProgrammaticHost['ctx'];
34
14
  env: ProgrammaticHost['env'] & Record<string, unknown>;
35
15
  }
36
16
  interface OAuthStatePayload {
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/session/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAiB3B,UAAU,YAAY;IACpB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IACxE,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE;QACzB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;KAC3E,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CAC/B;AAED,UAAU,IAAK,SAAQ,gBAAgB,EAAE,aAAa;IACpD,GAAG,EAAE;QAAE,OAAO,EAAE,YAAY,CAAA;KAAE,CAAC;IAC/B,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxD;AAED,UAAU,iBAAiB;IACzB,CAAC,EAAE,CAAC,CAAC;IACL,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA2BD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2ClG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAQxF"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/session/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgCH,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,SAAS,CAAC;AACjB,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAkB3B,UAAU,IAAK,SAAQ,gBAAgB,EAAE,aAAa;IACpD,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC7B,GAAG,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxD;AAED,UAAU,iBAAiB;IACzB,CAAC,EAAE,CAAC,CAAC;IACL,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB;AA2BD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CA2ClG;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI,CAQxF"}
@@ -40,6 +40,7 @@
40
40
  */
41
41
  import type { LanguageModel } from 'ai';
42
42
  import { z } from 'zod/v4';
43
+ import type { PortRegistry } from '@nimbus-sh/core/runtime/port-registry.js';
43
44
  import { type NimbusCloudflareAccount } from './agent-oauth.js';
44
45
  export interface SessionAiHost {
45
46
  env: Record<string, unknown>;
@@ -47,10 +48,13 @@ export interface SessionAiHost {
47
48
  storage: {
48
49
  get(key: string): Promise<unknown>;
49
50
  put(key: string, value: unknown): Promise<void>;
50
- delete(key: string): Promise<void>;
51
+ delete(key: string): Promise<boolean | void>;
51
52
  };
52
53
  };
53
54
  }
55
+ export declare function routeSessionLoopback(host: SessionAiHost & {
56
+ portRegistry: PortRegistry;
57
+ }, port: number, request: Request): Promise<Response | null>;
54
58
  /** DO storage key holding this session's Cloudflare credential of record. */
55
59
  export declare const SESSION_AI_CREDENTIAL_KEY = "nimbus:ai:credential";
56
60
  export declare const DEFAULT_SESSION_AI_MODEL = "@cf/zai-org/glm-5.2";
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/session/ai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/session/ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAG7E,OAAO,EAUL,KAAK,uBAAuB,EAC7B,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,GAAG,EAAE;QACH,OAAO,EAAE;YACP,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;YACnC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;SAC9C,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,aAAa,GAAG;IAAE,YAAY,EAAE,YAAY,CAAA;CAAE,EACpD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAI1B;AAED,6EAA6E;AAC7E,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAShE,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,eAAO,MAAM,6BAA6B,YAAY,CAAC;AAmBvD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,aAAa,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,oBAAoB,GAAG,iBAAiB,CAAC;IAC/C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,oBAAoB,CAAA;CAAE,GAC9C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,CAAA;CAAE,CAAC;AAEhD,QAAA,MAAM,sBAAsB;;;;;iBAK1B,CAAC;AAEH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAyC/D,iFAAiF;AACjF,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,mBAAmB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAUrD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,CAQjF;AAID;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBrG;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+BlG;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhB;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;IAC9E,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,uBAAuB,EAAE,CAAC;IACpC,IAAI,EAAE,OAAO,CAAC;CACf,CAAC,CASD;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM1G;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,aAAa,GAAG,aAAa,CAQvE;AAED,iFAAiF;AACjF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKlG;AAED,uDAAuD;AACvD,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED,wEAAwE;AACxE,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAEnG;AAID;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkCrG"}
@@ -41,8 +41,15 @@
41
41
  import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
42
42
  import { z } from 'zod/v4';
43
43
  import { NIMBUS_AI_GATEWAY_PORT } from '@nimbus-sh/core/constants.js';
44
+ import { routeRuntimeLoopback } from './loopback.js';
44
45
  import { NIMBUS_AI_TOKEN_ENV, mintSessionAiToken } from '@nimbus-sh/core/_shared/ai-egress.js';
45
46
  import { NIMBUS_AGENT_AUTH_COOKIE, NIMBUS_CLOUDFLARE_API, fetchNimbusCloudflareAccounts, fetchNimbusCloudflareUserInfo, loadNimbusAgentOAuthFromRequest, readNimbusAgentCookieSecret, readNimbusAgentOAuthConfig, readNimbusCookie, requestNimbusCloudflareOAuthToken, } from './agent-oauth.js';
47
+ export function routeSessionLoopback(host, port, request) {
48
+ // A credential-backed gateway is private, not a shareable port entry.
49
+ if (port === NIMBUS_AI_GATEWAY_PORT)
50
+ return handleSessionAiRequest(host, request);
51
+ return routeRuntimeLoopback(host.portRegistry, port, request);
52
+ }
46
53
  /** DO storage key holding this session's Cloudflare credential of record. */
47
54
  export const SESSION_AI_CREDENTIAL_KEY = 'nimbus:ai:credential';
48
55
  /**
@@ -80,6 +80,7 @@ export declare function wireHibernationOnConstruct(ctx: any): WsHibernationConfi
80
80
  * (per /api/_test/hib/simulate flow; plan §VI.7 F.2 invariant).
81
81
  */
82
82
  export declare function wireProcessLogPersist(host: HibHost, ctx: any): void;
83
+ export declare function installLogPersistence(host: Pick<HibHost, '_w9PersistWired' | '_w9SchemaInit' | 'processes'>, ctx: DurableObjectState, onActivity: () => void): void;
83
84
  /**
84
85
  * W1: arm the log-janitor alarm cycle for this instance. Called from the
85
86
  * log-activity hook so only sessions that actually produce process logs
@@ -103,7 +104,7 @@ export declare function wireProcessLogPersist(host: HibHost, ctx: any): void;
103
104
  export declare function clearDestroyedTombstone(host: HibHost, ctx: any): void;
104
105
  export declare function ensureLogJanitor(host: HibHost, ctx: any): void;
105
106
  /** W9: idempotent SQL schema bootstrap. */
106
- export declare function ensureHibSchema(host: HibHost, ctx: any): void;
107
+ export declare function ensureHibSchema(host: Pick<HibHost, '_w9SchemaInit'>, ctx: any): void;
107
108
  /**
108
109
  * W1: this session's canonical alarm-reason strings, registered on the
109
110
  * fabric's reason map. Forward-compat: the dispatcher silently drops unknown
@@ -1 +1 @@
1
- {"version":3,"file":"hibernation.d.ts","sourceRoot":"","sources":["../../src/session/hibernation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,EAA0B,KAAK,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACpH,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGrE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,SAAS,EAAE,wBAAwB,CAAC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;IACzB,uEAAuE;IACvE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,GAAG,GAAG,yBAAyB,CAY9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CA6GnE;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAc9D;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqB7D;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAEzE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqB9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,GAAG,EACR,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC7C,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC1C,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAMhD"}
1
+ {"version":3,"file":"hibernation.d.ts","sourceRoot":"","sources":["../../src/session/hibernation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uDAAuD,CAAC;AACtG,OAAO,EAA0B,KAAK,yBAAyB,EAAE,MAAM,4CAA4C,CAAC;AACpH,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAGrE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACxC,SAAS,EAAE,wBAAwB,CAAC;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,GAAG,CAAC;IACnB,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;IACzB,uEAAuE;IACvE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,GAAG,GAAG,yBAAyB,CAY9E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAKnE;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,GAAG,WAAW,CAAC,EACtE,GAAG,EAAE,kBAAkB,EACvB,UAAU,EAAE,MAAM,IAAI,GACrB,IAAI,CA0GN;AAED;;;;;;;;;;GAUG;AACH;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAMrE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAc9D;AAED,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqBpF;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,iBAAiB,CAAC;AAEzE;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAqB9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,GAAG,EACR,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EAC7C,oBAAoB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC1C,SAAS,CAAC,EAAE,mBAAmB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAMhD"}
@@ -75,6 +75,12 @@ export function wireHibernationOnConstruct(ctx) {
75
75
  * (per /api/_test/hib/simulate flow; plan §VI.7 F.2 invariant).
76
76
  */
77
77
  export function wireProcessLogPersist(host, ctx) {
78
+ installLogPersistence(host, ctx, () => {
79
+ scheduleHibFlush(host, ctx);
80
+ ensureLogJanitor(host, ctx);
81
+ });
82
+ }
83
+ export function installLogPersistence(host, ctx, onActivity) {
78
84
  if (host._w9PersistWired)
79
85
  return;
80
86
  host._w9PersistWired = true;
@@ -174,10 +180,7 @@ export function wireProcessLogPersist(host, ctx) {
174
180
  // every boot, including boots caused by a destroyed session's own
175
181
  // leftover alarm, making every session DO ever created fire an alarm
176
182
  // every ~60s forever (see dispatchAlarm's re-arm condition below).
177
- host.processes.setLogPersist(adapter, () => {
178
- scheduleHibFlush(host, ctx);
179
- ensureLogJanitor(host, ctx);
180
- });
183
+ host.processes.setLogPersist(adapter, onActivity);
181
184
  }
182
185
  /**
183
186
  * W1: arm the log-janitor alarm cycle for this instance. Called from the
@@ -1,38 +1,3 @@
1
- /**
2
- * session/init.ts — initSession boot + shell-command registrations.
3
- *
4
- * Why this is one big function and not a class:
5
- * initSession runs once per /ws upgrade and walks the session
6
- * through Phase R (rehydrate from SQL), Phase B (compose the
7
- * workspace + register the session's commands), Phase W (attach
8
- * terminal), and (cold-only) Phase O (MOTD + framework hint). The
9
- * phases share lots of locals (vfs, kernel, registry, shell) and
10
- * ordering matters strictly — there's no interesting reuse boundary
11
- * that a class decomposition would expose.
12
- *
13
- * What it no longer does is COMPOSE the operating system. The kernel,
14
- * the provider mounts, the command registry, the coreutils, the exec
15
- * resolver, the default environment and the shell come from
16
- * `NimbusWorkspace` (@nimbus-sh/core/workspace), which an embedder off
17
- * Cloudflare builds the same way. What stays here is everything that
18
- * only makes sense with a socket, a Durable Object and a product behind
19
- * it: the terminal and its scrollback, the phase machine, the persisted
20
- * shell state, npm, git, vite, wrangler and the facet-backed runtimes.
21
- *
22
- * The function is intentionally written so that a reader sees:
23
- * 1. setPhase('rehydrate') ...
24
- * 2. setPhase('build') ... (~95% of the LOC)
25
- * 3. setPhase('online') if (cold)
26
- * 4. self._b4Phase = 'hydrated'
27
- *
28
- * `self` is typed as InitHost, a narrow view of SessionInternal plus readonly
29
- * ctx/env, so this module can use the session internals it owns without
30
- * depending on the full Durable Object class surface.
31
- *
32
- * Imports and class delegators on NimbusSession preserve back-compat:
33
- * - acceptShellWebSocket → self.initSession(ws) (S7 will extract).
34
- * - The class still has `initSession(ws)` as a delegator method.
35
- */
36
1
  import type { SessionInternal } from './internal.js';
37
2
  /**
38
3
  * `initSession` reads `this.ctx` and `this.env` extensively (~14 sites).
@@ -61,6 +26,6 @@ type InitHost = SessionInternal & {
61
26
  export interface InitSessionOptions {
62
27
  resume?: 'reconnect' | 'wake';
63
28
  }
64
- export declare function initSession(self: InitHost, ws: WebSocket, options?: InitSessionOptions): Promise<void>;
29
+ export declare function initSession(self: InitHost, ws: WebSocket | null, options?: InitSessionOptions): Promise<void>;
65
30
  export {};
66
31
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAkFH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;GAQG;AACH,KAAK,QAAQ,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAAC;AAQ3E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC/B;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,SAAS,EACb,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAgsEf"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;GAQG;AACH,KAAK,QAAQ,GAAG,eAAe,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAA;CAAE,CAAC;AAQ3E;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CAC/B;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,QAAQ,EACd,EAAE,EAAE,SAAS,GAAG,IAAI,EACpB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAkcf"}