@nimbus-sh/worker 0.6.0 → 0.8.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 (184) hide show
  1. package/README.md +2 -2
  2. package/dist/cirrus-npm-cjs.generated.d.ts +1 -1
  3. package/dist/cirrus-npm-cjs.generated.js +1 -1
  4. package/dist/facets/cirrus-real.d.ts.map +1 -1
  5. package/dist/facets/cirrus-real.js +6 -5
  6. package/dist/facets/compose.d.ts +148 -0
  7. package/dist/facets/compose.d.ts.map +1 -0
  8. package/dist/facets/compose.js +146 -0
  9. package/dist/facets/durable-images.d.ts +9 -5
  10. package/dist/facets/durable-images.d.ts.map +1 -1
  11. package/dist/facets/durable-images.js +17 -7
  12. package/dist/facets/esbuild-bundle-pool.d.ts +49 -0
  13. package/dist/facets/esbuild-bundle-pool.d.ts.map +1 -0
  14. package/dist/facets/esbuild-bundle-pool.js +122 -0
  15. package/dist/facets/exec-telemetry.d.ts +8 -0
  16. package/dist/facets/exec-telemetry.d.ts.map +1 -1
  17. package/dist/facets/manager.d.ts +240 -109
  18. package/dist/facets/manager.d.ts.map +1 -1
  19. package/dist/facets/manager.js +677 -342
  20. package/dist/facets/process.d.ts +20 -16
  21. package/dist/facets/process.d.ts.map +1 -1
  22. package/dist/facets/process.js +59 -28
  23. package/dist/facets/real-vite-fs-shim.js +2 -2
  24. package/dist/facets/real-vite-hmr.d.ts +3 -1
  25. package/dist/facets/real-vite-hmr.d.ts.map +1 -1
  26. package/dist/facets/real-vite-hmr.js +18 -8
  27. package/dist/facets/vite-dev-server.d.ts +25 -47
  28. package/dist/facets/vite-dev-server.d.ts.map +1 -1
  29. package/dist/facets/vite-dev-server.js +185 -219
  30. package/dist/facets/wasm-image-digest.d.ts +25 -0
  31. package/dist/facets/wasm-image-digest.d.ts.map +1 -0
  32. package/dist/facets/wasm-image-digest.js +25 -0
  33. package/dist/facets/wasm-swap-registry.d.ts +51 -92
  34. package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
  35. package/dist/facets/wasm-swap-registry.js +68 -227
  36. package/dist/facets/ws-terminal.d.ts +9 -31
  37. package/dist/facets/ws-terminal.d.ts.map +1 -1
  38. package/dist/facets/ws-terminal.js +58 -51
  39. package/dist/git/network-facet.d.ts.map +1 -1
  40. package/dist/git/network-facet.js +6 -5
  41. package/dist/hosted/commands.d.ts +12 -0
  42. package/dist/hosted/commands.d.ts.map +1 -0
  43. package/dist/hosted/commands.js +1658 -0
  44. package/dist/hosted/runtime.d.ts +114 -0
  45. package/dist/hosted/runtime.d.ts.map +1 -0
  46. package/dist/hosted/runtime.js +288 -0
  47. package/dist/hosted/services.d.ts +40 -0
  48. package/dist/hosted/services.d.ts.map +1 -0
  49. package/dist/hosted/services.js +512 -0
  50. package/dist/loaders/child-process/spawn-pool.d.ts +3 -2
  51. package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
  52. package/dist/loaders/child-process/spawn-pool.js +3 -2
  53. package/dist/loaders/generated-workers.d.ts +2 -2
  54. package/dist/loaders/generated-workers.d.ts.map +1 -1
  55. package/dist/loaders/generated-workers.js +3 -3
  56. package/dist/loaders/npm-resolve-preamble.d.ts +3 -6
  57. package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
  58. package/dist/loaders/npm-resolve-preamble.js +34 -108
  59. package/dist/node-shims-artifact.generated.js +3 -3
  60. package/dist/npm/install-batch-facet.d.ts +3 -2
  61. package/dist/npm/install-batch-facet.d.ts.map +1 -1
  62. package/dist/npm/install-batch-facet.js +45 -15
  63. package/dist/npm/installer.d.ts +22 -17
  64. package/dist/npm/installer.d.ts.map +1 -1
  65. package/dist/npm/installer.js +209 -193
  66. package/dist/npm/pre-bundle-facet.d.ts +1 -1
  67. package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
  68. package/dist/npm/pre-bundle-facet.js +1 -1
  69. package/dist/npm/resolve-facet.d.ts +6 -0
  70. package/dist/npm/resolve-facet.d.ts.map +1 -1
  71. package/dist/npm/resolve-one-facet.d.ts +21 -20
  72. package/dist/npm/resolve-one-facet.d.ts.map +1 -1
  73. package/dist/npm/resolve-one-facet.js +85 -84
  74. package/dist/npm/semver.d.ts +59 -0
  75. package/dist/npm/semver.d.ts.map +1 -0
  76. package/dist/npm/semver.js +226 -0
  77. package/dist/router/remote-api.js +31 -1
  78. package/dist/runtime/bash-repl.d.ts +1 -1
  79. package/dist/runtime/bash-repl.d.ts.map +1 -1
  80. package/dist/runtime/bash-repl.js +38 -4
  81. package/dist/runtime/bun-runner.js +1 -1
  82. package/dist/runtime/html-entrypoint.d.ts +7 -0
  83. package/dist/runtime/html-entrypoint.d.ts.map +1 -1
  84. package/dist/runtime/html-entrypoint.js +18 -2
  85. package/dist/runtime/node-runner.d.ts +4 -1
  86. package/dist/runtime/node-runner.d.ts.map +1 -1
  87. package/dist/runtime/node-runner.js +9 -2
  88. package/dist/runtime/node-shims.d.ts.map +1 -1
  89. package/dist/runtime/node-shims.js +305 -29
  90. package/dist/runtime/opencode-facet-runner.js +16 -16
  91. package/dist/runtime/package-manager.d.ts +35 -122
  92. package/dist/runtime/package-manager.d.ts.map +1 -1
  93. package/dist/runtime/package-manager.js +61 -596
  94. package/dist/runtime/process-logs-api.d.ts +1 -1
  95. package/dist/runtime/process-logs-api.d.ts.map +1 -1
  96. package/dist/runtime/process-logs-api.js +1 -1
  97. package/dist/runtime/python-repl.d.ts +2 -1
  98. package/dist/runtime/python-repl.d.ts.map +1 -1
  99. package/dist/runtime/python-repl.js +82 -59
  100. package/dist/runtime/repl-session.d.ts +9 -47
  101. package/dist/runtime/repl-session.d.ts.map +1 -1
  102. package/dist/runtime/repl-session.js +105 -105
  103. package/dist/runtime/runtime-catalog.d.ts +13 -0
  104. package/dist/runtime/runtime-catalog.d.ts.map +1 -1
  105. package/dist/runtime/runtime-catalog.js +88 -0
  106. package/dist/session/agent.d.ts +1 -21
  107. package/dist/session/agent.d.ts.map +1 -1
  108. package/dist/session/ai.d.ts +5 -1
  109. package/dist/session/ai.d.ts.map +1 -1
  110. package/dist/session/ai.js +7 -0
  111. package/dist/session/helpers.d.ts +38 -0
  112. package/dist/session/helpers.d.ts.map +1 -1
  113. package/dist/session/helpers.js +76 -0
  114. package/dist/session/hibernation.d.ts +2 -1
  115. package/dist/session/hibernation.d.ts.map +1 -1
  116. package/dist/session/hibernation.js +7 -4
  117. package/dist/session/init-phases.d.ts +1 -1
  118. package/dist/session/init-phases.d.ts.map +1 -1
  119. package/dist/session/init-phases.js +2 -12
  120. package/dist/session/init.d.ts +15 -36
  121. package/dist/session/init.d.ts.map +1 -1
  122. package/dist/session/init.js +50 -2327
  123. package/dist/session/loopback.d.ts +2 -29
  124. package/dist/session/loopback.d.ts.map +1 -1
  125. package/dist/session/loopback.js +3 -27
  126. package/dist/session/nimbus-session.d.ts +77 -34
  127. package/dist/session/nimbus-session.d.ts.map +1 -1
  128. package/dist/session/nimbus-session.js +126 -514
  129. package/dist/session/npm-install-port.d.ts +18 -0
  130. package/dist/session/npm-install-port.d.ts.map +1 -0
  131. package/dist/session/npm-install-port.js +37 -0
  132. package/dist/session/port-capability.d.ts +44 -0
  133. package/dist/session/port-capability.d.ts.map +1 -1
  134. package/dist/session/port-capability.js +110 -0
  135. package/dist/session/programmatic.d.ts +36 -43
  136. package/dist/session/programmatic.d.ts.map +1 -1
  137. package/dist/session/programmatic.js +109 -115
  138. package/dist/session/routes.d.ts +30 -17
  139. package/dist/session/routes.d.ts.map +1 -1
  140. package/dist/session/routes.js +42 -131
  141. package/dist/session/rpc.d.ts +15 -15
  142. package/dist/session/rpc.d.ts.map +1 -1
  143. package/dist/session/rpc.js +98 -49
  144. package/dist/session/serving-port.d.ts +27 -0
  145. package/dist/session/serving-port.d.ts.map +1 -0
  146. package/dist/session/serving-port.js +27 -0
  147. package/dist/session/start-real-vite.d.ts +12 -0
  148. package/dist/session/start-real-vite.d.ts.map +1 -1
  149. package/dist/session/start-real-vite.js +4 -4
  150. package/dist/session/supervisor-op.d.ts +4 -4
  151. package/dist/session/supervisor-op.d.ts.map +1 -1
  152. package/dist/session/supervisor-op.js +24 -10
  153. package/dist/session/supervisor-rpc.d.ts +7 -7
  154. package/dist/session/supervisor-rpc.d.ts.map +1 -1
  155. package/dist/session/supervisor-rpc.js +4 -0
  156. package/dist/session/vite-command.d.ts +18 -0
  157. package/dist/session/vite-command.d.ts.map +1 -0
  158. package/dist/session/vite-command.js +609 -0
  159. package/dist/session/ws.d.ts +61 -0
  160. package/dist/session/ws.d.ts.map +1 -1
  161. package/dist/session/ws.js +122 -12
  162. package/dist/shell/npm-bin-entrypoints.d.ts +0 -35
  163. package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
  164. package/dist/shell/npm-bin-entrypoints.js +12 -85
  165. package/dist/workspace-host.d.ts +6 -0
  166. package/dist/workspace-host.d.ts.map +1 -0
  167. package/dist/workspace-host.js +5 -0
  168. package/dist/workspace.d.ts +2 -0
  169. package/dist/workspace.d.ts.map +1 -0
  170. package/dist/workspace.js +1 -0
  171. package/package.json +34 -9
  172. package/public/_assets/runtime/{node-shims-9e1380d9ee430fcc.js → node-shims-8f8c64edd2a1f0f5.js} +305 -29
  173. package/public/index.html +1 -1
  174. package/scripts/bundle-facet-workers.mjs +1 -1
  175. package/scripts/bundle-npm-cjs.mjs +2 -2
  176. package/dist/facets/on-demand-bundle-gate.d.ts +0 -65
  177. package/dist/facets/on-demand-bundle-gate.d.ts.map +0 -1
  178. package/dist/facets/on-demand-bundle-gate.js +0 -125
  179. package/dist/npm/install-args.d.ts +0 -21
  180. package/dist/npm/install-args.d.ts.map +0 -1
  181. package/dist/npm/install-args.js +0 -70
  182. package/dist/npm/npm-log.d.ts +0 -31
  183. package/dist/npm/npm-log.d.ts.map +0 -1
  184. package/dist/npm/npm-log.js +0 -51
