@nimbus-sh/worker 0.2.2 → 0.3.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 (131) hide show
  1. package/README.md +5 -2
  2. package/dist/_shared/session-router.d.ts +8 -0
  3. package/dist/_shared/session-router.d.ts.map +1 -1
  4. package/dist/_shared/session-router.js +8 -0
  5. package/dist/facets/cirrus-real.js +1 -1
  6. package/dist/facets/manager.d.ts +42 -104
  7. package/dist/facets/manager.d.ts.map +1 -1
  8. package/dist/facets/manager.js +126 -283
  9. package/dist/facets/opencode-staging.d.ts +1 -1
  10. package/dist/facets/opencode-staging.d.ts.map +1 -1
  11. package/dist/facets/opencode-staging.js +4 -0
  12. package/dist/facets/vite-dev-server.d.ts +2 -2
  13. package/dist/facets/vite-dev-server.js +4 -4
  14. package/dist/git/commands.d.ts +8 -0
  15. package/dist/git/commands.d.ts.map +1 -1
  16. package/dist/git/commands.js +41 -9
  17. package/dist/git/network-facet.d.ts +1 -1
  18. package/dist/git/network-facet.d.ts.map +1 -1
  19. package/dist/git/network-facet.js +35 -12
  20. package/dist/git-bundle.generated.d.ts +2 -2
  21. package/dist/git-bundle.generated.d.ts.map +1 -1
  22. package/dist/git-bundle.generated.js +3 -3
  23. package/dist/index.js +1 -1
  24. package/dist/loaders/child-process/spawn-facet.js +1 -1
  25. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
  26. package/dist/loaders/child-process/spawn-pool.js +2 -2
  27. package/dist/loaders/generated-workers.d.ts +1 -1
  28. package/dist/loaders/generated-workers.d.ts.map +1 -1
  29. package/dist/loaders/generated-workers.js +2 -2
  30. package/dist/loaders/npm-resolve-preamble.d.ts +3 -3
  31. package/dist/loaders/npm-resolve-preamble.js +3 -3
  32. package/dist/loaders/pre-bundle-preamble.d.ts +5 -5
  33. package/dist/loaders/pre-bundle-preamble.js +6 -6
  34. package/dist/loaders/process-host.d.ts +6 -107
  35. package/dist/loaders/process-host.d.ts.map +1 -1
  36. package/dist/loaders/process-host.js +6 -405
  37. package/dist/npm/install-batch-facet.js +1 -1
  38. package/dist/npm/installer.d.ts +4 -4
  39. package/dist/npm/installer.js +18 -18
  40. package/dist/npm/pre-bundle-facet.d.ts +2 -2
  41. package/dist/npm/pre-bundle-facet.js +5 -5
  42. package/dist/npm/resolve-facet.d.ts +1 -1
  43. package/dist/npm/resolve-facet.js +1 -1
  44. package/dist/npm/resolve-one-facet.d.ts +5 -5
  45. package/dist/npm/resolve-one-facet.js +5 -5
  46. package/dist/router/index.js +1 -1
  47. package/dist/router/remote-api.js +8 -0
  48. package/dist/runtime/bun-repl.d.ts +1 -1
  49. package/dist/runtime/bun-repl.js +3 -3
  50. package/dist/runtime/facet-loader-host.d.ts +5 -8
  51. package/dist/runtime/facet-loader-host.d.ts.map +1 -1
  52. package/dist/runtime/facet-loader-host.js +7 -11
  53. package/dist/runtime/node-repl.js +2 -2
  54. package/dist/runtime/python-repl.js +3 -3
  55. package/dist/runtime/ruby-repl.js +2 -2
  56. package/dist/runtime/ruby-resident.js +1 -1
  57. package/dist/session/hibernation.d.ts +18 -51
  58. package/dist/session/hibernation.d.ts.map +1 -1
  59. package/dist/session/hibernation.js +49 -186
  60. package/dist/session/init-phases.d.ts +2 -2
  61. package/dist/session/init-phases.d.ts.map +1 -1
  62. package/dist/session/init-phases.js +1 -1
  63. package/dist/session/init.d.ts.map +1 -1
  64. package/dist/session/init.js +16 -2
  65. package/dist/session/keys.d.ts +14 -35
  66. package/dist/session/keys.d.ts.map +1 -1
  67. package/dist/session/keys.js +17 -35
  68. package/dist/session/nimbus-session.d.ts +10 -4
  69. package/dist/session/nimbus-session.d.ts.map +1 -1
  70. package/dist/session/nimbus-session.js +20 -11
  71. package/dist/session/port-capability.d.ts +43 -0
  72. package/dist/session/port-capability.d.ts.map +1 -0
  73. package/dist/session/port-capability.js +49 -0
  74. package/dist/session/programmatic.d.ts +41 -5
  75. package/dist/session/programmatic.d.ts.map +1 -1
  76. package/dist/session/programmatic.js +147 -15
  77. package/dist/session/routes.d.ts +2 -0
  78. package/dist/session/routes.d.ts.map +1 -1
  79. package/dist/session/routes.js +91 -16
  80. package/dist/session/rpc.d.ts +35 -8
  81. package/dist/session/rpc.d.ts.map +1 -1
  82. package/dist/session/rpc.js +73 -14
  83. package/dist/session/start-real-vite.d.ts.map +1 -1
  84. package/dist/session/start-real-vite.js +2 -0
  85. package/dist/session/state-store.d.ts +3 -2
  86. package/dist/session/state-store.d.ts.map +1 -1
  87. package/dist/session/state-store.js +3 -2
  88. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  89. package/dist/session/supervisor-rpc.js +5 -0
  90. package/dist/session/ws.d.ts +2 -2
  91. package/dist/session/ws.d.ts.map +1 -1
  92. package/dist/session/ws.js +2 -2
  93. package/dist/wrangler/nimbus-wrangler.js +1 -1
  94. package/package.json +3 -2
  95. package/scripts/bundle-runtime.mjs +5 -2
  96. package/dist/facets/inner-do-registry.d.ts +0 -41
  97. package/dist/facets/inner-do-registry.d.ts.map +0 -1
  98. package/dist/facets/inner-do-registry.js +0 -51
  99. package/dist/facets/launch-pacer.d.ts +0 -111
  100. package/dist/facets/launch-pacer.d.ts.map +0 -1
  101. package/dist/facets/launch-pacer.js +0 -130
  102. package/dist/loaders/fanout-pool.d.ts +0 -207
  103. package/dist/loaders/fanout-pool.d.ts.map +0 -1
  104. package/dist/loaders/fanout-pool.js +0 -363
  105. package/dist/loaders/loader-pool.d.ts +0 -294
  106. package/dist/loaders/loader-pool.d.ts.map +0 -1
  107. package/dist/loaders/loader-pool.js +0 -642
  108. package/dist/loaders/process-fabric.d.ts +0 -509
  109. package/dist/loaders/process-fabric.d.ts.map +0 -1
  110. package/dist/loaders/process-fabric.js +0 -360
  111. package/dist/loaders/vendor/errors.d.ts +0 -24
  112. package/dist/loaders/vendor/errors.d.ts.map +0 -1
  113. package/dist/loaders/vendor/errors.js +0 -46
  114. package/dist/loaders/vendor/serialize.d.ts +0 -3
  115. package/dist/loaders/vendor/serialize.d.ts.map +0 -1
  116. package/dist/loaders/vendor/serialize.js +0 -25
  117. package/dist/loaders/vendor/types.d.ts +0 -69
  118. package/dist/loaders/vendor/types.d.ts.map +0 -1
  119. package/dist/loaders/vendor/types.js +0 -4
  120. package/dist/loaders/workerd-facet-host.d.ts +0 -141
  121. package/dist/loaders/workerd-facet-host.d.ts.map +0 -1
  122. package/dist/loaders/workerd-facet-host.js +0 -284
  123. package/dist/session/bindings.d.ts +0 -209
  124. package/dist/session/bindings.d.ts.map +0 -1
  125. package/dist/session/bindings.js +0 -680
  126. package/dist/session/ctx-exports.d.ts +0 -16
  127. package/dist/session/ctx-exports.d.ts.map +0 -1
  128. package/dist/session/ctx-exports.js +0 -22
  129. package/dist/session/ws-hibernation-config.d.ts +0 -64
  130. package/dist/session/ws-hibernation-config.d.ts.map +0 -1
  131. package/dist/session/ws-hibernation-config.js +0 -89
