@nimbus-sh/worker 0.5.0 → 0.7.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.
- package/README.md +2 -2
- package/dist/_shared/preview-host.d.ts +26 -8
- package/dist/_shared/preview-host.d.ts.map +1 -1
- package/dist/_shared/preview-host.js +51 -11
- package/dist/cirrus-npm-cjs.generated.d.ts +1 -1
- package/dist/cirrus-npm-cjs.generated.js +1 -1
- package/dist/facets/cirrus-real.d.ts.map +1 -1
- package/dist/facets/cirrus-real.js +6 -5
- package/dist/facets/compose.d.ts +148 -0
- package/dist/facets/compose.d.ts.map +1 -0
- package/dist/facets/compose.js +146 -0
- package/dist/facets/durable-images.d.ts +18 -5
- package/dist/facets/durable-images.d.ts.map +1 -1
- package/dist/facets/durable-images.js +36 -7
- package/dist/facets/durable-slots.d.ts +1 -1
- package/dist/facets/durable-slots.d.ts.map +1 -1
- package/dist/facets/durable-slots.js +2 -1
- package/dist/facets/esbuild-bundle-pool.d.ts +49 -0
- package/dist/facets/esbuild-bundle-pool.d.ts.map +1 -0
- package/dist/facets/esbuild-bundle-pool.js +122 -0
- package/dist/facets/exec-telemetry.d.ts +8 -0
- package/dist/facets/exec-telemetry.d.ts.map +1 -1
- package/dist/facets/manager.d.ts +337 -123
- package/dist/facets/manager.d.ts.map +1 -1
- package/dist/facets/manager.js +1100 -449
- package/dist/facets/process.d.ts +20 -16
- package/dist/facets/process.d.ts.map +1 -1
- package/dist/facets/process.js +59 -28
- package/dist/facets/real-vite-fs-shim.js +2 -2
- package/dist/facets/resident-identity.d.ts +23 -0
- package/dist/facets/resident-identity.d.ts.map +1 -0
- package/dist/facets/resident-identity.js +31 -0
- package/dist/facets/vite-dev-server.d.ts +25 -47
- package/dist/facets/vite-dev-server.d.ts.map +1 -1
- package/dist/facets/vite-dev-server.js +185 -219
- package/dist/facets/wasm-image-digest.d.ts +25 -0
- package/dist/facets/wasm-image-digest.d.ts.map +1 -0
- package/dist/facets/wasm-image-digest.js +25 -0
- package/dist/facets/wasm-swap-registry.d.ts +51 -92
- package/dist/facets/wasm-swap-registry.d.ts.map +1 -1
- package/dist/facets/wasm-swap-registry.js +68 -227
- package/dist/git/commands.d.ts +0 -1
- package/dist/git/commands.d.ts.map +1 -1
- package/dist/git/commands.js +0 -3
- package/dist/git/network-facet.d.ts.map +1 -1
- package/dist/git/network-facet.js +6 -5
- package/dist/loaders/child-process/spawn-pool.d.ts +3 -2
- package/dist/loaders/child-process/spawn-pool.d.ts.map +1 -1
- package/dist/loaders/child-process/spawn-pool.js +3 -2
- package/dist/loaders/generated-workers.d.ts +2 -2
- package/dist/loaders/generated-workers.d.ts.map +1 -1
- package/dist/loaders/generated-workers.js +3 -3
- package/dist/loaders/npm-resolve-preamble.d.ts +3 -6
- package/dist/loaders/npm-resolve-preamble.d.ts.map +1 -1
- package/dist/loaders/npm-resolve-preamble.js +34 -108
- package/dist/node-shims-artifact.generated.js +3 -3
- package/dist/npm/install-batch-facet.d.ts +3 -2
- package/dist/npm/install-batch-facet.d.ts.map +1 -1
- package/dist/npm/install-batch-facet.js +45 -15
- package/dist/npm/installer.d.ts +22 -17
- package/dist/npm/installer.d.ts.map +1 -1
- package/dist/npm/installer.js +209 -193
- package/dist/npm/pre-bundle-facet.d.ts +1 -1
- package/dist/npm/pre-bundle-facet.d.ts.map +1 -1
- package/dist/npm/pre-bundle-facet.js +1 -1
- package/dist/npm/resolve-facet.d.ts +6 -0
- package/dist/npm/resolve-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.d.ts +21 -20
- package/dist/npm/resolve-one-facet.d.ts.map +1 -1
- package/dist/npm/resolve-one-facet.js +85 -84
- package/dist/npm/semver.d.ts +59 -0
- package/dist/npm/semver.d.ts.map +1 -0
- package/dist/npm/semver.js +226 -0
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +47 -10
- package/dist/router/public-directory.d.ts +5 -1
- package/dist/router/public-directory.d.ts.map +1 -1
- package/dist/router/public-directory.js +9 -2
- package/dist/router/remote-api.d.ts +18 -0
- package/dist/router/remote-api.d.ts.map +1 -1
- package/dist/router/remote-api.js +64 -5
- package/dist/runtime/cpython-resident.d.ts.map +1 -1
- package/dist/runtime/cpython-resident.js +3 -1
- package/dist/runtime/html-entrypoint.d.ts +7 -0
- package/dist/runtime/html-entrypoint.d.ts.map +1 -1
- package/dist/runtime/html-entrypoint.js +18 -2
- package/dist/runtime/node-runner.d.ts +3 -0
- package/dist/runtime/node-runner.d.ts.map +1 -1
- package/dist/runtime/node-runner.js +7 -0
- package/dist/runtime/node-shims.d.ts.map +1 -1
- package/dist/runtime/node-shims.js +305 -29
- package/dist/runtime/opencode-facet-runner.js +2 -2
- package/dist/runtime/package-manager.d.ts +44 -1
- package/dist/runtime/package-manager.d.ts.map +1 -1
- package/dist/runtime/package-manager.js +168 -3
- package/dist/runtime/ruby-resident.d.ts.map +1 -1
- package/dist/runtime/ruby-resident.js +2 -0
- package/dist/session/agent.d.ts.map +1 -1
- package/dist/session/agent.js +28 -1
- package/dist/session/helpers.d.ts +38 -0
- package/dist/session/helpers.d.ts.map +1 -1
- package/dist/session/helpers.js +76 -0
- package/dist/session/init-phases.d.ts +1 -1
- package/dist/session/init-phases.d.ts.map +1 -1
- package/dist/session/init-phases.js +2 -12
- package/dist/session/init.d.ts +15 -1
- package/dist/session/init.d.ts.map +1 -1
- package/dist/session/init.js +91 -603
- package/dist/session/keys.d.ts +4 -0
- package/dist/session/keys.d.ts.map +1 -1
- package/dist/session/keys.js +4 -0
- package/dist/session/nimbus-session.d.ts +90 -23
- package/dist/session/nimbus-session.d.ts.map +1 -1
- package/dist/session/nimbus-session.js +200 -110
- package/dist/session/npm-install-port.d.ts +16 -0
- package/dist/session/npm-install-port.d.ts.map +1 -0
- package/dist/session/npm-install-port.js +37 -0
- package/dist/session/port-capability.d.ts +90 -0
- package/dist/session/port-capability.d.ts.map +1 -1
- package/dist/session/port-capability.js +219 -9
- package/dist/session/programmatic.d.ts +125 -5
- package/dist/session/programmatic.d.ts.map +1 -1
- package/dist/session/programmatic.js +439 -89
- package/dist/session/routes.d.ts +39 -17
- package/dist/session/routes.d.ts.map +1 -1
- package/dist/session/routes.js +67 -131
- package/dist/session/rpc.d.ts +39 -16
- package/dist/session/rpc.d.ts.map +1 -1
- package/dist/session/rpc.js +137 -130
- package/dist/session/serving-port.d.ts +27 -0
- package/dist/session/serving-port.d.ts.map +1 -0
- package/dist/session/serving-port.js +27 -0
- package/dist/session/start-real-vite.d.ts +12 -0
- package/dist/session/start-real-vite.d.ts.map +1 -1
- package/dist/session/start-real-vite.js +4 -4
- package/dist/session/supervisor-op.d.ts +41 -4
- package/dist/session/supervisor-op.d.ts.map +1 -1
- package/dist/session/supervisor-op.js +101 -73
- package/dist/session/supervisor-rpc.d.ts +7 -7
- package/dist/session/supervisor-rpc.d.ts.map +1 -1
- package/dist/session/supervisor-rpc.js +6 -3
- package/dist/session/vite-command.d.ts +18 -0
- package/dist/session/vite-command.d.ts.map +1 -0
- package/dist/session/vite-command.js +609 -0
- package/dist/session/ws.d.ts +61 -0
- package/dist/session/ws.d.ts.map +1 -1
- package/dist/session/ws.js +122 -12
- package/dist/shell/npm-bin-entrypoints.d.ts +0 -35
- package/dist/shell/npm-bin-entrypoints.d.ts.map +1 -1
- package/dist/shell/npm-bin-entrypoints.js +12 -85
- package/package.json +24 -4
- package/public/_assets/runtime/{node-shims-9e1380d9ee430fcc.js → node-shims-8f8c64edd2a1f0f5.js} +305 -29
- package/public/index.html +1 -1
- package/scripts/bundle-facet-workers.mjs +1 -1
- package/scripts/bundle-npm-cjs.mjs +2 -2
- package/dist/facets/on-demand-bundle-gate.d.ts +0 -65
- package/dist/facets/on-demand-bundle-gate.d.ts.map +0 -1
- package/dist/facets/on-demand-bundle-gate.js +0 -125
- package/dist/npm/install-args.d.ts +0 -21
- package/dist/npm/install-args.d.ts.map +0 -1
- package/dist/npm/install-args.js +0 -70
- package/dist/npm/npm-log.d.ts +0 -31
- package/dist/npm/npm-log.d.ts.map +0 -1
- package/dist/npm/npm-log.js +0 -51
|
@@ -200,12 +200,19 @@ export async function ensureRuntimesProgrammatic(deps, specs, opts = {}) {
|
|
|
200
200
|
}
|
|
201
201
|
return results;
|
|
202
202
|
}
|
|
203
|
+
const NIMBUS_USAGE = [
|
|
204
|
+
'usage: nimbus install <name>[@<version>] | nimbus install --list | nimbus install --available | nimbus uninstall <name>',
|
|
205
|
+
' nimbus expose <port|pid> [--public] [--name <name>]',
|
|
206
|
+
' nimbus app list | url <name|port> | rotate <name|port> | remove <name|port>',
|
|
207
|
+
' nimbus start [--restart never|on-failure] <command> [args...]',
|
|
208
|
+
].join('\n');
|
|
203
209
|
/**
|
|
204
210
|
* Build the shell-command handler that implements `nimbus install …`,
|
|
205
|
-
* `nimbus uninstall
|
|
211
|
+
* `nimbus uninstall …`, `nimbus expose …`, `nimbus app …` and
|
|
212
|
+
* `nimbus start …`. Registered under the name `nimbus`.
|
|
206
213
|
*/
|
|
207
214
|
export function makeNimbusVerbHandler(deps) {
|
|
208
|
-
const { env, registry, getHome, warmRuntime } = deps;
|
|
215
|
+
const { env, registry, getHome, warmRuntime, apps } = deps;
|
|
209
216
|
const vfs = deps.vfs.as(CRED_KERNEL);
|
|
210
217
|
return async function nimbus(ctx) {
|
|
211
218
|
const argv = ctx.args || [];
|
|
@@ -217,12 +224,170 @@ export function makeNimbusVerbHandler(deps) {
|
|
|
217
224
|
if (verb === 'uninstall') {
|
|
218
225
|
return runUninstall(rest, ctx, { vfs, registry, getHome });
|
|
219
226
|
}
|
|
227
|
+
if (verb === 'expose' || verb === 'app' || verb === 'start') {
|
|
228
|
+
if (verb === 'start')
|
|
229
|
+
return runStart(rest, ctx, registry);
|
|
230
|
+
if (!apps) {
|
|
231
|
+
ctx.stderr.write(`nimbus ${verb}: this host has no session to address applications on\n`);
|
|
232
|
+
return 1;
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
return verb === 'expose' ? await runExpose(rest, ctx, apps) : await runApp(rest, ctx, apps);
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
ctx.stderr.write(`nimbus ${verb}: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
239
|
+
return 1;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
220
242
|
// Unknown verb.
|
|
221
243
|
ctx.stderr.write(`nimbus: unknown subcommand '${verb || '(none)'}'\n`);
|
|
222
|
-
ctx.stderr.write(
|
|
244
|
+
ctx.stderr.write(`${NIMBUS_USAGE}\n`);
|
|
223
245
|
return 2;
|
|
224
246
|
};
|
|
225
247
|
}
|
|
248
|
+
// ── expose / app / start ─────────────────────────────────────────────
|
|
249
|
+
/** `<port|pid|name>` as the verbs take it: digits are a port or pid, anything else a name. */
|
|
250
|
+
function appTargetArg(raw) {
|
|
251
|
+
return /^\d+$/.test(raw) ? Number(raw) : raw;
|
|
252
|
+
}
|
|
253
|
+
async function runExpose(args, ctx, apps) {
|
|
254
|
+
let target;
|
|
255
|
+
let name;
|
|
256
|
+
let visibility;
|
|
257
|
+
for (let i = 0; i < args.length; i++) {
|
|
258
|
+
const arg = args[i];
|
|
259
|
+
if (arg === '--public')
|
|
260
|
+
visibility = 'public';
|
|
261
|
+
else if (arg === '--scoped')
|
|
262
|
+
visibility = 'scoped';
|
|
263
|
+
else if (arg === '--name') {
|
|
264
|
+
name = args[++i];
|
|
265
|
+
}
|
|
266
|
+
else if (arg.startsWith('--name='))
|
|
267
|
+
name = arg.slice('--name='.length);
|
|
268
|
+
else if (arg.startsWith('--')) {
|
|
269
|
+
ctx.stderr.write(`nimbus expose: unknown flag ${arg}\n`);
|
|
270
|
+
return 2;
|
|
271
|
+
}
|
|
272
|
+
else if (target === undefined)
|
|
273
|
+
target = arg;
|
|
274
|
+
else {
|
|
275
|
+
ctx.stderr.write('nimbus expose: one target only\n');
|
|
276
|
+
return 2;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (target === undefined) {
|
|
280
|
+
ctx.stderr.write('usage: nimbus expose <port|pid> [--public] [--name <name>]\n');
|
|
281
|
+
return 2;
|
|
282
|
+
}
|
|
283
|
+
const exposed = await apps.expose(appTargetArg(target), {
|
|
284
|
+
...(visibility !== undefined ? { visibility } : {}),
|
|
285
|
+
...(name !== undefined ? { name } : {}),
|
|
286
|
+
});
|
|
287
|
+
ctx.stdout.write(`${exposed.url ?? `(no URL: port ${exposed.port}, capability ${exposed.capability ?? 'none'})`}\n`);
|
|
288
|
+
ctx.stdout.write(` ${exposed.visibility} · ${exposed.name ?? exposed.owner} · port ${exposed.port}\n`);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
async function runApp(args, ctx, apps) {
|
|
292
|
+
const [sub, target] = args;
|
|
293
|
+
if (sub === 'list' || sub === 'ls') {
|
|
294
|
+
const rows = await apps.list();
|
|
295
|
+
if (rows.length === 0) {
|
|
296
|
+
ctx.stdout.write('(no applications)\n');
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
for (const app of rows) {
|
|
300
|
+
const label = app.name ?? app.owner;
|
|
301
|
+
const where = app.port === null ? '-' : String(app.port);
|
|
302
|
+
const pid = app.pid === null ? '-' : String(app.pid);
|
|
303
|
+
const status = app.diagnostic ? `${app.status} (${app.diagnostic})` : app.status;
|
|
304
|
+
ctx.stdout.write(`${label}\t${where}\t${pid}\t${status}\t${app.visibility}\t${app.restart}\t${app.url ?? '-'}\n`);
|
|
305
|
+
}
|
|
306
|
+
return 0;
|
|
307
|
+
}
|
|
308
|
+
if (target === undefined || (sub !== 'url' && sub !== 'rotate' && sub !== 'remove')) {
|
|
309
|
+
ctx.stderr.write('usage: nimbus app list | url <name|port> | rotate <name|port> | remove <name|port>\n');
|
|
310
|
+
return 2;
|
|
311
|
+
}
|
|
312
|
+
const t = appTargetArg(target);
|
|
313
|
+
if (sub === 'url') {
|
|
314
|
+
const app = (await apps.list()).find((row) => row.name === t || row.owner === t || row.port === t || row.pid === t);
|
|
315
|
+
if (!app) {
|
|
316
|
+
ctx.stderr.write(`nimbus app url: no application matches ${target}\n`);
|
|
317
|
+
return 1;
|
|
318
|
+
}
|
|
319
|
+
ctx.stdout.write(`${app.url ?? `(no URL: port ${app.port ?? '-'})`}\n`);
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
if (sub === 'rotate') {
|
|
323
|
+
const rotated = await apps.rotateLink(t);
|
|
324
|
+
ctx.stdout.write(`${rotated.url ?? `(no URL: port ${rotated.port}, capability ${rotated.capability ?? 'none'})`}\n`);
|
|
325
|
+
return 0;
|
|
326
|
+
}
|
|
327
|
+
const removed = await apps.remove(t);
|
|
328
|
+
ctx.stdout.write(removed.removed
|
|
329
|
+
? `removed ${removed.owner}${removed.port !== null ? ` (port ${removed.port} released)` : ''}\n`
|
|
330
|
+
: `nothing to remove for ${removed.owner}\n`);
|
|
331
|
+
return removed.removed ? 0 : 1;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* `nimbus start [--restart <policy>] <command> [args...]` — run a
|
|
335
|
+
* registered command with the restart policy in its environment, which is
|
|
336
|
+
* where the resident it starts reads the policy from (`NIMBUS_RESTART`),
|
|
337
|
+
* exactly as the SDK's `startProcess({ restart })` carries it.
|
|
338
|
+
*/
|
|
339
|
+
async function runStart(args, ctx, registry) {
|
|
340
|
+
let restart = 'never';
|
|
341
|
+
let i = 0;
|
|
342
|
+
for (; i < args.length; i++) {
|
|
343
|
+
const arg = args[i];
|
|
344
|
+
if (arg === '--restart') {
|
|
345
|
+
const policy = args[++i];
|
|
346
|
+
if (policy !== 'never' && policy !== 'on-failure') {
|
|
347
|
+
ctx.stderr.write(`nimbus start: --restart must be never or on-failure, got ${policy ?? '(none)'}\n`);
|
|
348
|
+
return 2;
|
|
349
|
+
}
|
|
350
|
+
restart = policy;
|
|
351
|
+
}
|
|
352
|
+
else if (arg.startsWith('--restart=')) {
|
|
353
|
+
const policy = arg.slice('--restart='.length);
|
|
354
|
+
if (policy !== 'never' && policy !== 'on-failure') {
|
|
355
|
+
ctx.stderr.write(`nimbus start: --restart must be never or on-failure, got ${policy}\n`);
|
|
356
|
+
return 2;
|
|
357
|
+
}
|
|
358
|
+
restart = policy;
|
|
359
|
+
}
|
|
360
|
+
else if (arg === '--') {
|
|
361
|
+
i += 1;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
else if (arg.startsWith('--')) {
|
|
365
|
+
ctx.stderr.write(`nimbus start: unknown flag ${arg}\n`);
|
|
366
|
+
return 2;
|
|
367
|
+
}
|
|
368
|
+
else
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
const [command, ...commandArgs] = args.slice(i);
|
|
372
|
+
if (!command) {
|
|
373
|
+
ctx.stderr.write('usage: nimbus start [--restart never|on-failure] <command> [args...]\n');
|
|
374
|
+
return 2;
|
|
375
|
+
}
|
|
376
|
+
const handler = registry.resolve ? await registry.resolve(command) : null;
|
|
377
|
+
if (!handler) {
|
|
378
|
+
ctx.stderr.write(`nimbus start: ${command}: command not found\n`);
|
|
379
|
+
return 127;
|
|
380
|
+
}
|
|
381
|
+
// The shell hands `nimbus` its full CommandContext; ShellCtx is only the
|
|
382
|
+
// slice this module reads, so the spread carries everything the command
|
|
383
|
+
// needs (signal, vfs, stdin, ...) through untouched.
|
|
384
|
+
const full = ctx;
|
|
385
|
+
return handler({
|
|
386
|
+
...full,
|
|
387
|
+
args: commandArgs,
|
|
388
|
+
env: { ...full.env, NIMBUS_RESTART: restart },
|
|
389
|
+
});
|
|
390
|
+
}
|
|
226
391
|
// ── install ──────────────────────────────────────────────────────────
|
|
227
392
|
async function runInstall(args, ctx, deps) {
|
|
228
393
|
// Flag parsing.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ruby-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAezD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ruby-resident.d.ts","sourceRoot":"","sources":["../../src/runtime/ruby-resident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,wCAAwC,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAezD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,iBAAiB,CAgF3E;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiLrE"}
|
|
@@ -28,6 +28,8 @@ export function rubyResidentStart(facetMgr) {
|
|
|
28
28
|
const command = args.command;
|
|
29
29
|
const workerCode = buildRubySocketProcessWorker(buildRubyPreamble());
|
|
30
30
|
const spawned = await facetMgr.spawnWorker(workerCode, command, args.cwd, {
|
|
31
|
+
resident: { argv: args.argv, runtime: 'ruby' },
|
|
32
|
+
restart: args.startArgs.userEnv.NIMBUS_RESTART === 'on-failure' ? 'on-failure' : 'never',
|
|
31
33
|
compatibilityFlags: ['nodejs_compat'],
|
|
32
34
|
// By path, not by value: the image is 34.3 MiB — more than a single RPC
|
|
33
35
|
// value may carry — so whichever host runs this process reads it itself.
|
|
@@ -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,
|
|
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"}
|
package/dist/session/agent.js
CHANGED
|
@@ -12,7 +12,7 @@ import { BASE_PATH_HEADER, TENANT_HEADER } from '../_shared/session-router.js';
|
|
|
12
12
|
import { decodeJsonBase64Url, encodeJsonBase64Url, pkceChallenge, randomBase64Url, sealJson, unsealJson, } from '@nimbus-sh/core/_shared/crypto.js';
|
|
13
13
|
import { clearNimbusAgentOAuthCookie, fetchNimbusCloudflareAccounts, isNimbusCloudflareAccountId, isNimbusTenantSegment, NIMBUS_CF_OAUTH_AUTH_URL, readNimbusCookie, readNimbusAgentCookieSecret, readNimbusAgentOAuthConfig, requestNimbusCloudflareOAuthToken, serializeNimbusCookie, } from './agent-oauth.js';
|
|
14
14
|
import { clearSessionAiCredential, createSessionAiModel, describeSessionAiConnection, readSessionAiConfig, resolveSessionAiCredential, sessionAiAccountIsAvailable, setSessionAiAccount, storeSessionAiCredential, } from './ai.js';
|
|
15
|
-
import { ensureProgrammaticReady, rpcExec, rpcEnsureRuntimes, rpcInstallRuntime, rpcKillProcess, rpcListPorts, rpcListProcesses, rpcProcessLogs, rpcStartProcess, } from './programmatic.js';
|
|
15
|
+
import { ensureProgrammaticReady, rpcExec, rpcEnsureRuntimes, rpcInstallRuntime, rpcExposeApp, rpcKillProcess, rpcListApps, rpcListPorts, rpcListProcesses, rpcProcessLogs, rpcStartProcess, } from './programmatic.js';
|
|
16
16
|
import { resolveVfsPath } from '@nimbus-sh/core/vfs/path.js';
|
|
17
17
|
import { appendTextPart, interruptRunningTools, textFromParts, upsertStoredMessage, upsertToolPart, } from './agent-contract.js';
|
|
18
18
|
import { CRED_KERNEL } from '@nimbus-sh/core/runtime/os-contracts.js';
|
|
@@ -645,6 +645,20 @@ function createAiSdkTools(self) {
|
|
|
645
645
|
inputSchema: toolSchema({}, []),
|
|
646
646
|
execute: async (args) => runTool(self, 'list_ports', args),
|
|
647
647
|
}),
|
|
648
|
+
expose_app: aiTool({
|
|
649
|
+
description: 'Expose a running application by port, pid or name: reserves its port under its identity, optionally names it and makes it public, and returns its URL.',
|
|
650
|
+
inputSchema: toolSchema({
|
|
651
|
+
target: stringProp('Port number, process id, or app name.'),
|
|
652
|
+
visibility: stringProp("'scoped' (default) or 'public' — public mints a shareable capability URL."),
|
|
653
|
+
name: stringProp('Optional DNS-label name for the app, e.g. "api".'),
|
|
654
|
+
}, ['target']),
|
|
655
|
+
execute: async (args) => runTool(self, 'expose_app', args),
|
|
656
|
+
}),
|
|
657
|
+
list_apps: aiTool({
|
|
658
|
+
description: 'List every application the session knows: owner, name, port, pid, status, visibility, restart policy and URL.',
|
|
659
|
+
inputSchema: toolSchema({}, []),
|
|
660
|
+
execute: async (args) => runTool(self, 'list_apps', args),
|
|
661
|
+
}),
|
|
648
662
|
};
|
|
649
663
|
}
|
|
650
664
|
function collectTurnParts(result) {
|
|
@@ -872,6 +886,19 @@ async function runTool(self, name, args) {
|
|
|
872
886
|
}
|
|
873
887
|
if (name === 'list_ports')
|
|
874
888
|
return rpcListPorts(self);
|
|
889
|
+
if (name === 'expose_app') {
|
|
890
|
+
const raw = String(args.target ?? '').trim();
|
|
891
|
+
if (!raw)
|
|
892
|
+
return { error: 'target is required' };
|
|
893
|
+
const visibility = args.visibility === 'public' ? 'public' : args.visibility === 'scoped' ? 'scoped' : undefined;
|
|
894
|
+
const appName = typeof args.name === 'string' && args.name.trim() ? args.name.trim() : undefined;
|
|
895
|
+
return rpcExposeApp(self, /^\d+$/.test(raw) ? Number(raw) : raw, {
|
|
896
|
+
...(visibility !== undefined ? { visibility } : {}),
|
|
897
|
+
...(appName !== undefined ? { name: appName } : {}),
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
if (name === 'list_apps')
|
|
901
|
+
return rpcListApps(self);
|
|
875
902
|
return { error: `unknown tool: ${name}` };
|
|
876
903
|
}
|
|
877
904
|
catch (e) {
|
|
@@ -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"}
|
package/dist/session/helpers.js
CHANGED
|
@@ -430,6 +430,58 @@ export function detectBundlerBin(script) {
|
|
|
430
430
|
}
|
|
431
431
|
return null;
|
|
432
432
|
}
|
|
433
|
+
/**
|
|
434
|
+
* Whether `npm run <scriptName>` (or `npm start`/`npm test`) should refuse
|
|
435
|
+
* before dispatch because the resolved script invokes `next` on a
|
|
436
|
+
* subcommand Nimbus cannot run: `dev`, `start`, `build`, or `export` all
|
|
437
|
+
* need the same missing pipeline — webpack/Turbopack bundling,
|
|
438
|
+
* child_process.fork with v8-IPC, custom http.Server semantics.
|
|
439
|
+
*
|
|
440
|
+
* Returns the blocked subcommand ('dev'|'start'|'build'|'export') or null.
|
|
441
|
+
* `--force` / `--allow-next` in the script args bypasses the refusal.
|
|
442
|
+
* scriptName 'dev'/'start' on a next-depending package refuses even when
|
|
443
|
+
* the script body doesn't name `next` (custom dev servers), matching the
|
|
444
|
+
* pre-extension dev/start-only behavior.
|
|
445
|
+
*/
|
|
446
|
+
export function refusedNextSubcommand(scriptName, script, pkg, scriptArgs) {
|
|
447
|
+
if (scriptArgs.includes('--force') || scriptArgs.includes('--allow-next'))
|
|
448
|
+
return null;
|
|
449
|
+
if (!(pkg.dependencies?.next || pkg.devDependencies?.next))
|
|
450
|
+
return null;
|
|
451
|
+
if (scriptName === 'dev' || scriptName === 'start')
|
|
452
|
+
return scriptName;
|
|
453
|
+
// For other script names the script body must actually invoke a blocked
|
|
454
|
+
// next subcommand. Tokens: skip env assignments and cross-env/env/npx.
|
|
455
|
+
const tokens = (script || '').trim().split(/\s+/);
|
|
456
|
+
let i = 0;
|
|
457
|
+
while (i < tokens.length) {
|
|
458
|
+
const t = tokens[i];
|
|
459
|
+
if (/^[A-Z_][A-Z0-9_]*=/.test(t) || t === 'cross-env' || t === 'env' || t === 'npx') {
|
|
460
|
+
i++;
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
const bin = (tokens[i] || '').replace(/^\.\/node_modules\/\.bin\//, '');
|
|
466
|
+
if (bin !== 'next' && !bin.startsWith('next.'))
|
|
467
|
+
return null;
|
|
468
|
+
const sub = tokens[i + 1];
|
|
469
|
+
if (sub === 'dev' || sub === 'start' || sub === 'build' || sub === 'export')
|
|
470
|
+
return sub;
|
|
471
|
+
return null;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* The refusal message for `refusedNextSubcommand` — identical blockers and
|
|
475
|
+
* escape hatch for every blocked subcommand.
|
|
476
|
+
*/
|
|
477
|
+
export const NEXT_REFUSAL_MESSAGE = '\x1b[31m✘\x1b[0m \x1b[1mNext.js is not supported in Nimbus.\x1b[0m\n' +
|
|
478
|
+
' Specific blockers:\n' +
|
|
479
|
+
" 1. \x1b[2mchild_process.fork\x1b[0m IPC uses v8-serializer (Nimbus ships JSON projection).\n" +
|
|
480
|
+
' 2. webpack / Turbopack bundlers are not integrated with the pre-bundle pipeline.\n' +
|
|
481
|
+
' 3. Custom \x1b[2mhttp.Server\x1b[0m semantics (keep-alive, raw sockets) are facet-incompatible.\n' +
|
|
482
|
+
'\n' +
|
|
483
|
+
' Workaround: run the Next.js project outside Nimbus (or a hosted runtime),\n' +
|
|
484
|
+
' or pass \x1b[36m--allow-next\x1b[0m to bypass at your own risk.\n';
|
|
433
485
|
/**
|
|
434
486
|
* Check whether a project directory has installed dependencies.
|
|
435
487
|
*
|
|
@@ -462,3 +514,27 @@ export function checkNodeModulesGuard(vfs, projectRoot) {
|
|
|
462
514
|
return { missing: false, depCount: 0 };
|
|
463
515
|
}
|
|
464
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* Bound for the `vite build` esbuild bundle step (init.ts). Demo-app
|
|
519
|
+
* builds take seconds; anything past this is a stall, not a build.
|
|
520
|
+
*/
|
|
521
|
+
export const VITE_BUILD_TIMEOUT_MS = 120_000;
|
|
522
|
+
/**
|
|
523
|
+
* G5: race an unbounded await against a loud timeout.
|
|
524
|
+
*
|
|
525
|
+
* The timeout does not cancel `work` (there is nothing to cancel an
|
|
526
|
+
* in-isolate esbuild bundle with) — it stops *waiting* and rejects
|
|
527
|
+
* with an error that names what was attempted and how long it ran,
|
|
528
|
+
* so a stalled build surfaces as a timeout error instead of silence.
|
|
529
|
+
* The timer handle never escapes the executor, so there is nothing
|
|
530
|
+
* to null-check: settle clears it on every path.
|
|
531
|
+
*/
|
|
532
|
+
export function withLoudTimeout(work, timeoutMs, what) {
|
|
533
|
+
return new Promise((resolve, reject) => {
|
|
534
|
+
const timer = setTimeout(() => {
|
|
535
|
+
reject(new Error(`${what} produced no result after ${(timeoutMs / 1000).toFixed(0)}s — ` +
|
|
536
|
+
'stopped waiting (the work may still finish in the background; re-run to retry).'));
|
|
537
|
+
}, timeoutMs);
|
|
538
|
+
work.then((value) => { clearTimeout(timer); resolve(value); }, (error) => { clearTimeout(timer); reject(error); });
|
|
539
|
+
});
|
|
540
|
+
}
|
|
@@ -88,6 +88,6 @@ export declare function joinExistingSession(self: {
|
|
|
88
88
|
};
|
|
89
89
|
_b4Phase: SessionState | null;
|
|
90
90
|
_b4WarmJoinCount: number;
|
|
91
|
-
}, ws: WebSocket,
|
|
91
|
+
}, ws: WebSocket, tee: (frame: string) => void, loadScrollback: (ctx: any) => string): void;
|
|
92
92
|
export {};
|
|
93
93
|
//# sourceMappingURL=init-phases.d.ts.map
|
|
@@ -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,0CAA0C,CAAC;AAElG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EACtD,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,iBAAiB,CAG7E;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,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,
|
|
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,0CAA0C,CAAC;AAElG,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE;IAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,EACtD,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,MAAM,GACd,IAAI,CAcN;AAED,KAAK,iBAAiB,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,gBAAgB,CAAC;CACxB,EAAE,OAAO,EAAE,SAAS,SAAS,EAAE,EAAE,GAAG,GAAE,MAAmB,GAAG,iBAAiB,CAG7E;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,gBAAgB,EAAE,MAAM,CAAC;CAC1B,EACD,EAAE,EAAE,SAAS,EACb,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC5B,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,MAAM,GACnC,IAAI,CAiCN"}
|
|
@@ -91,7 +91,7 @@ export function classifyWsUpgrade(self, sockets, now = Date.now()) {
|
|
|
91
91
|
* needed here; init-phases.ts shouldn't grow a circular dep on
|
|
92
92
|
* nimbus-session-internal.
|
|
93
93
|
*/
|
|
94
|
-
export function joinExistingSession(self, ws,
|
|
94
|
+
export function joinExistingSession(self, ws, tee, loadScrollback) {
|
|
95
95
|
// Phase R — pure SQL reads. No-op on warm rejoin (live state is
|
|
96
96
|
// already correct in self.shell / self.terminal). Recorded in the
|
|
97
97
|
// ring for symmetry with cold init.
|
|
@@ -101,17 +101,7 @@ export function joinExistingSession(self, ws, appendScrollback, loadScrollback)
|
|
|
101
101
|
// the same WebSocketTerminal instance is preserved (we mutate
|
|
102
102
|
// its internal ws ref via attach()).
|
|
103
103
|
setPhase(self, 'wire', 'warm-rejoin');
|
|
104
|
-
self.terminal.attach(ws,
|
|
105
|
-
try {
|
|
106
|
-
appendScrollback(self.ctx, frame, Date.now());
|
|
107
|
-
}
|
|
108
|
-
catch (e) {
|
|
109
|
-
try {
|
|
110
|
-
console.warn("[B'.3] appendScrollback failed:", e?.message || e);
|
|
111
|
-
}
|
|
112
|
-
catch { }
|
|
113
|
-
}
|
|
114
|
-
});
|
|
104
|
+
self.terminal.attach(ws, tee);
|
|
115
105
|
// Replay scrollback to the new ws so the user sees the prior
|
|
116
106
|
// session's terminal contents. Same shape as cold-init's replay
|
|
117
107
|
// when persisted state exists.
|
package/dist/session/init.d.ts
CHANGED
|
@@ -47,6 +47,20 @@ type InitHost = SessionInternal & {
|
|
|
47
47
|
readonly ctx: any;
|
|
48
48
|
readonly env: any;
|
|
49
49
|
};
|
|
50
|
-
|
|
50
|
+
/**
|
|
51
|
+
* How the socket being wired came to need a session.
|
|
52
|
+
*
|
|
53
|
+
* - reconnect: a fresh terminal on a fresh /ws upgrade. Its screen is
|
|
54
|
+
* empty, so the persisted scrollback is replayed above the live prompt.
|
|
55
|
+
* - wake: the socket was accepted by a previous instance and outlived it
|
|
56
|
+
* in hibernation; the peer's screen still shows everything up to the
|
|
57
|
+
* sleep. Replaying scrollback there duplicates what the peer already
|
|
58
|
+
* has, and a driver waiting for a fresh prompt would take the replayed
|
|
59
|
+
* one for its answer. Only the resumed-instance notice is written.
|
|
60
|
+
*/
|
|
61
|
+
export interface InitSessionOptions {
|
|
62
|
+
resume?: 'reconnect' | 'wake';
|
|
63
|
+
}
|
|
64
|
+
export declare function initSession(self: InitHost, ws: WebSocket, options?: InitSessionOptions): Promise<void>;
|
|
51
65
|
export {};
|
|
52
66
|
//# sourceMappingURL=init.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/session/init.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;
|
|
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"}
|