@@ -11,46 +11,12 @@
11
11
  * live in src/runtime/<name>-repl.ts and implement the ReplAdapter
12
12
  * interface declared below.
13
13
  */
14
+ import { errorText } from '@nimbus-sh/core/_shared/error-text.js';
14
15
  import { normalizeTerminalNewlines } from '@nimbus-sh/core/_shared/terminal.js';
15
- /**
16
- * Manages an interactive REPL session: stdin buffering with minimal
17
- * readline UX (line-mode), output routing to the WS terminal, prompt
18
- * rendering, and adapter dispatch.
19
- *
20
- * The shell creates a ReplSession when a runtime's `startRepl` hook
21
- * fires; the session installs a `replCallback` on the WebSocketTerminal
22
- * (via attachRepl()) and runs until the adapter signals 'exit' or the
23
- * user presses Ctrl-D on an empty line.
24
- *
25
- * No setTimeout in the read loop — the session is driven entirely by
26
- * keystroke arrival on the WS, with awaits gating the adapter's push().
27
- */
28
16
  export class ReplSession {
29
17
  adapter;
18
+ detachRepl = null;
30
19
  terminal;
31
- detachReplCb = null;
32
- /**
33
- * REPL-R7-1 (2026-05-12): optional reference to the Nimbus shell.
34
- *
35
- * Required when the REPL is launched from a multi-line WS frame
36
- * (e.g. user pastes `python\nexit(7)`). The shell input handler
37
- * splits the frame on \r\n and pushes lines AFTER
38
- * the first into `shell.pasteQueue`, which is drained ONLY when
39
- * the shell becomes idle (after executeLine returns). While our
40
- * REPL is running, those pasteQueue lines sit there waiting and
41
- * the REPL itself receives no input → user sees a hung `>>> `
42
- * prompt that never responds.
43
- *
44
- * If `shell` is provided, ReplSession will, immediately after
45
- * attaching its replCallback, drain shell.pasteQueue and feed the
46
- * lines into the callback (suffixed with \r each — matches what
47
- * the WS frame originally would have looked like). This makes the
48
- * paste path work transparently for REPL launches.
49
- *
50
- * The shell reference is optional so existing adapters (bun, node,
51
- * ruby) that haven't been updated keep working with their
52
- * pre-fix behavior.
53
- */
54
20
  shellRef = null;
55
21
  /** Current line buffer (chars typed since the last enter). */
56
22
  lineBuf = '';
@@ -63,9 +29,11 @@ export class ReplSession {
63
29
  /** Per-session history ring (most recent first). Capped at 100. */
64
30
  history = [];
65
31
  historyIdx = -1;
66
- /** Resolves when close() has been called and the session ended. */
67
32
  closedResolve = null;
68
33
  closedPromise;
34
+ pendingInterrupt = null;
35
+ activePush = null;
36
+ ending = null;
69
37
  /** Exit code captured from adapter's last 'exit' return. */
70
38
  exitCode = 0;
71
39
  /**
@@ -109,68 +77,64 @@ export class ReplSession {
109
77
  // 3. Install the input handler.
110
78
  // REPL-A1b: per-frame data appended to inputQueue; single drain
111
79
  // task ensures serial processing across multiple WS frames.
112
- this.detachReplCb = this.terminal.attachRepl((data) => {
80
+ this.detachRepl = this.terminal.attachRepl((data) => {
81
+ // Ctrl-C is the one input byte that must not queue behind a busy
82
+ // push: it is the user's abort, and it only works if it runs now.
83
+ if (this.busy && data.includes('\x03')) {
84
+ this.inputQueue = '';
85
+ data = data.slice(data.lastIndexOf('\x03') + 1);
86
+ this.interruptBusy();
87
+ if (data.length === 0)
88
+ return;
89
+ }
90
+ if (this.ending)
91
+ return;
113
92
  this.inputQueue += data;
114
93
  if (!this.draining) {
115
94
  this.draining = true;
116
95
  void this.drainInput();
117
96
  }
118
- });
119
- // REPL-R7-1: drain any input that the shell received in the SAME
120
- // WS frame as the REPL-launching command (`python\nexit(7)` style
121
- // pastes). Without this drain, those lines sit forever in
122
- // shell.pasteQueue while the REPL hangs at `>>> `.
123
- //
124
- // Each pasteQueue entry is a single line (no \r/\n). We re-frame
125
- // each into the replCallback as `line + \r` so handleInput
126
- // processes it through the normal Enter-triggered submitLine
127
- // path — same behavior as if the user had typed and pressed
128
- // Enter for each line.
129
- //
130
- // Best-effort: if shellRef is null or pasteQueue is missing,
131
- // skip silently. Mutate the queue (shift) so the shell doesn't
132
- // try to re-process the same items when it drains its own queue
133
- // after this REPL exits.
134
- if (this.shellRef && Array.isArray(this.shellRef.pasteQueue)) {
135
- const pq = this.shellRef.pasteQueue;
136
- if (pq.length > 0) {
137
- const drained = pq.splice(0).filter(line => line !== undefined && line !== null);
138
- if (drained.length > 0) {
139
- // Feed via inputQueue + draining (same path as a real WS
140
- // frame). Each line ends with \r so handleInput's
141
- // submitLine fires per line.
142
- this.inputQueue += drained.join('\r') + '\r';
143
- if (!this.draining) {
144
- this.draining = true;
145
- void this.drainInput();
146
- }
147
- }
97
+ }, () => this.endSession(this.exitCode));
98
+ const queued = this.shellRef?.takeQueuedInput() ?? [];
99
+ if (queued.length > 0) {
100
+ this.inputQueue += queued.join('\r') + '\r';
101
+ if (!this.draining) {
102
+ this.draining = true;
103
+ void this.drainInput();
148
104
  }
149
105
  }
150
106
  // 4. Wait until close() is called.
151
107
  await this.closedPromise;
152
108
  return this.exitCode;
153
109
  }
154
- /**
155
- * REPL-A1b: drain the input queue serially. Pulls data off
156
- * inputQueue, runs handleInput, and reads any data that arrived
157
- * during the await. Exits when queue is empty. Only ONE drainInput
158
- * runs at a time (guarded by draining flag set in attachRepl
159
- * callback).
160
- */
161
110
  async drainInput() {
162
- while (this.inputQueue.length > 0) {
163
- const chunk = this.inputQueue;
164
- this.inputQueue = '';
165
- await this.handleInput(chunk);
111
+ try {
112
+ while (this.inputQueue.length > 0 && !this.ending) {
113
+ const chunk = this.inputQueue;
114
+ this.inputQueue = '';
115
+ await this.handleInput(chunk);
116
+ }
117
+ }
118
+ catch (error) {
119
+ if (!this.ending) {
120
+ this.terminal.write('[repl] ' + errorText(error) + '\r\n');
121
+ try {
122
+ await this.endSession(1);
123
+ }
124
+ catch { /* run() reports the cleanup failure as exit 1. */ }
125
+ }
126
+ }
127
+ finally {
128
+ this.draining = false;
166
129
  }
167
- this.draining = false;
168
130
  }
169
131
  /** Process an input chunk. May contain multiple characters (paste
170
132
  * or rapid typing) — we iterate char-by-char to handle each
171
133
  * control byte individually. */
172
134
  async handleInput(data) {
173
135
  for (let i = 0; i < data.length; i++) {
136
+ if (this.ending)
137
+ return;
174
138
  const ch = data[i];
175
139
  // CTRL-D (0x04): on empty line, close cleanly.
176
140
  if (ch === '\x04') {
@@ -185,10 +149,7 @@ export class ReplSession {
185
149
  // CTRL-C (0x03): cancel current line / block.
186
150
  if (ch === '\x03') {
187
151
  if (this.busy) {
188
- // Mid-execution: we can't actually interrupt the wasm runtime
189
- // in v1 (no SIGINT plumbing). Buffer the cancel for after.
190
- // For now: just display ^C and let the runtime finish.
191
- this.terminal.write('^C\r\n');
152
+ this.interruptBusy();
192
153
  continue;
193
154
  }
194
155
  // Idle: discard current buffer, reset, fresh prompt.
@@ -255,7 +216,20 @@ export class ReplSession {
255
216
  }
256
217
  }
257
218
  }
258
- /** Submit the current line buffer to the adapter. */
219
+ interruptBusy() {
220
+ if (this.ending || this.pendingInterrupt)
221
+ return;
222
+ this.terminal.write('^C\r\n');
223
+ this.terminal.flushNow();
224
+ if (!this.adapter.interrupt)
225
+ return;
226
+ try {
227
+ this.pendingInterrupt = Promise.resolve(this.adapter.interrupt()).then(() => ({ kind: 'interrupted' }), (error) => ({ kind: 'failed', message: errorText(error) }));
228
+ }
229
+ catch (error) {
230
+ this.pendingInterrupt = Promise.resolve({ kind: 'failed', message: errorText(error) });
231
+ }
232
+ }
259
233
  async submitLine() {
260
234
  this.terminal.write('\r\n');
261
235
  const line = this.lineBuf;
@@ -274,15 +248,31 @@ export class ReplSession {
274
248
  this.busy = true;
275
249
  let result;
276
250
  try {
277
- result = await this.adapter.push(fullSource);
251
+ this.activePush = this.adapter.push(fullSource);
252
+ result = await this.activePush;
253
+ }
254
+ catch (error) {
255
+ result = { kind: 'error', stderr: '[repl] adapter threw: ' + errorText(error) + '\n' };
278
256
  }
279
- catch (e) {
280
- result = {
281
- kind: 'error',
282
- stderr: `[repl] adapter threw: ${e?.message || e}\n`,
283
- };
257
+ finally {
258
+ this.activePush = null;
259
+ }
260
+ const pending = this.pendingInterrupt;
261
+ if (pending) {
262
+ const outcome = await pending;
263
+ if (this.pendingInterrupt === pending)
264
+ this.pendingInterrupt = null;
265
+ if (outcome.kind === 'interrupted') {
266
+ result = { kind: 'error', stderr: 'KeyboardInterrupt\n[repl] execution interrupted; interpreter state reset.\n' };
267
+ }
268
+ else {
269
+ this.terminal.write('[repl] interrupt failed: ' + outcome.message + '\r\n');
270
+ this.terminal.flushNow();
271
+ }
284
272
  }
285
273
  this.busy = false;
274
+ if (this.ending)
275
+ return;
286
276
  // REPL-A1 (master plan §1): emit stdout, stderr, and the next-prompt
287
277
  // as three discrete WS frames in deterministic order. Without
288
278
  // flushNow() between them, the 5 ms coalescer in WebSocketTerminal
@@ -364,23 +354,33 @@ export class ReplSession {
364
354
  this.cursorPos = text.length;
365
355
  this.terminal.write(text);
366
356
  }
367
- /** Close the session: detach input hook, free adapter, resolve. */
368
- async endSession(code) {
357
+ endSession(code) {
358
+ if (this.ending)
359
+ return this.ending;
369
360
  this.exitCode = code;
370
- if (this.detachReplCb) {
361
+ this.inputQueue = '';
362
+ this.ending = Promise.resolve().then(async () => {
363
+ let failure = null;
371
364
  try {
372
- this.detachReplCb();
365
+ await this.adapter.close();
373
366
  }
374
- catch { /* fail-soft */ }
375
- this.detachReplCb = null;
376
- }
377
- try {
378
- await this.adapter.close();
379
- }
380
- catch { /* fail-soft */ }
381
- if (this.closedResolve) {
382
- this.closedResolve();
367
+ catch (error) {
368
+ failure = error instanceof Error ? error : new Error(String(error));
369
+ this.exitCode = 1;
370
+ this.terminal.write('[repl] cleanup failed: ' + failure.message + '\r\n');
371
+ this.terminal.flushNow();
372
+ }
373
+ if (this.activePush)
374
+ await this.activePush.catch(() => { });
375
+ if (this.pendingInterrupt)
376
+ await this.pendingInterrupt;
377
+ this.detachRepl?.();
378
+ this.detachRepl = null;
379
+ this.closedResolve?.();
383
380
  this.closedResolve = null;
384
- }
381
+ if (failure)
382
+ throw failure;
383
+ });
384
+ return this.ending;
385
385
  }
386
386
  }
@@ -46,6 +46,8 @@
46
46
  * makes a stale pin a cache miss rather than an outage.
47
47
  */
48
48
  import { type ManifestFile, type RuntimeManifest } from '@nimbus-sh/core/runtime/runtime-manifest.js';
49
+ import { type RuntimeSource } from '@nimbus-sh/core/runtime/runtime-package.js';
50
+ import { type RuntimePackageAbi } from '@nimbus-sh/core/runtime/os-contracts.js';
49
51
  /** Minimal R2Bucket shape we depend on. */
50
52
  type R2BucketLike = {
51
53
  get(key: string): Promise<{
@@ -102,5 +104,16 @@ export declare function fetchManifest(env: RuntimeCatalogEnv, entry: CatalogVers
102
104
  * execution in whichever session installs it.
103
105
  */
104
106
  export declare function fetchBlob(env: RuntimeCatalogEnv, file: ManifestFile): Promise<Uint8Array>;
107
+ export declare function runtimeAbiForCatalogName(name: string): RuntimePackageAbi;
108
+ /**
109
+ * The R2 catalog as a core `RuntimeSource` — the worker adapter half of the
110
+ * install path, so a workspace composed inside this Worker resolves
111
+ * `nimbus install <spec>` against the same bucket and digest chain the
112
+ * session's installer always used. Aliases resolve the way the old
113
+ * resolver did: `python` redirects to `cpython` unless a version pins it,
114
+ * and any bin a runtime's default manifest declares resolves to that
115
+ * runtime — except a superseded one, which never answers for a bin.
116
+ */
117
+ export declare function runtimeCatalogSource(env: RuntimeCatalogEnv): RuntimeSource;
105
118
  export {};
106
119
  //# sourceMappingURL=runtime-catalog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-catalog.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAKH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,6CAA6C,CAAC;AAErD,2CAA2C;AAC3C,KAAK,YAAY,GAAG;IAClB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACxB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;KACzB,GAAG,IAAI,CAAC,CAAC;CACX,GAAG,IAAI,GAAG,SAAS,CAAC;AAErB,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,oBAAoB,CAAC,EAAE,YAAY,CAAC;CACrC;AAID,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;2EACuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC/C;AAiBD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAElE;AA4DD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBlF;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,UAAU,CAAC,CA4BrB"}
1
+ {"version":3,"file":"runtime-catalog.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAKH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EAKL,KAAK,aAAa,EACnB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,yCAAyC,CAAC;AAEjD,2CAA2C;AAC3C,KAAK,YAAY,GAAG;IAClB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QACxB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;KACzB,GAAG,IAAI,CAAC,CAAC;CACX,GAAG,IAAI,GAAG,SAAS,CAAC;AAErB,8CAA8C;AAC9C,MAAM,WAAW,iBAAiB;IAChC,oBAAoB,CAAC,EAAE,YAAY,CAAC;CACrC;AAID,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB;2EACuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;CAC/C;AAiBD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAElE;AA4DD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CAuBlF;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,iBAAiB,EACtB,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,eAAe,CAAC,CA8B1B;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,UAAU,CAAC,CA4BrB;AAID,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAExE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,aAAa,CAwE1E"}
@@ -49,6 +49,9 @@ import { z } from 'zod/v4';
49
49
  import { sha256Hex } from '@nimbus-sh/core/_shared/crypto.js';
50
50
  import { RUNTIME_CATALOG_SHA256 } from '../runtime-catalog.generated.js';
51
51
  import { HexSha256Schema, parseRuntimeManifest, } from '@nimbus-sh/core/runtime/runtime-manifest.js';
52
+ import { runtimeEntrypoints } from '@nimbus-sh/core/runtime/installed-runtimes.js';
53
+ import { splitRuntimeSpec, SUPERSEDED_RUNTIMES, } from '@nimbus-sh/core/runtime/runtime-package.js';
54
+ import { NIMBUS_RUNTIME_ABIS, NATIVE_UNSUPPORTED_ABI, } from '@nimbus-sh/core/runtime/os-contracts.js';
52
55
  const CatalogVersionEntrySchema = z.object({
53
56
  manifest: z.string().min(1),
54
57
  manifest_sha256: HexSha256Schema.optional(),
@@ -192,6 +195,91 @@ export async function fetchBlob(env, file) {
192
195
  await l2Put(verified, 'application/octet-stream');
193
196
  return verified.bytes;
194
197
  }
198
+ // ── RuntimeSource ────────────────────────────────────────────────────
199
+ export function runtimeAbiForCatalogName(name) {
200
+ return NIMBUS_RUNTIME_ABIS[name] ?? NATIVE_UNSUPPORTED_ABI;
201
+ }
202
+ /**
203
+ * The R2 catalog as a core `RuntimeSource` — the worker adapter half of the
204
+ * install path, so a workspace composed inside this Worker resolves
205
+ * `nimbus install <spec>` against the same bucket and digest chain the
206
+ * session's installer always used. Aliases resolve the way the old
207
+ * resolver did: `python` redirects to `cpython` unless a version pins it,
208
+ * and any bin a runtime's default manifest declares resolves to that
209
+ * runtime — except a superseded one, which never answers for a bin.
210
+ */
211
+ export function runtimeCatalogSource(env) {
212
+ return {
213
+ async list() {
214
+ const catalog = await fetchCatalog(env);
215
+ return Object.entries(catalog.runtimes)
216
+ .sort(([a], [b]) => a.localeCompare(b))
217
+ .map(([name, entry]) => ({
218
+ name,
219
+ abi: runtimeAbiForCatalogName(name),
220
+ defaultVersion: entry.default,
221
+ versions: Object.entries(entry.versions)
222
+ .sort(([a], [b]) => a.localeCompare(b))
223
+ .map(([version, v]) => ({
224
+ version,
225
+ sizeBytes: v.size_bytes,
226
+ license: v.license,
227
+ })),
228
+ }));
229
+ },
230
+ async resolve(spec) {
231
+ const { name, versionOverride } = splitRuntimeSpec(spec);
232
+ const catalog = await fetchCatalog(env);
233
+ // `python` is CPython now: a bare spec follows the supersession, an
234
+ // explicit `python@<version>` is a deliberate request and bypasses it.
235
+ const superseding = versionOverride === null ? SUPERSEDED_RUNTIMES[name] : undefined;
236
+ const runtimeName = (superseding !== undefined && catalog.runtimes[superseding] ? superseding : null)
237
+ ?? (catalog.runtimes[name] ? name : null);
238
+ let resolved = runtimeName;
239
+ if (resolved === null) {
240
+ // Bin-name aliasing is catalog-driven: any command a runtime
241
+ // provides resolves to that runtime. A superseded runtime does not
242
+ // answer for a command name either — its runner is no longer
243
+ // registered, and the successor declares the same commands further
244
+ // down this same loop.
245
+ for (const [candidate, entry] of Object.entries(catalog.runtimes)) {
246
+ if (versionOverride === null
247
+ && SUPERSEDED_RUNTIMES[candidate] !== undefined
248
+ && catalog.runtimes[SUPERSEDED_RUNTIMES[candidate]])
249
+ continue;
250
+ const versionEntry = entry.versions[entry.default];
251
+ if (!versionEntry)
252
+ continue;
253
+ try {
254
+ const manifest = await fetchManifest(env, versionEntry);
255
+ if (runtimeEntrypoints(manifest).some((ep) => ep.binName === name)) {
256
+ resolved = candidate;
257
+ break;
258
+ }
259
+ }
260
+ catch {
261
+ // A bad manifest should not prevent canonical catalog names from
262
+ // resolving; it only suppresses bin-name aliasing for that runtime.
263
+ }
264
+ }
265
+ }
266
+ if (resolved === null)
267
+ return null;
268
+ const entry = catalog.runtimes[resolved];
269
+ const version = versionOverride ?? entry.default;
270
+ const versionEntry = entry.versions[version];
271
+ if (!versionEntry) {
272
+ throw new Error(`'${resolved}@${version}' not in catalog`);
273
+ }
274
+ const manifest = await fetchManifest(env, versionEntry);
275
+ const pkg = {
276
+ manifest,
277
+ readBlob: (file) => fetchBlob(env, file),
278
+ };
279
+ return pkg;
280
+ },
281
+ };
282
+ }
195
283
  /** Read the entry at `address`, or null on miss, on a stripped Cache API,
196
284
  * or when what came back does not hash to the key it was found under. */
197
285
  async function l2Get(address) {
@@ -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":"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"}
@@ -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
  /**
@@ -127,6 +127,28 @@ export declare function _classifyCommand(name: string): {
127
127
  * Returns the detected bundler bin name (e.g. "vite") or null.
128
128
  */
129
129
  export declare function detectBundlerBin(script: string): string | null;
130
+ /**
131
+ * Whether `npm run <scriptName>` (or `npm start`/`npm test`) should refuse
132
+ * before dispatch because the resolved script invokes `next` on a
133
+ * subcommand Nimbus cannot run: `dev`, `start`, `build`, or `export` all
134
+ * need the same missing pipeline — webpack/Turbopack bundling,
135
+ * child_process.fork with v8-IPC, custom http.Server semantics.
136
+ *
137
+ * Returns the blocked subcommand ('dev'|'start'|'build'|'export') or null.
138
+ * `--force` / `--allow-next` in the script args bypasses the refusal.
139
+ * scriptName 'dev'/'start' on a next-depending package refuses even when
140
+ * the script body doesn't name `next` (custom dev servers), matching the
141
+ * pre-extension dev/start-only behavior.
142
+ */
143
+ export declare function refusedNextSubcommand(scriptName: string, script: string, pkg: {
144
+ dependencies?: Record<string, string>;
145
+ devDependencies?: Record<string, string>;
146
+ }, scriptArgs: readonly string[]): 'dev' | 'start' | 'build' | 'export' | null;
147
+ /**
148
+ * The refusal message for `refusedNextSubcommand` — identical blockers and
149
+ * escape hatch for every blocked subcommand.
150
+ */
151
+ export declare const NEXT_REFUSAL_MESSAGE: string;
130
152
  /**
131
153
  * Check whether a project directory has installed dependencies.
132
154
  *
@@ -140,4 +162,20 @@ export declare function checkNodeModulesGuard(vfs: CredentialedVfs, projectRoot:
140
162
  missing: boolean;
141
163
  depCount: number;
142
164
  };
165
+ /**
166
+ * Bound for the `vite build` esbuild bundle step (init.ts). Demo-app
167
+ * builds take seconds; anything past this is a stall, not a build.
168
+ */
169
+ export declare const VITE_BUILD_TIMEOUT_MS = 120000;
170
+ /**
171
+ * G5: race an unbounded await against a loud timeout.
172
+ *
173
+ * The timeout does not cancel `work` (there is nothing to cancel an
174
+ * in-isolate esbuild bundle with) — it stops *waiting* and rejects
175
+ * with an error that names what was attempted and how long it ran,
176
+ * so a stalled build surfaces as a timeout error instead of silence.
177
+ * The timer handle never escapes the executor, so there is nothing
178
+ * to null-check: settle clears it on every path.
179
+ */
180
+ export declare function withLoudTimeout<T>(work: Promise<T>, timeoutMs: number, what: string): Promise<T>;
143
181
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/session/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;CAC9B,GAAG,MAAM,CAiHT;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAehC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAI5F,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,aAQjC,CAAC;AACH,eAAO,MAAM,iCAAiC,aAG5C,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoBzF;AAED;;;;;;;;;;;GAWG;AAiBH,eAAO,MAAM,kCAAkC,UAQ9C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAwC5F;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,aAS3B,CAAC;AACH,eAAO,MAAM,gBAAgB,aAS3B,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAU3G;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,MAAM,GAClB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAiBxC"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/session/helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE;IAC1C,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,OAAO,EAAE,MAAM,GAAG,UAAU,CAAC;CAC9B,GAAG,MAAM,CAiHT;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAehC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAI5F,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,aAQjC,CAAC;AACH,eAAO,MAAM,iCAAiC,aAG5C,CAAC;AAEH;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CAoBzF;AAED;;;;;;;;;;;GAWG;AAiBH,eAAO,MAAM,kCAAkC,UAQ9C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAwC5F;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,aAS3B,CAAC;AACH,eAAO,MAAM,gBAAgB,aAS3B,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAU3G;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiB9D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,EACxF,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAkB7C;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,QAQuC,CAAC;AAEzE;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,MAAM,GAClB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAiBxC;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAE7C;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,CAAC,CAAC,CAaZ"}