@@ -18,11 +18,15 @@
18
18
  * w9_proc_logs + w9_proc_exits.
19
19
  * - scheduleHibFlush(host, ctx) — debounced setTimeout + best-effort
20
20
  * setAlarm for post-hibernation drain.
21
- * - dispatchAlarm(host) — alarm() handler body.
22
- * - maybeBumpIsolateGen(host, ctx) — increment + persist isolate-gen
23
- * counter once per fresh isolate.
21
+ * - dispatchAlarm(host) — alarm() handler body: the fabric's generic
22
+ * reason dispatcher with this session's handlers registered.
24
23
  * - flushOnClose(host) — synchronous flush on ws close.
25
24
  *
25
+ * The alarm multiplexer itself (reason map, scheduleAlarm, the per-instance
26
+ * chain) and maybeBumpIsolateGen are fabric machinery —
27
+ * `@nimbus-sh/fabric/alarms.js`; this module registers the session's reasons
28
+ * ('w9-flush' | 'log-janitor' | 'resident-launch') on top of it.
29
+ *
26
30
  * **`ctx` taken as a separate arg from `host`** because the parent
27
31
  * `CloudflareDurableObject` class declares `ctx` as `protected`, which
28
32
  * is nominal-typed in TS and cannot appear on a public interface
@@ -34,8 +38,9 @@
34
38
  * responsible for setting `host._w9PersistWired = false` BEFORE calling
35
39
  * wireProcessLogPersist again.
36
40
  */
37
- import { configureWsHibernation } from './ws-hibernation-config.js';
38
- import { SESSION_DESTROYED_KEY, W9_ISOLATE_GEN_KEY, W9_FLUSH_DEBOUNCE_MS, W1_NEXT_ALARM_REASONS_KEY } from './keys.js';
41
+ import { configureWsHibernation } from '@nimbus-sh/fabric/ws-hibernation-config.js';
42
+ import { dispatchAlarm as dispatchAlarmReasons, scheduleAlarm, } from '@nimbus-sh/fabric/alarms.js';
43
+ import { SESSION_DESTROYED_KEY, W9_FLUSH_DEBOUNCE_MS } from './keys.js';
39
44
  /**
40
45
  * Run at DO ctor time. Returns the result for the class to assign to
41
46
  * `_w9WsConfig`. Failures are non-fatal — older workerd builds may lack
@@ -241,59 +246,6 @@ export function ensureHibSchema(host, ctx) {
241
246
  host._w9SchemaInit = false; // retry next time
242
247
  }
243
248
  }
244
- /**
245
- * W1: schedule (or re-schedule) an alarm reason. Coordinated via a
246
- * single map in DO storage so multiple subsystems (W9 debounced flush +
247
- * W1 log-janitor sweep) don't clobber each other's `setAlarm()` calls.
248
- *
249
- * Semantics:
250
- * - Reads the existing reasons map.
251
- * - Sets `map[reason] = whenMs` IF `whenMs` is sooner than the
252
- * currently-pending deadline for that reason (or no entry exists).
253
- * Later-than-pending requests are silently ignored — the existing
254
- * alarm will fire and re-arm anyway.
255
- * - Writes the map back and calls `ctx.storage.setAlarm(min(deadlines))`.
256
- *
257
- * Cost: 1 storage read + 1 storage write + 1 setAlarm per call. setAlarm
258
- * itself is billed as 1 row written per DO pricing. At W1's 60s
259
- * cadence, this is ~$0.05/mo/session at scale — dwarfed by the
260
- * hibernation duration savings.
261
- *
262
- * Fail-soft: any throw is swallowed with a warn. On older runtimes /
263
- * wrangler-dev where setAlarm is unavailable, this is a no-op (the
264
- * subsystem's in-isolate setTimeout fallback continues to work).
265
- */
266
- export function scheduleAlarm(host, ctx, reason, whenMs) {
267
- // Serialize every read-modify-write of the reasons map through one
268
- // per-instance chain: scheduleHibFlush and ensureLogJanitor fire
269
- // back-to-back from the same log-activity hook, and two interleaved
270
- // get→put cycles would silently drop whichever reason wrote first.
271
- const run = async () => {
272
- try {
273
- const setAlarmFn = ctx?.storage?.setAlarm;
274
- if (typeof setAlarmFn !== 'function')
275
- return false;
276
- const existing = (await ctx.storage.get(W1_NEXT_ALARM_REASONS_KEY));
277
- const map = { ...(existing || {}) };
278
- // Earliest-deadline-first: only update if new request is sooner or
279
- // this reason has no pending entry.
280
- if (!(reason in map) || whenMs < map[reason]) {
281
- map[reason] = whenMs;
282
- await ctx.storage.put(W1_NEXT_ALARM_REASONS_KEY, map);
283
- }
284
- const earliest = Math.min(...Object.values(map));
285
- setAlarmFn.call(ctx.storage, earliest);
286
- return true;
287
- }
288
- catch (e) {
289
- console.warn('[nimbus/W1] scheduleAlarm threw:', e?.message);
290
- return false;
291
- }
292
- };
293
- const chained = (host._w1AlarmChain ?? Promise.resolve()).then(run, run);
294
- host._w1AlarmChain = chained;
295
- return chained;
296
- }
297
249
  /**
298
250
  * W9: ensure the alarm is set for the next flush window. Cheap to
299
251
  * call repeatedly — we only schedule the in-isolate flush timer if
@@ -325,148 +277,59 @@ export function scheduleHibFlush(host, ctx) {
325
277
  void scheduleAlarm(host, ctx, 'w9-flush', Date.now() + W9_FLUSH_DEBOUNCE_MS * 4);
326
278
  }
327
279
  /**
328
- * W1: multi-reason alarm dispatcher. Called from the DO's `alarm()`
329
- * handler.
330
- *
331
- * For each pending reason whose deadline has passed, run its handler.
332
- * Reasons supported today:
280
+ * W1: this session's alarm() handler body — the fabric's multi-reason
281
+ * dispatcher with this session's handlers registered:
333
282
  * - `'w9-flush'` → processes.flushLogs()
283
+ * - `'resident-launch'` → pumpResidentLaunches()
334
284
  * - `'log-janitor'` → processes.dropLogsOlderThan(orphanCheck); re-arm
335
- * for next 60s cycle.
285
+ * for next 60s cycle while the session still has anything to sweep.
336
286
  *
337
287
  * `janitorOrphanCheck` is the orphan-pid predicate provided by the
338
288
  * caller (typically `(pid) => !host.processes.get(pid)`). Decoupled
339
289
  * so HibHost doesn't need to import ProcessTable.
340
- *
341
- * After running fireable reasons, re-arms `ctx.storage.setAlarm` at the
342
- * earliest remaining deadline. If no reasons remain, deletes the map
343
- * key and does NOT call setAlarm — the DO becomes hibernation-eligible
344
- * after the 10s idle window.
345
- *
346
- * Forward/back-compat: unknown reasons silently dropped.
347
290
  */
348
291
  export function dispatchAlarm(host, ctx, janitorOrphanCheck, pumpResidentLaunches) {
349
- // Same serialization as scheduleAlarm: the dispatcher's read→handlers→write
350
- // cycle must not interleave with a log-activity scheduleAlarm.
351
- const chained = (host._w1AlarmChain ?? Promise.resolve()).then(() => dispatchAlarmBody(host, ctx, janitorOrphanCheck, pumpResidentLaunches), () => dispatchAlarmBody(host, ctx, janitorOrphanCheck, pumpResidentLaunches));
352
- host._w1AlarmChain = chained;
353
- return chained;
354
- }
355
- async function dispatchAlarmBody(host, ctx, janitorOrphanCheck, pumpResidentLaunches) {
356
- try {
357
- const now = Date.now();
358
- const existing = (await ctx?.storage?.get?.(W1_NEXT_ALARM_REASONS_KEY));
292
+ return dispatchAlarmReasons(host, ctx, {
293
+ 'w9-flush': () => {
294
+ host.processes.flushLogs();
295
+ },
296
+ 'resident-launch': async () => {
297
+ // Awaited, not fired and forgotten: this invocation is the fresh
298
+ // turn the launch asked for, and it has to stay the one paying for
299
+ // the chunk it just released.
300
+ await pumpResidentLaunches?.();
301
+ },
302
+ 'log-janitor': (now) => {
303
+ host.processes.dropLogsOlderThan(undefined, janitorOrphanCheck);
304
+ // Re-arm only while the session still has running processes or
305
+ // buffered logs to sweep. An idle, abandoned, or destroyed
306
+ // session must NOT keep an eternal 60s alarm loop alive: the
307
+ // janitor used to self-renew unconditionally (and the DO
308
+ // constructor re-armed it on every alarm-triggered boot), so
309
+ // every session ever created kept booting its DO every ~60s
310
+ // forever. The accumulated fleet of deleted probe sessions
311
+ // produced continuous DO-storage churn (measured ~24 zombie
312
+ // boots/s on 2026-07-13) that intermittently reset LIVE
313
+ // session DOs mid-run ("Internal error in Durable Object
314
+ // storage caused object to be reset"). The next log append
315
+ // re-arms the cycle via ensureLogJanitor.
316
+ if (host.processes.stats.running > 0 || host.processes.logStats.totalPids > 0) {
317
+ return { rearmAt: now + 60_000 };
318
+ }
319
+ host._w1JanitorArmed = false;
320
+ },
321
+ }, () => {
359
322
  // Legacy path: pre-W1 deploys had no map. dispatchAlarm was called
360
323
  // with no map and unconditionally ran the log flush. Preserve
361
324
  // that on a missing map (one-time post-deploy, then the map is
362
325
  // populated by the next scheduleHibFlush / scheduleAlarm call).
363
- if (!existing || Object.keys(existing).length === 0) {
364
- try {
365
- host.processes.flushLogs();
366
- }
367
- catch (e) {
368
- console.warn('[nimbus/W9] legacy flush threw:', e?.message);
369
- }
370
- return;
371
- }
372
- const map = { ...existing };
373
- // Snapshot fireable reasons BEFORE running any of them, so a
374
- // handler that schedules itself for the next cycle doesn't get
375
- // immediately re-fired in the same dispatch.
376
- const fired = [];
377
- for (const [reason, when] of Object.entries(map)) {
378
- if (when <= now)
379
- fired.push(reason);
380
- }
381
- for (const reason of fired) {
382
- delete map[reason];
383
- try {
384
- if (reason === 'w9-flush') {
385
- host.processes.flushLogs();
386
- }
387
- else if (reason === 'resident-launch') {
388
- // Awaited, not fired and forgotten: this invocation is the fresh
389
- // turn the launch asked for, and it has to stay the one paying for
390
- // the chunk it just released.
391
- await pumpResidentLaunches?.();
392
- }
393
- else if (reason === 'log-janitor') {
394
- host.processes.dropLogsOlderThan(undefined, janitorOrphanCheck);
395
- // Re-arm only while the session still has running processes or
396
- // buffered logs to sweep. An idle, abandoned, or destroyed
397
- // session must NOT keep an eternal 60s alarm loop alive: the
398
- // janitor used to self-renew unconditionally (and the DO
399
- // constructor re-armed it on every alarm-triggered boot), so
400
- // every session ever created kept booting its DO every ~60s
401
- // forever. The accumulated fleet of deleted probe sessions
402
- // produced continuous DO-storage churn (measured ~24 zombie
403
- // boots/s on 2026-07-13) that intermittently reset LIVE
404
- // session DOs mid-run ("Internal error in Durable Object
405
- // storage caused object to be reset"). The next log append
406
- // re-arms the cycle via ensureLogJanitor.
407
- if (host.processes.stats.running > 0 || host.processes.logStats.totalPids > 0) {
408
- map['log-janitor'] = now + 60_000;
409
- }
410
- else {
411
- host._w1JanitorArmed = false;
412
- }
413
- }
414
- // Unknown reasons silently dropped (forward-compat).
415
- }
416
- catch (e) {
417
- console.warn(`[nimbus/W1] dispatch ${reason} threw:`, e?.message);
418
- }
419
- }
420
- // Re-arm or clear.
421
- const setAlarmFn = ctx?.storage?.setAlarm;
422
- if (Object.keys(map).length > 0) {
423
- await ctx.storage.put(W1_NEXT_ALARM_REASONS_KEY, map);
424
- const earliest = Math.min(...Object.values(map));
425
- if (typeof setAlarmFn === 'function') {
426
- setAlarmFn.call(ctx.storage, earliest);
427
- }
326
+ try {
327
+ host.processes.flushLogs();
428
328
  }
429
- else {
430
- try {
431
- await ctx.storage.delete(W1_NEXT_ALARM_REASONS_KEY);
432
- }
433
- catch { }
434
- // No remaining reasons → no setAlarm call → DO becomes
435
- // hibernation-eligible after the 10s idle window.
329
+ catch (e) {
330
+ console.warn('[nimbus/W9] legacy flush threw:', e?.message);
436
331
  }
437
- }
438
- catch (e) {
439
- console.warn('[nimbus/W1] dispatchAlarm threw:', e?.message);
440
- }
441
- }
442
- /** W9: increment + persist isolate-gen counter once per fresh isolate. */
443
- export async function maybeBumpIsolateGen(host, ctx) {
444
- if (host._w9IsolateGenPersisted)
445
- return;
446
- host._w9IsolateGenPersisted = true;
447
- try {
448
- const prev = (await ctx.storage.get(W9_ISOLATE_GEN_KEY));
449
- // Adopt the persisted truth first, and adopt the bump only after the
450
- // put resolves. An unpersisted `next` would be re-read as `prev` by the
451
- // NEXT boot and re-issued — two instances sharing one generation is
452
- // exactly the pid-aliasing this counter exists to prevent. Running on
453
- // the previous persisted generation is the lesser lapse, and the
454
- // put-failure case is replica-only in practice (replicas never spawn).
455
- //
456
- // What holds the guarantee is the output gate, not this await: measured,
457
- // the block body resolves in 0 ms even with a confirmed put, because
458
- // `await storage.put()` returns before durability. The gate is what
459
- // keeps a pid from generation N from escaping before N is durable, which
460
- // is why marking this put `allowUnconfirmed` is not a free speedup — see
461
- // scratchpad/coldstart-s1.md.
462
- host._w9IsolateGen = typeof prev === 'number' ? prev : 0;
463
- const next = host._w9IsolateGen + 1;
464
- await ctx.storage.put(W9_ISOLATE_GEN_KEY, next);
465
- host._w9IsolateGen = next;
466
- }
467
- catch (e) {
468
- console.warn('[nimbus/W9] isolate-gen bump failed:', e?.message);
469
- }
332
+ });
470
333
  }
471
334
  /**
472
335
  * W9: synchronous flush of the process-log ring on session close.
@@ -40,7 +40,7 @@ import { type SessionState } from '@nimbus-sh/core/observability/oom-discriminat
40
40
  */
41
41
  export declare function setPhase(self: {
42
42
  _b4Phase: SessionState | null;
43
- _w9IsolateGen?: number;
43
+ _isolateGen?: number;
44
44
  }, toState: SessionState, trigger: string): void;
45
45
  /**
46
46
  * [B'.5] Identify the original phase-based warm-rejoin case. The /ws
@@ -93,7 +93,7 @@ export declare function joinExistingSession(self: {
93
93
  write(s: string): void;
94
94
  };
95
95
  _b4Phase: SessionState | null;
96
- _w9IsolateGen?: number;
96
+ _isolateGen?: number;
97
97
  _b4WarmJoinCount: number;
98
98
  }, ws: WebSocket, appendScrollback: (ctx: any, data: string, atMs: number) => void, loadScrollback: (ctx: any) => string): void;
99
99
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"init-phases.d.ts","sourceRoot":"","sources":["../../src/session/init-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,oDAAoD,CAAC;AAE5G;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,EAC/D,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;CACxC,GAAG,OAAO,CAKV;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,iBAAiB,CAmBnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE;IACJ,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAChE,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAsCN"}
1
+ {"version":3,"file":"init-phases.d.ts","sourceRoot":"","sources":["../../src/session/init-phases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,oDAAoD,CAAC;AAE5G;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7D,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC;CACxC,GAAG,OAAO,CAKV;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,iBAAiB,CAmBnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE;IACJ,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,EAAE;QAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACpG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,gBAAgB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,EAChE,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAsCN"}
@@ -47,7 +47,7 @@ export function setPhase(self, toState, trigger) {
47
47
  fromState,
48
48
  toState,
49
49
  trigger,
50
- isolateGen: self._w9IsolateGen ?? 0,
50
+ isolateGen: self._isolateGen ?? 0,
51
51
  dataLoss: false,
52
52
  snapshotKeysRehydrated: 0,
53
53
  });
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA6EH,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;AAa3E,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAsrF9E"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AA8EH,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;AAa3E,wBAAsB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAosF9E"}
@@ -76,6 +76,7 @@ import { sessionAiEnv } from './ai.js';
76
76
  import { routeSessionLoopback } from './loopback.js';
77
77
  import { setPhase } from './init-phases.js';
78
78
  import { VITE_CONFIG_KEY } from './keys.js';
79
+ import { clearPortCapability } from './port-capability.js';
79
80
  function resolveNpmPrefix(prefix, cwd) {
80
81
  return prefix.startsWith('/')
81
82
  ? normalizeVfsPath(prefix)
@@ -164,6 +165,17 @@ export async function initSession(self, ws) {
164
165
  self.terminal.write('\x1b[33m[nimbus] this session resumed on a new instance. Anything still '
165
166
  + 'running was lost with the old one — re-run it if it had not finished.\x1b[0m\r\n');
166
167
  }
168
+ // A reset that killed a resident launch left its journal row behind
169
+ // (fabric's ResidentLaunchJournal.recoverInterrupted). The alarm the dying
170
+ // instance was using for launch turns is NOT a trigger recovery can rely
171
+ // on — measured live, a launch killed early in its first chunks rolls the
172
+ // alarm-map put back with the rest of the dying turn, so the replacement
173
+ // instance never fires an alarm at all. What always follows a dead session
174
+ // is this reconnect, so recovery runs here: after the terminal exists (the
175
+ // report lands in front of the user, live) and after the constructor's
176
+ // pidBase gate (the journal predicate needs this instance's generation).
177
+ // Idempotent per instance; a no-op whenever no launch was interrupted.
178
+ await self.facetManager.pumpResidentLaunches();
167
179
  // [B'.4] Phase B — Build. Compose the workspace (kernel + mounts +
168
180
  // shell + the OS command set), then install the session's own
169
181
  // commands and wiring on top. CPU-intensive phase. Spans from here
@@ -469,7 +481,7 @@ export async function initSession(self, ws) {
469
481
  registerRunnerFactory('cpython-runner', (manifest, installRoot, binName, binKind) => async function pythonReplOrOneShot(ctx) {
470
482
  const argv = ctx.args || [];
471
483
  // No args at all → REPL session. Hand off to runPythonRepl
472
- // which builds its own NimbusLoaderPool (separate from the
484
+ // which builds its own LoaderPool (separate from the
473
485
  // one-shot dispatch's pool) and drives a ReplSession.
474
486
  if (argv.length === 0 && self.terminal) {
475
487
  const { runPythonRepl } = await import('../runtime/python-repl.js');
@@ -1232,6 +1244,7 @@ export async function initSession(self, ws) {
1232
1244
  try {
1233
1245
  const previewStub = makeLongRunningPortStub(self.viteDevServer);
1234
1246
  self.portRegistry.bindFacetStub(previewProcEntry.pid, previewStub);
1247
+ await clearPortCapability(self, previewPort);
1235
1248
  self.portRegistry.register(previewPort, previewProcEntry.pid);
1236
1249
  self._viteShimPid = previewProcEntry.pid;
1237
1250
  self._viteShimPort = previewPort;
@@ -1446,6 +1459,7 @@ export async function initSession(self, ws) {
1446
1459
  // facet uses (Express, Bun.serve, http.createServer().listen()).
1447
1460
  const viteStub = makeLongRunningPortStub(self.viteDevServer);
1448
1461
  self.portRegistry.bindFacetStub(viteProcEntry.pid, viteStub);
1462
+ await clearPortCapability(self, resolvedPort);
1449
1463
  self.portRegistry.register(resolvedPort, viteProcEntry.pid);
1450
1464
  // Track the wiring so `vite stop` and crash-handlers can tear it
1451
1465
  // down without searching the registry.
@@ -2691,7 +2705,7 @@ export async function initSession(self, ws) {
2691
2705
  fromState: fromState,
2692
2706
  toState: 'hydrated',
2693
2707
  trigger: 'init-session',
2694
- isolateGen: self._w9IsolateGen,
2708
+ isolateGen: self._isolateGen,
2695
2709
  dataLoss: false,
2696
2710
  snapshotKeysRehydrated: snapshotKeys,
2697
2711
  });
@@ -17,9 +17,6 @@
17
17
  * These keys persist DO state across deploys. Renaming any key is a
18
18
  * storage migration — never do it without an explicit migration plan.
19
19
  */
20
- /** W9: storage key for the isolate-generation counter (cold-start +
21
- * post-hibernation wake; one increment per fresh isolate). */
22
- export declare const W9_ISOLATE_GEN_KEY = "w9_isolate_gen";
23
20
  /** W9: debounce window in ms before flushing pending process-log writes
24
21
  * to SQL. Hot path (every append schedules a flush via this debounce). */
25
22
  export declare const W9_FLUSH_DEBOUNCE_MS = 250;
@@ -34,25 +31,6 @@ export declare const SESSION_BASE_PATH_KEY = "session-base-path";
34
31
  * hibernation so vite resumes serving after wake without re-running
35
32
  * /api/start-vite. */
36
33
  export declare const VITE_CONFIG_KEY = "vite-config";
37
- /** W1: multi-reason alarm coordination map.
38
- *
39
- * JSON-serialised `Record<reason, deadlineMsEpoch>` where keys are
40
- * canonical reason strings (e.g. 'w9-flush', 'log-janitor'). The
41
- * alarm() dispatcher reads this on fire, dispatches every reason
42
- * whose deadline has passed, and re-arms `ctx.storage.setAlarm` at
43
- * the earliest remaining deadline.
44
- *
45
- * Why a map (not a single nextAlarmAt + reason): two subsystems
46
- * (W9 debounced flush + W1 log-janitor sweep) can have distinct
47
- * deadlines. Without the map, the later setAlarm() call would
48
- * overwrite the earlier reason silently, breaking whichever
49
- * subsystem expected its deadline.
50
- *
51
- * Forward-compat: dispatcher silently drops unknown reasons so a
52
- * rollback from a future deploy that added new reasons doesn't
53
- * leave the alarm stuck.
54
- */
55
- export declare const W1_NEXT_ALARM_REASONS_KEY = "w1_next_alarm_reasons";
56
34
  /**
57
35
  * Destroyed-session tombstone. Written AFTER `storage.deleteAll()` in the
58
36
  * destroy flow so a straggler facet RPC that wakes the dead DO cannot re-arm
@@ -60,22 +38,23 @@ export declare const W1_NEXT_ALARM_REASONS_KEY = "w1_next_alarm_reasons";
60
38
  * metadata is the deliberate cost of keeping destroyed sessions inert.
61
39
  */
62
40
  export declare const SESSION_DESTROYED_KEY = "session_destroyed";
63
- /**
64
- * Prefix for the resident-launch journal: one row per launch in flight, keyed
65
- * by the pid it is building for.
66
- *
67
- * A launch spans many turns and holds its state in memory, so an instance
68
- * reset destroys it silently — the process, the terminal and the work all go
69
- * with the object. The row is what a LATER instance reads to know a launch
70
- * ended that way rather than by finishing: a pid at or below the reader's own
71
- * pid base was allocated by a previous generation (see PID_GEN_STRIDE).
72
- * Written before the launch's first byte of work and removed when it settles,
73
- * so a row that outlives its instance is exactly an interrupted launch.
74
- */
75
- export declare const RESIDENT_LAUNCH_KEY_PREFIX = "resident-launch:";
76
41
  /** Prefix for consumed single-use attach bootstrap token ids (`jti`).
77
42
  * Written set-if-absent by `_rpcConsumeAttachBootstrap` on the attach
78
43
  * exchange; an existing row means the bootstrap URL was replayed.
79
44
  * Bounded: at most one row per `POST /new` bootstrap actually attached. */
80
45
  export declare const ATTACH_BOOTSTRAP_JTI_KEY_PREFIX = "attach-bootstrap-jti:";
46
+ /**
47
+ * Prefix for a port's durable preview capability, keyed by port number. The
48
+ * registry mints the value in memory per registration; this is what lets a
49
+ * preview URL the embedder was already handed survive a rebuild. Owned by
50
+ * `session/port-capability.ts`, which is the only module that reads or writes
51
+ * these rows.
52
+ */
53
+ export declare const PORT_CAPABILITY_KEY_PREFIX = "nimbus_preview_capability:";
54
+ /**
55
+ * Prefix for a named programmatic shell's durable cwd+env, keyed by shell id.
56
+ * One row per id the embedder has actually used; bounded by the embedder's own
57
+ * naming, the way a terminal tab is.
58
+ */
59
+ export declare const SHELL_STATE_KEY_PREFIX = "nimbus_programmatic_shell:";
81
60
  //# sourceMappingURL=keys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;+DAC+D;AAC/D,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAEnD;2EAC2E;AAC3E,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;yDAEyD;AACzD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD;0DAC0D;AAC1D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;uBAEuB;AACvB,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0BAA0B,qBAAqB,CAAC;AAE7D;;;4EAG4E;AAC5E,eAAO,MAAM,+BAA+B,0BAA0B,CAAC"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/session/keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAMH;2EAC2E;AAC3E,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC;;yDAEyD;AACzD,eAAO,MAAM,mBAAmB,mBAAmB,CAAC;AAEpD;0DAC0D;AAC1D,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;uBAEuB;AACvB,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AAEzD;;;4EAG4E;AAC5E,eAAO,MAAM,+BAA+B,0BAA0B,CAAC;AAEvE;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AAEvE;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC"}
@@ -17,9 +17,9 @@
17
17
  * These keys persist DO state across deploys. Renaming any key is a
18
18
  * storage migration — never do it without an explicit migration plan.
19
19
  */
20
- /** W9: storage key for the isolate-generation counter (cold-start +
21
- * post-hibernation wake; one increment per fresh isolate). */
22
- export const W9_ISOLATE_GEN_KEY = 'w9_isolate_gen';
20
+ // The isolate-generation counter key (ISOLATE_GEN_KEY) and the multi-reason
21
+ // alarm map key (ALARM_REASONS_KEY) live with their machinery in
22
+ // @nimbus-sh/fabric/alarms.js; their persisted VALUES are unchanged.
23
23
  /** W9: debounce window in ms before flushing pending process-log writes
24
24
  * to SQL. Hot path (every append schedules a flush via this debounce). */
25
25
  export const W9_FLUSH_DEBOUNCE_MS = 250;
@@ -34,25 +34,6 @@ export const SESSION_BASE_PATH_KEY = 'session-base-path';
34
34
  * hibernation so vite resumes serving after wake without re-running
35
35
  * /api/start-vite. */
36
36
  export const VITE_CONFIG_KEY = 'vite-config';
37
- /** W1: multi-reason alarm coordination map.
38
- *
39
- * JSON-serialised `Record<reason, deadlineMsEpoch>` where keys are
40
- * canonical reason strings (e.g. 'w9-flush', 'log-janitor'). The
41
- * alarm() dispatcher reads this on fire, dispatches every reason
42
- * whose deadline has passed, and re-arms `ctx.storage.setAlarm` at
43
- * the earliest remaining deadline.
44
- *
45
- * Why a map (not a single nextAlarmAt + reason): two subsystems
46
- * (W9 debounced flush + W1 log-janitor sweep) can have distinct
47
- * deadlines. Without the map, the later setAlarm() call would
48
- * overwrite the earlier reason silently, breaking whichever
49
- * subsystem expected its deadline.
50
- *
51
- * Forward-compat: dispatcher silently drops unknown reasons so a
52
- * rollback from a future deploy that added new reasons doesn't
53
- * leave the alarm stuck.
54
- */
55
- export const W1_NEXT_ALARM_REASONS_KEY = 'w1_next_alarm_reasons';
56
37
  /**
57
38
  * Destroyed-session tombstone. Written AFTER `storage.deleteAll()` in the
58
39
  * destroy flow so a straggler facet RPC that wakes the dead DO cannot re-arm
@@ -60,21 +41,22 @@ export const W1_NEXT_ALARM_REASONS_KEY = 'w1_next_alarm_reasons';
60
41
  * metadata is the deliberate cost of keeping destroyed sessions inert.
61
42
  */
62
43
  export const SESSION_DESTROYED_KEY = 'session_destroyed';
63
- /**
64
- * Prefix for the resident-launch journal: one row per launch in flight, keyed
65
- * by the pid it is building for.
66
- *
67
- * A launch spans many turns and holds its state in memory, so an instance
68
- * reset destroys it silently — the process, the terminal and the work all go
69
- * with the object. The row is what a LATER instance reads to know a launch
70
- * ended that way rather than by finishing: a pid at or below the reader's own
71
- * pid base was allocated by a previous generation (see PID_GEN_STRIDE).
72
- * Written before the launch's first byte of work and removed when it settles,
73
- * so a row that outlives its instance is exactly an interrupted launch.
74
- */
75
- export const RESIDENT_LAUNCH_KEY_PREFIX = 'resident-launch:';
76
44
  /** Prefix for consumed single-use attach bootstrap token ids (`jti`).
77
45
  * Written set-if-absent by `_rpcConsumeAttachBootstrap` on the attach
78
46
  * exchange; an existing row means the bootstrap URL was replayed.
79
47
  * Bounded: at most one row per `POST /new` bootstrap actually attached. */
80
48
  export const ATTACH_BOOTSTRAP_JTI_KEY_PREFIX = 'attach-bootstrap-jti:';
49
+ /**
50
+ * Prefix for a port's durable preview capability, keyed by port number. The
51
+ * registry mints the value in memory per registration; this is what lets a
52
+ * preview URL the embedder was already handed survive a rebuild. Owned by
53
+ * `session/port-capability.ts`, which is the only module that reads or writes
54
+ * these rows.
55
+ */
56
+ export const PORT_CAPABILITY_KEY_PREFIX = 'nimbus_preview_capability:';
57
+ /**
58
+ * Prefix for a named programmatic shell's durable cwd+env, keyed by shell id.
59
+ * One row per id the embedder has actually used; bounded by the embedder's own
60
+ * naming, the way a terminal tab is.
61
+ */
62
+ export const SHELL_STATE_KEY_PREFIX = 'nimbus_programmatic_shell:';
@@ -22,7 +22,7 @@ import { NimbusWrangler } from '../wrangler/nimbus-wrangler.js';
22
22
  import { NpmInstaller } from '../npm/installer.js';
23
23
  import { type TryEnableReplicasResult as _W12EnableResult } from '../replica/routing.js';
24
24
  import * as _rpc from './rpc.js';
25
- import { type HostedHttpRequest, type HostedHttpResponse } from '../loaders/process-host.js';
25
+ import type { HostedHttpRequest, HostedHttpResponse } from '@nimbus-sh/fabric/process-host.js';
26
26
  import { WebSocketRelay } from './ws-relay.js';
27
27
  import * as _programmatic from './programmatic.js';
28
28
  export { filterWranglerFlags, detectBundlerBin, checkNodeModulesGuard, detectUnsupportedWranglerConfig, renderNoDevServerHtml, BUNDLER_BIN_PREFIXES, NIMBUS_UNSUPPORTED_BINS, WRANGLER_IGNORED_FLAGS, WRANGLER_IGNORED_FLAGS_WITH_VALUE, WRANGLER_UNSUPPORTED_CONFIG_FIELDS, } from './helpers.js';
@@ -126,9 +126,11 @@ export declare class NimbusSession extends CloudflareDurableObject {
126
126
  * Lets `/api/_diag/memory` confirm whether a wake actually happened
127
127
  * between two probe calls.
128
128
  */
129
- _w9IsolateGen: number;
129
+ _isolateGen: number;
130
130
  /** True once we've persisted the bumped gen counter to storage. */
131
- _w9IsolateGenPersisted: boolean;
131
+ _isolateGenPersisted: boolean;
132
+ /** W1: serializes every alarm-map read-modify-write (fabric alarms.ts). */
133
+ _alarmChain?: Promise<unknown>;
132
134
  /** SQL DDL — idempotent; run on first fetch. */
133
135
  _w9SchemaInit: boolean;
134
136
  /** Have we wired the persist adapter into ProcessLogStore yet? */
@@ -262,6 +264,7 @@ export declare class NimbusSession extends CloudflareDurableObject {
262
264
  _rpcReadFileBytes(path: string, pid?: number): Promise<Uint8Array | null>;
263
265
  _rpcInnerDoFetch(req: any): Promise<any>;
264
266
  _rpcWriteFile(path: string, content: string | Uint8Array, pid?: number): Promise<number>;
267
+ _rpcWriteProtectedRootFile(rootPath: string, path: string, content: string | Uint8Array): Promise<void>;
265
268
  _rpcStat(path: string, pid?: number): Promise<any>;
266
269
  _rpcLstat(path: string, pid?: number): Promise<any>;
267
270
  _rpcHasLegacySymlinkUnder(path: string, pid?: number): Promise<boolean>;
@@ -450,11 +453,14 @@ export declare class NimbusSession extends CloudflareDurableObject {
450
453
  listening: boolean;
451
454
  pid: number | null;
452
455
  registeredAt: number | null;
456
+ capability: string | null;
453
457
  }>;
454
458
  _rpcUnexposePort(port: number): Promise<{
455
459
  port: number;
456
460
  ok: boolean;
457
461
  }>;
462
+ /** Capability-authenticated port route, for an embedder holding the token. */
463
+ _rpcRouteCapabilityPort(port: number, capability: string, request: Request, innerPath: string): Promise<Response>;
458
464
  _rpcDeleteFile(path: string, options?: {
459
465
  recursive?: boolean;
460
466
  }): Promise<void>;
@@ -581,5 +587,5 @@ export declare class NimbusSession extends CloudflareDurableObject {
581
587
  /** W5: bridge _w5PersistRing → ctx.waitUntil. Delegator → ./nimbus-session-ws.ts (S7). */
582
588
  _w5SafePersistRing(): void;
583
589
  }
584
- export { NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, } from './bindings.js';
590
+ export { NimbusAssetsRPC, NimbusLoaderRPC, NimbusLoadedWorker, NimbusLoadedEntrypoint, NimbusDurableObjectNamespace, NimbusDOStub, } from '@nimbus-sh/fabric/bindings.js';
585
591
  //# sourceMappingURL=nimbus-session.d.ts.map