@tangle-network/agent-app 0.44.59 → 0.45.1
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/dist/assistant/index.js +1 -1
- package/dist/chat-routes/index.js +1 -1
- package/dist/{chunk-HCOROIRT.js → chunk-BATKJP3P.js} +8 -5
- package/dist/chunk-BATKJP3P.js.map +1 -0
- package/dist/{chunk-2UDJH6QR.js → chunk-EC7CUA4L.js} +37 -310
- package/dist/chunk-EC7CUA4L.js.map +1 -0
- package/dist/sandbox/index.d.ts +142 -225
- package/dist/sandbox/index.js +3 -35
- package/dist/web-react/index.js +1 -1
- package/dist/web-react/terminal.d.ts +44 -3
- package/dist/web-react/terminal.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2UDJH6QR.js.map +0 -1
- package/dist/chunk-HCOROIRT.js.map +0 -1
package/dist/sandbox/index.d.ts
CHANGED
|
@@ -261,21 +261,7 @@ declare function statSandboxFileSize(box: SandboxExecChannel, absolutePath: stri
|
|
|
261
261
|
* mismatch is reported, never returned as a short buffer. */
|
|
262
262
|
declare function readSandboxBinaryBytes(box: SandboxExecChannel, absolutePath: string, expectedSize: number, options?: SandboxExecOptions): Promise<SandboxFileBytesOutcome>;
|
|
263
263
|
|
|
264
|
-
/** Define
|
|
265
|
-
interface TerminalProxyIdentity {
|
|
266
|
-
userId: string;
|
|
267
|
-
workspaceId: string;
|
|
268
|
-
sandboxId: string;
|
|
269
|
-
}
|
|
270
|
-
/** Generate a signed token for TerminalProxyIdentity with an expiration based on TTL milliseconds */
|
|
271
|
-
declare function mintTerminalProxyToken(secret: string, identity: TerminalProxyIdentity, ttlMs?: number, now?: () => number): Promise<Outcome<{
|
|
272
|
-
token: string;
|
|
273
|
-
expiresAt: Date;
|
|
274
|
-
}>>;
|
|
275
|
-
/** Verify the authenticity and validity of a terminal proxy token against expected identity and timestamp */
|
|
276
|
-
declare function verifyTerminalProxyToken(secret: string, token: string, expected: TerminalProxyIdentity, now?: () => number): Promise<boolean>;
|
|
277
|
-
|
|
278
|
-
/** Define the shape of a workspace sandbox instance including its connection details and status */
|
|
264
|
+
/** Define the shape of a workspace sandbox instance including its connection details and status. */
|
|
279
265
|
interface WorkspaceSandboxInstanceLike {
|
|
280
266
|
id: string;
|
|
281
267
|
name?: string;
|
|
@@ -288,12 +274,12 @@ interface WorkspaceSandboxInstanceLike {
|
|
|
288
274
|
authTokenExpiresAt?: string;
|
|
289
275
|
} | null;
|
|
290
276
|
}
|
|
291
|
-
/** Define the context containing workspace and user identifiers for sandbox environment operations */
|
|
277
|
+
/** Define the context containing workspace and user identifiers for sandbox environment operations. */
|
|
292
278
|
interface WorkspaceSandboxEnsureContext {
|
|
293
279
|
workspaceId: string;
|
|
294
280
|
userId: string;
|
|
295
281
|
}
|
|
296
|
-
/** Define configuration options for managing
|
|
282
|
+
/** Define configuration options for managing workspace sandboxes. */
|
|
297
283
|
interface WorkspaceSandboxManagerOptions<TClient, TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void> {
|
|
298
284
|
getClient: (ctx: WorkspaceSandboxEnsureContext) => Promise<TClient> | TClient;
|
|
299
285
|
nameForWorkspace: (workspaceId: string, ctx: WorkspaceSandboxEnsureContext) => string;
|
|
@@ -310,230 +296,161 @@ interface WorkspaceSandboxManagerOptions<TClient, TBox extends WorkspaceSandboxI
|
|
|
310
296
|
prepareCreated?: (box: TBox, ctx: WorkspaceSandboxEnsureContext, options: TEnsureOptions) => Promise<TBox | void>;
|
|
311
297
|
onListError?: (error: unknown, ctx: WorkspaceSandboxEnsureContext) => void;
|
|
312
298
|
}
|
|
313
|
-
/** Manage workspace sandboxes by ensuring their creation and retrieval for specified users */
|
|
299
|
+
/** Manage workspace sandboxes by ensuring their creation and retrieval for specified users. */
|
|
314
300
|
interface WorkspaceSandboxManager<TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void> {
|
|
315
301
|
ensureWorkspaceSandbox: (workspaceId: string, userId: string, options?: TEnsureOptions) => Promise<TBox>;
|
|
316
302
|
}
|
|
317
|
-
/**
|
|
303
|
+
/**
|
|
304
|
+
* Create a generic name-keyed sandbox lifecycle manager for products that
|
|
305
|
+
* drive their own SDK or box types.
|
|
306
|
+
*/
|
|
318
307
|
declare function createWorkspaceSandboxManager<TClient, TBox extends WorkspaceSandboxInstanceLike, TEnsureOptions = void>(opts: WorkspaceSandboxManagerOptions<TClient, TBox, TEnsureOptions>): WorkspaceSandboxManager<TBox, TEnsureOptions>;
|
|
319
|
-
|
|
320
|
-
interface SandboxTerminalTokenOptions {
|
|
321
|
-
secret?: string;
|
|
322
|
-
expiresInMs?: number;
|
|
323
|
-
now?: () => number;
|
|
324
|
-
}
|
|
325
|
-
/** Resolve the identity type used for sandbox terminal token subjects */
|
|
326
|
-
type SandboxTerminalTokenSubject = TerminalProxyIdentity;
|
|
327
|
-
/** Provide token and expiration details for a sandbox terminal session */
|
|
328
|
-
interface SandboxTerminalTokenResult {
|
|
329
|
-
token: string;
|
|
330
|
-
expiresAt: Date;
|
|
331
|
-
}
|
|
332
|
-
/** Generate a sandbox terminal token for a given subject with specified options */
|
|
333
|
-
declare function createSandboxTerminalToken(subject: SandboxTerminalTokenSubject, opts: SandboxTerminalTokenOptions): Promise<SandboxTerminalTokenResult>;
|
|
334
|
-
/** Verify the validity of a sandbox terminal token against the expected identity and options */
|
|
335
|
-
declare function verifySandboxTerminalToken(token: string, expected: SandboxTerminalTokenSubject, opts: SandboxTerminalTokenOptions): Promise<boolean>;
|
|
336
|
-
/** Represent an authenticated user within a sandbox environment with a unique identifier */
|
|
337
|
-
interface AuthenticatedSandboxUser {
|
|
338
|
-
id: string;
|
|
339
|
-
}
|
|
340
|
-
/** Define options to handle workspace sandbox connections with user authentication and access control */
|
|
341
|
-
interface WorkspaceSandboxConnectionHandlerOptions<TBox extends WorkspaceSandboxInstanceLike> {
|
|
342
|
-
requireUser: (request: Request) => Promise<AuthenticatedSandboxUser>;
|
|
343
|
-
requireWorkspaceAccess: (args: {
|
|
344
|
-
request: Request;
|
|
345
|
-
userId: string;
|
|
346
|
-
workspaceId: string;
|
|
347
|
-
}) => Promise<void>;
|
|
348
|
-
ensureWorkspaceSandbox: (workspaceId: string, userId: string) => Promise<TBox>;
|
|
349
|
-
tokenSecret: string | (() => string | undefined);
|
|
350
|
-
tokenExpiresInMs?: number;
|
|
351
|
-
proxyRuntimeUrl?: (args: {
|
|
352
|
-
request: Request;
|
|
353
|
-
workspaceId: string;
|
|
354
|
-
sandboxId: string;
|
|
355
|
-
box: TBox;
|
|
356
|
-
}) => string;
|
|
357
|
-
exposeDirectSidecar?: boolean;
|
|
358
|
-
}
|
|
359
|
-
/** Define arguments required to establish a workspace sandbox connection */
|
|
360
|
-
interface WorkspaceSandboxConnectionArgs {
|
|
361
|
-
request: Request;
|
|
362
|
-
params: {
|
|
363
|
-
workspaceId?: string;
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
/** Create a handler to resolve workspace sandbox connections with user and access validation */
|
|
367
|
-
declare function createWorkspaceSandboxConnectionHandler<TBox extends WorkspaceSandboxInstanceLike>(opts: WorkspaceSandboxConnectionHandlerOptions<TBox>): ({ request, params }: WorkspaceSandboxConnectionArgs) => Promise<Response>;
|
|
368
|
-
/** Define credentials required to access the sandbox API environment */
|
|
369
|
-
interface SandboxApiCredentials {
|
|
370
|
-
baseUrl: string;
|
|
371
|
-
apiKey: string;
|
|
372
|
-
}
|
|
308
|
+
|
|
373
309
|
/**
|
|
374
|
-
*
|
|
375
|
-
* `{baseUrl}/v1/sidecar-proxy/{sandboxId}`.
|
|
310
|
+
* Browser-direct scoped-token terminal connection route (#341/#349).
|
|
376
311
|
*
|
|
377
|
-
*
|
|
378
|
-
*
|
|
379
|
-
*
|
|
312
|
+
* Epic #343 / decision #341: the fleet's terminal transport is browser-direct
|
|
313
|
+
* — the product's server authenticates the request and provisions/resolves
|
|
314
|
+
* the sandbox exactly once, mints a short-lived SDK scoped token
|
|
315
|
+
* (`box.mintScopedToken`), and hands the browser just enough to connect
|
|
316
|
+
* `TerminalView` straight to the sidecar. No worker relays terminal bytes.
|
|
317
|
+
* The deprecated same-origin relay was removed in #350 after the fleet
|
|
318
|
+
* migrated, leaving this as the package's only terminal transport.
|
|
380
319
|
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
* | `/v1/sidecar-proxy/{id}` | 101 -> `ready` 2551ms -> shell |
|
|
384
|
-
* | `/v1/sandboxes/{id}/runtime/` | HTTP 500 |
|
|
385
|
-
* | `connection.runtimeUrl` (the box host) | 101 then close 1000, 0 bytes |
|
|
320
|
+
* VERIFIED PLATFORM CONTRACT (`@tangle-network/sandbox` 0.15.2 + the
|
|
321
|
+
* orchestrator/sidecar enforcement source, verified 2026-07-30):
|
|
386
322
|
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
323
|
+
* 1. Only a `scope: 'session-runtime'` token carries the `terminal`
|
|
324
|
+
* capability (`cap: ["read", "workspace", "terminal"]`). `'project'` and
|
|
325
|
+
* `'session'` mint SessionGateway READ tokens (HS256, `typ: "read"`, no
|
|
326
|
+
* `cap` claim at all — a different token family the sidecar rejects
|
|
327
|
+
* outright); `'read-only'` carries `cap: ["read"]` only. **No scope other
|
|
328
|
+
* than `'session-runtime'` can ever open a terminal**, which is why this
|
|
329
|
+
* route no longer takes `scope` as a parameter — it is pinned.
|
|
330
|
+
* 2. The orchestrator's terminal WS gate fails closed unless the token's
|
|
331
|
+
* `sid` claim EQUALS the `<connectionId>` path segment of
|
|
332
|
+
* `/terminals/<connectionId>/ws`
|
|
333
|
+
* (`verifyScopedSidecarCapability(sidecar, token, "terminal", connectionId)`).
|
|
334
|
+
* So `mintScopedToken({ scope: 'session-runtime', sessionId })` MUST be
|
|
335
|
+
* called with `sessionId === connectionId` — the exact id `TerminalView`
|
|
336
|
+
* will dial. That is why this route threads a `connectionId` end to end
|
|
337
|
+
* instead of deriving its own session id.
|
|
338
|
+
* 3. The browser-safe terminal base is the mint result's `sidecarProxyUrl`
|
|
339
|
+
* (`/v1/sidecar-proxy/{id}` on the Sandbox API) — **not**
|
|
340
|
+
* `box.connection.runtimeUrl`. The SDK's own `_attachTerminal` is the
|
|
341
|
+
* reference implementation:
|
|
342
|
+
* `mintScopedToken({ scope: 'session-runtime', sessionId: connectionId })`
|
|
343
|
+
* then dial `${scoped.sidecarProxyUrl}/terminals/${connectionId}/ws`.
|
|
344
|
+
* Pointing `TerminalView` at `runtimeUrl` fails auth regardless of scope —
|
|
345
|
+
* only the sidecar-proxy hop decodes the browser's
|
|
346
|
+
* `bearer.<base64url>` WS subprotocol.
|
|
392
347
|
*
|
|
393
|
-
*
|
|
348
|
+
* HISTORICAL NOTE: an earlier shape of this route (and legal-agent's
|
|
349
|
+
* production route it was modeled on, `scope: 'project'` +
|
|
350
|
+
* `connection.runtimeUrl`) predates the platform's terminal-auth hardening —
|
|
351
|
+
* the terminal capability gate (2026-06-19), the scoped-token terminal WS
|
|
352
|
+
* path (2026-07-15), and the `sid`-binding fail-closed check
|
|
353
|
+
* (2026-07-17/18). That shape does not authenticate on the current platform
|
|
354
|
+
* and is not a valid spec for the token path anymore.
|
|
355
|
+
*
|
|
356
|
+
* SECURITY POSTURE: unlike the read-only session-gateway streaming token
|
|
357
|
+
* (`box.mintScopedToken({scope:'session'})` paired with
|
|
358
|
+
* `SessionGatewayClient`), the token this route mints grants **command
|
|
359
|
+
* execution** in the sandbox once handed to `TerminalView`. Its safety rests
|
|
360
|
+
* on a **short TTL** (default 15 minutes, the SDK's own max — still a caller
|
|
361
|
+
* parameter) and, structurally, the narrowest scope the platform offers: one
|
|
362
|
+
* box (`ensureSandbox` resolved it for THIS user), one terminal connection
|
|
363
|
+
* (`session-runtime` bound to a single `sid`). Widening the TTL default
|
|
364
|
+
* without an explicit reason is a security regression, not a convenience.
|
|
365
|
+
*
|
|
366
|
+
* Wire contract: the browser passes the response's `sidecarUrl` as
|
|
367
|
+
* `TerminalView`'s `apiUrl` prop, `token` as its token prop, and the
|
|
368
|
+
* response's echoed `connectionId` as `TerminalView`'s `connectionId` prop —
|
|
369
|
+
* the token's `sid` is bound to exactly that id, so any other value fails the
|
|
370
|
+
* WS upgrade. sandbox-ui sends the token as a `bearer.<base64url>` WebSocket
|
|
371
|
+
* subprotocol (browsers cannot set `Authorization` on a WS handshake).
|
|
372
|
+
* `useSandboxTerminalConnection` (`../web-react/sandbox-terminal`) carries
|
|
373
|
+
* `connectionId` through automatically.
|
|
394
374
|
*/
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}
|
|
402
|
-
/** Define options for handling workspace sandbox runtime proxy including user, access, credentials, and connection retrieval */
|
|
403
|
-
interface WorkspaceSandboxRuntimeProxyHandlerOptions {
|
|
404
|
-
requireUser: (request: Request) => Promise<AuthenticatedSandboxUser>;
|
|
405
|
-
requireWorkspaceAccess: (args: {
|
|
406
|
-
request: Request;
|
|
407
|
-
userId: string;
|
|
408
|
-
workspaceId: string;
|
|
409
|
-
sandboxId: string;
|
|
410
|
-
}) => Promise<void>;
|
|
411
|
-
getSandboxApiCredentials: (args: {
|
|
412
|
-
request: Request;
|
|
413
|
-
userId: string;
|
|
414
|
-
workspaceId: string;
|
|
415
|
-
sandboxId: string;
|
|
416
|
-
}) => Promise<SandboxApiCredentials>;
|
|
417
|
-
getSandboxRuntimeConnection?: (args: {
|
|
418
|
-
request: Request;
|
|
419
|
-
userId: string;
|
|
420
|
-
workspaceId: string;
|
|
421
|
-
sandboxId: string;
|
|
422
|
-
}) => Promise<SandboxRuntimeConnection | null | undefined>;
|
|
423
|
-
tokenSecret: string | (() => string | undefined);
|
|
424
|
-
fetch?: typeof fetch;
|
|
425
|
-
forwardHeaders?: string[];
|
|
426
|
-
}
|
|
427
|
-
/** Define arguments for proxying runtime requests within a workspace sandbox environment */
|
|
428
|
-
interface WorkspaceSandboxRuntimeProxyArgs {
|
|
429
|
-
request: Request;
|
|
430
|
-
params: {
|
|
431
|
-
workspaceId?: string;
|
|
432
|
-
sandboxId?: string;
|
|
433
|
-
'*'?: string;
|
|
375
|
+
/** The structural surface this route needs from an SDK sandbox box — no `@tangle-network/sandbox` class import (invariant 3). */
|
|
376
|
+
interface TerminalConnectionBoxLike {
|
|
377
|
+
id: string;
|
|
378
|
+
status?: string;
|
|
379
|
+
connection?: {
|
|
380
|
+
runtimeUrl?: string;
|
|
434
381
|
};
|
|
382
|
+
mintScopedToken(opts: {
|
|
383
|
+
scope: string;
|
|
384
|
+
sessionId?: string;
|
|
385
|
+
ttlMinutes?: number;
|
|
386
|
+
}): Promise<{
|
|
387
|
+
token: string;
|
|
388
|
+
expiresAt: Date;
|
|
389
|
+
sidecarProxyUrl: string;
|
|
390
|
+
}>;
|
|
435
391
|
}
|
|
436
|
-
/**
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
*/
|
|
452
|
-
|
|
453
|
-
/**
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
392
|
+
/** Configuration for {@link createSandboxTerminalConnectionRoute}. */
|
|
393
|
+
interface SandboxTerminalConnectionRouteOptions<TBox extends TerminalConnectionBoxLike, TUser> {
|
|
394
|
+
/**
|
|
395
|
+
* Authenticate the incoming request. Return the authenticated user, or a
|
|
396
|
+
* `Response` to short-circuit the route (e.g. a 401) — that Response is
|
|
397
|
+
* returned to the caller verbatim.
|
|
398
|
+
*/
|
|
399
|
+
requireUser(request: Request): Promise<TUser | Response>;
|
|
400
|
+
/**
|
|
401
|
+
* Resolve (provisioning if needed) the sandbox this user's terminal should
|
|
402
|
+
* connect to. Domain-specific provisioning (workspace- vs user-scoped,
|
|
403
|
+
* naming, reuse) stays entirely in the product's implementation of this
|
|
404
|
+
* seam — the route only reacts to success/failure.
|
|
405
|
+
*/
|
|
406
|
+
ensureSandbox(user: TUser, request: Request): Promise<TBox>;
|
|
407
|
+
/** `box.mintScopedToken` TTL in minutes. Default `15` (the SDK's own max). */
|
|
408
|
+
ttlMinutes?: number;
|
|
409
|
+
/**
|
|
410
|
+
* Resolve the terminal connection id the minted token's `sid` is bound to
|
|
411
|
+
* — this MUST be the same id `TerminalView` dials
|
|
412
|
+
* (`tabTerminalConnectionId()`), because the orchestrator's terminal WS
|
|
413
|
+
* gate fails closed unless `sid === <connectionId>` in
|
|
414
|
+
* `/terminals/<connectionId>/ws`.
|
|
415
|
+
*
|
|
416
|
+
* `requested` is `new URL(request.url).searchParams.get('connectionId')`.
|
|
417
|
+
* The default resolver returns `requested` unchanged. A product may
|
|
418
|
+
* validate/namespace the id here (e.g. a per-user prefix in a shared box)
|
|
419
|
+
* — if it rewrites the id, the client MUST use the response's echoed
|
|
420
|
+
* `connectionId`, since the sid binding makes any other id fail the WS
|
|
421
|
+
* upgrade.
|
|
422
|
+
*
|
|
423
|
+
* A resolved falsy/empty value fails the request with a 400 before any
|
|
424
|
+
* sandbox work happens.
|
|
425
|
+
*/
|
|
426
|
+
resolveConnectionId?: (ctx: {
|
|
471
427
|
request: Request;
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
}) => Promise<
|
|
476
|
-
tokenSecret: string | (() => string | undefined);
|
|
477
|
-
fetch?: typeof fetch;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Build a Worker-entry handler that proxies a sandbox terminal WebSocket
|
|
481
|
-
* upgrade to the sandbox API runtime proxy. Returns `null` when the request is
|
|
482
|
-
* not a terminal WS upgrade, so the caller can fall through to its normal
|
|
483
|
-
* request handler:
|
|
484
|
-
*
|
|
485
|
-
* ```ts
|
|
486
|
-
* const handled = await handleSandboxTerminalUpgrade(request)
|
|
487
|
-
* if (handled) return handled
|
|
488
|
-
* ```
|
|
489
|
-
*/
|
|
490
|
-
declare function createWorkspaceSandboxTerminalUpgradeHandler(opts: WorkspaceSandboxTerminalUpgradeHandlerOptions): (request: Request) => Promise<Response | null>;
|
|
491
|
-
/** A response-like shape carrying just what the subprotocol echo decision reads. */
|
|
492
|
-
interface TerminalUpgradeResponseLike {
|
|
493
|
-
status: number;
|
|
494
|
-
statusText?: string;
|
|
495
|
-
headers: Headers;
|
|
428
|
+
user: TUser;
|
|
429
|
+
box: TBox;
|
|
430
|
+
requested: string | null;
|
|
431
|
+
}) => string | null | undefined | Promise<string | null | undefined>;
|
|
496
432
|
}
|
|
497
433
|
/**
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
* `Authorization` on a WS handshake. That subprotocol is a browser-to-Worker
|
|
505
|
-
* credential, so it is stripped before the upstream hop — and the upstream then
|
|
506
|
-
* answers the 101 selecting nothing. A browser MUST fail the connection when a
|
|
507
|
-
* 101 selects no subprotocol after it offered one (RFC 6455 s4.1), so the socket
|
|
508
|
-
* dies on open and the terminal renders a spinner forever.
|
|
509
|
-
*
|
|
510
|
-
* Kept as a pure function because a 101 `Response` cannot be constructed off
|
|
511
|
-
* Workers, so this is the only part of the decision a test can drive directly.
|
|
512
|
-
*/
|
|
513
|
-
declare function terminalUpgradeSubprotocolEcho(upstream: TerminalUpgradeResponseLike, browserProtocol: string | null): {
|
|
514
|
-
status: number;
|
|
515
|
-
statusText: string;
|
|
516
|
-
headers: Headers;
|
|
517
|
-
} | null;
|
|
518
|
-
/**
|
|
519
|
-
* The exact `bearer.*` subprotocol string the browser offered, so it can be
|
|
520
|
-
* echoed verbatim on the 101. Returns null when the browser offered none.
|
|
434
|
+
* Build the browser-direct terminal connection route: `GET` handler that
|
|
435
|
+
* authenticates, resolves the sandbox, mints a scoped token pinned to
|
|
436
|
+
* `scope: 'session-runtime'` (the ONLY scope the platform grants the
|
|
437
|
+
* `terminal` capability to), and returns exactly what the browser needs to
|
|
438
|
+
* connect `TerminalView` directly to the sidecar — no worker in the data
|
|
439
|
+
* path once the terminal is open.
|
|
521
440
|
*
|
|
522
|
-
*
|
|
523
|
-
*
|
|
524
|
-
*
|
|
441
|
+
* Response shapes:
|
|
442
|
+
* - `requireUser` returns a `Response` → that `Response`, verbatim.
|
|
443
|
+
* - `ensureSandbox` throws → `500 {error}` (the thrown message surfaced).
|
|
444
|
+
* - `box.connection?.runtimeUrl` missing → `503 {error, status: box.status}`
|
|
445
|
+
* — this is a READINESS gate only; the URL returned to the client on
|
|
446
|
+
* success is always the mint's `sidecarProxyUrl`, never `runtimeUrl`.
|
|
447
|
+
* - resolved connection id is falsy/empty → `400 {error}`.
|
|
448
|
+
* - `box.mintScopedToken` rejects → `503 {error}`.
|
|
449
|
+
* - success → `200 {sidecarUrl, token, expiresAt, status, sandboxId, connectionId}`.
|
|
450
|
+
* `connectionId` is the id the token's `sid` is bound to — the client MUST
|
|
451
|
+
* hand this (not its own) to `TerminalView`.
|
|
525
452
|
*/
|
|
526
|
-
declare function
|
|
527
|
-
/** Build proxy headers for sandbox runtime including authorization and forwarded headers */
|
|
528
|
-
declare function buildSandboxRuntimeProxyHeaders(source: Headers, sandboxApiKey: string, forwardHeaders?: string[]): Headers;
|
|
529
|
-
/** Encode a runtime path by URI-encoding each valid segment and returning null for invalid segments */
|
|
530
|
-
declare function encodeSandboxRuntimePath(runtimePath: string): string | null;
|
|
531
|
-
/** Extract the token from a bearer authorization string or return null if invalid or missing */
|
|
532
|
-
declare function bearerToken(value: string | null): string | null;
|
|
533
|
-
/** Resolve and decode a bearer token from a comma-separated subprotocol string or return null */
|
|
534
|
-
declare function bearerSubprotocolToken(value: string | null): string | null;
|
|
535
|
-
/** Resolve the terminal token from request headers using Authorization or Sec-WebSocket-Protocol fields */
|
|
536
|
-
declare function terminalTokenFromRequest(headers: Headers): string | null;
|
|
453
|
+
declare function createSandboxTerminalConnectionRoute<TBox extends TerminalConnectionBoxLike, TUser>(opts: SandboxTerminalConnectionRouteOptions<TBox, TUser>): (request: Request) => Promise<Response>;
|
|
537
454
|
|
|
538
455
|
/**
|
|
539
456
|
* `createSandboxPrewarmer` — "this user just opened this project; start warming
|
|
@@ -1339,4 +1256,4 @@ declare function isTerminalPromptEvent(event: unknown): boolean;
|
|
|
1339
1256
|
/** Resolve the interactive question text from a structured event or return null if none found */
|
|
1340
1257
|
declare function detectInteractiveQuestion(event: unknown): string | null;
|
|
1341
1258
|
|
|
1342
|
-
export { type AppToolDescriptor, type
|
|
1259
|
+
export { type AppToolDescriptor, type BuildAppToolMcpServersOptions, type BuildSandboxToolFileMountsOptions, type D1PrewarmClaimStoreOptions, DEFAULT_PREWARM_CLAIM_TABLE, DEFAULT_SANDBOX_RESOURCES, DEFAULT_SIDECAR_PROCESS_PATTERN, type DriveSandboxTurnOptions, ENV_TOTAL_MAX_BYTES, ENV_VALUE_MAX_BYTES, type EnsureWorkspaceSandboxOptions, type LivenessProbeConfig, type MemberSyncSeam, type ModelSelection, type ModelSelectionError, type ModelSelectionFailure, type ModelSelectionSource, type Outcome, PREWARM_CLAIM_TABLE_DDL, PROVISION_PAYLOAD_MAX_BYTES, type PeekWorkspaceSandboxOutcome, type PrewarmClaimD1Like, type PrewarmClaimStore, type PrewarmDecision, type PrewarmEvent, type PrewarmOutcome, type PrewarmResult, type ProfileComposeOptions, type PromptInputPart, type ProviderResolutionConfig, type ProvisionPayloadSections, type ProvisionProfileSection, type ResolveSandboxClientCredentialsOptions, type ResolvedModel, type SandboxBuildContext, type SandboxClientCredentials, type SandboxCredentialEnvironment, SandboxEgressPolicyMismatchError, type SandboxEgressPolicySource, type SandboxExecChannel, type SandboxExecOptions, type SandboxExistingBoxStage, type SandboxFileBytesOutcome, type SandboxFileSizeOutcome, SandboxModelResolutionError, type SandboxPermissionLevel, type SandboxPrewarmScope, type SandboxPrewarmer, type SandboxPrewarmerOptions, type SandboxReadiness, SandboxRecoveryFailedError, type SandboxRecoveryPhase, type SandboxResourceConfig, type SandboxRestoreSpec, SandboxRuntimeAuthRefreshError, type SandboxRuntimeConfig, type SandboxScope, type SandboxStepTransition, type SandboxTerminalConnectionRouteOptions, type SandboxToolPathOptions, type SandboxToolSpec, type ScopedTokenResult, type SecretStore, type StoppedSandboxResumeFailure, type StoppedSandboxResumeRecovery, type StreamSandboxPromptOptions, type TerminalConnectionBoxLike, type WorkspaceSandboxEnsureContext, type WorkspaceSandboxInstanceLike, type WorkspaceSandboxManager, type WorkspaceSandboxManagerOptions, type WriteProfileFilesOptions, assertEnvWithinLimits, assertProvisionPayloadWithinCap, attachReasoningEffort, buildAppToolMcpServers, buildSandboxToolFileMounts, buildSandboxToolPathSetupScript, classifySeveredStream, collectSandboxPromptText, createD1PrewarmClaimStore, createSandboxPrewarmer, createSandboxTerminalConnectionRoute, createWorkspaceSandboxManager, deferredCorpusHash, deleteSecret, detectInteractiveQuestion, driveSandboxTurn, ensureWorkspaceSandbox, flattenHistory, getClient, isTerminalPromptEvent, mergeExtraMcp, mergeHistoryIntoParts, mintSandboxScopedToken, peekWorkspaceSandbox, readSandboxBinaryBytes, readSecret, requireTransportableModel, resetClientCache, resolveModel, resolveModelSelection, resolveSandboxClientCredentials, runSandboxPrompt, runSandboxToolPathSetup, sandboxToolBinDir, sandboxToolPath, sandboxToolRootDir, secretStoreFromClient, shellQuote, splitDeferredProfileFiles, statSandboxFileSize, storeSecret, streamSandboxPrompt, syncSandboxMemberAdd, syncSandboxMemberRemove, syncSandboxMemberRole, writeProfileFilesToBox };
|
package/dist/sandbox/index.js
CHANGED
|
@@ -13,36 +13,26 @@ import {
|
|
|
13
13
|
assertEnvWithinLimits,
|
|
14
14
|
assertProvisionPayloadWithinCap,
|
|
15
15
|
attachReasoningEffort,
|
|
16
|
-
bearerSubprotocolToken,
|
|
17
|
-
bearerToken,
|
|
18
16
|
buildAppToolMcpServers,
|
|
19
|
-
buildSandboxRuntimeProxyHeaders,
|
|
20
17
|
buildSandboxToolFileMounts,
|
|
21
18
|
buildSandboxToolPathSetupScript,
|
|
22
19
|
classifySeveredStream,
|
|
23
20
|
collectSandboxPromptText,
|
|
24
21
|
createD1PrewarmClaimStore,
|
|
25
22
|
createSandboxPrewarmer,
|
|
26
|
-
|
|
27
|
-
createWorkspaceSandboxConnectionHandler,
|
|
23
|
+
createSandboxTerminalConnectionRoute,
|
|
28
24
|
createWorkspaceSandboxManager,
|
|
29
|
-
createWorkspaceSandboxRuntimeProxyHandler,
|
|
30
|
-
createWorkspaceSandboxTerminalUpgradeHandler,
|
|
31
25
|
deferredCorpusHash,
|
|
32
26
|
deleteSecret,
|
|
33
27
|
detectInteractiveQuestion,
|
|
34
28
|
driveSandboxTurn,
|
|
35
|
-
encodeSandboxRuntimePath,
|
|
36
29
|
ensureWorkspaceSandbox,
|
|
37
30
|
flattenHistory,
|
|
38
31
|
getClient,
|
|
39
|
-
isSandboxTerminalWsUpgrade,
|
|
40
32
|
isTerminalPromptEvent,
|
|
41
|
-
matchSandboxTerminalWsPath,
|
|
42
33
|
mergeExtraMcp,
|
|
43
34
|
mergeHistoryIntoParts,
|
|
44
35
|
mintSandboxScopedToken,
|
|
45
|
-
mintTerminalProxyToken,
|
|
46
36
|
peekWorkspaceSandbox,
|
|
47
37
|
readSandboxBinaryBytes,
|
|
48
38
|
readSecret,
|
|
@@ -53,12 +43,10 @@ import {
|
|
|
53
43
|
resolveSandboxClientCredentials,
|
|
54
44
|
runSandboxPrompt,
|
|
55
45
|
runSandboxToolPathSetup,
|
|
56
|
-
sandboxSidecarProxyUrl,
|
|
57
46
|
sandboxToolBinDir,
|
|
58
47
|
sandboxToolPath,
|
|
59
48
|
sandboxToolRootDir,
|
|
60
49
|
secretStoreFromClient,
|
|
61
|
-
selectedBearerSubprotocol,
|
|
62
50
|
shellQuote,
|
|
63
51
|
splitDeferredProfileFiles,
|
|
64
52
|
statSandboxFileSize,
|
|
@@ -67,12 +55,8 @@ import {
|
|
|
67
55
|
syncSandboxMemberAdd,
|
|
68
56
|
syncSandboxMemberRemove,
|
|
69
57
|
syncSandboxMemberRole,
|
|
70
|
-
terminalTokenFromRequest,
|
|
71
|
-
terminalUpgradeSubprotocolEcho,
|
|
72
|
-
verifySandboxTerminalToken,
|
|
73
|
-
verifyTerminalProxyToken,
|
|
74
58
|
writeProfileFilesToBox
|
|
75
|
-
} from "../chunk-
|
|
59
|
+
} from "../chunk-EC7CUA4L.js";
|
|
76
60
|
import "../chunk-LWSJK546.js";
|
|
77
61
|
import "../chunk-CQZSAR77.js";
|
|
78
62
|
import "../chunk-ICOHEZK6.js";
|
|
@@ -95,36 +79,26 @@ export {
|
|
|
95
79
|
assertEnvWithinLimits,
|
|
96
80
|
assertProvisionPayloadWithinCap,
|
|
97
81
|
attachReasoningEffort,
|
|
98
|
-
bearerSubprotocolToken,
|
|
99
|
-
bearerToken,
|
|
100
82
|
buildAppToolMcpServers,
|
|
101
|
-
buildSandboxRuntimeProxyHeaders,
|
|
102
83
|
buildSandboxToolFileMounts,
|
|
103
84
|
buildSandboxToolPathSetupScript,
|
|
104
85
|
classifySeveredStream,
|
|
105
86
|
collectSandboxPromptText,
|
|
106
87
|
createD1PrewarmClaimStore,
|
|
107
88
|
createSandboxPrewarmer,
|
|
108
|
-
|
|
109
|
-
createWorkspaceSandboxConnectionHandler,
|
|
89
|
+
createSandboxTerminalConnectionRoute,
|
|
110
90
|
createWorkspaceSandboxManager,
|
|
111
|
-
createWorkspaceSandboxRuntimeProxyHandler,
|
|
112
|
-
createWorkspaceSandboxTerminalUpgradeHandler,
|
|
113
91
|
deferredCorpusHash,
|
|
114
92
|
deleteSecret,
|
|
115
93
|
detectInteractiveQuestion,
|
|
116
94
|
driveSandboxTurn,
|
|
117
|
-
encodeSandboxRuntimePath,
|
|
118
95
|
ensureWorkspaceSandbox,
|
|
119
96
|
flattenHistory,
|
|
120
97
|
getClient,
|
|
121
|
-
isSandboxTerminalWsUpgrade,
|
|
122
98
|
isTerminalPromptEvent,
|
|
123
|
-
matchSandboxTerminalWsPath,
|
|
124
99
|
mergeExtraMcp,
|
|
125
100
|
mergeHistoryIntoParts,
|
|
126
101
|
mintSandboxScopedToken,
|
|
127
|
-
mintTerminalProxyToken,
|
|
128
102
|
peekWorkspaceSandbox,
|
|
129
103
|
readSandboxBinaryBytes,
|
|
130
104
|
readSecret,
|
|
@@ -135,12 +109,10 @@ export {
|
|
|
135
109
|
resolveSandboxClientCredentials,
|
|
136
110
|
runSandboxPrompt,
|
|
137
111
|
runSandboxToolPathSetup,
|
|
138
|
-
sandboxSidecarProxyUrl,
|
|
139
112
|
sandboxToolBinDir,
|
|
140
113
|
sandboxToolPath,
|
|
141
114
|
sandboxToolRootDir,
|
|
142
115
|
secretStoreFromClient,
|
|
143
|
-
selectedBearerSubprotocol,
|
|
144
116
|
shellQuote,
|
|
145
117
|
splitDeferredProfileFiles,
|
|
146
118
|
statSandboxFileSize,
|
|
@@ -149,10 +121,6 @@ export {
|
|
|
149
121
|
syncSandboxMemberAdd,
|
|
150
122
|
syncSandboxMemberRemove,
|
|
151
123
|
syncSandboxMemberRole,
|
|
152
|
-
terminalTokenFromRequest,
|
|
153
|
-
terminalUpgradeSubprotocolEcho,
|
|
154
|
-
verifySandboxTerminalToken,
|
|
155
|
-
verifyTerminalProxyToken,
|
|
156
124
|
writeProfileFilesToBox
|
|
157
125
|
};
|
|
158
126
|
//# sourceMappingURL=index.js.map
|
package/dist/web-react/index.js
CHANGED
|
@@ -8,8 +8,21 @@ interface SandboxTerminalConnection {
|
|
|
8
8
|
error: string | null;
|
|
9
9
|
loading: boolean;
|
|
10
10
|
sandboxId?: string;
|
|
11
|
+
connectionId?: string;
|
|
11
12
|
}
|
|
12
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Define the response structure for a sandbox terminal connection including URLs, token, status, and errors
|
|
15
|
+
*
|
|
16
|
+
* The browser-direct scoped-token route (`createSandboxTerminalConnectionRoute`,
|
|
17
|
+
* `src/sandbox/terminal-connection.ts`) returns `sidecarUrl`. The hook also
|
|
18
|
+
* exposes that URL through the historical `runtimeUrl` state field so existing
|
|
19
|
+
* terminal panels do not need transport-specific branching.
|
|
20
|
+
*
|
|
21
|
+
* `connectionId` is the id the route's minted token's `sid` is bound to
|
|
22
|
+
* (echoed back from the `connectionId` the hook sent) — pass it straight
|
|
23
|
+
* through as `TerminalView`'s `connectionId` prop, since any other value
|
|
24
|
+
* fails the WS upgrade on the current platform.
|
|
25
|
+
*/
|
|
13
26
|
interface SandboxTerminalConnectionResponse {
|
|
14
27
|
runtimeUrl?: string;
|
|
15
28
|
sidecarUrl?: string;
|
|
@@ -18,11 +31,23 @@ interface SandboxTerminalConnectionResponse {
|
|
|
18
31
|
status?: string;
|
|
19
32
|
error?: string;
|
|
20
33
|
sandboxId?: string;
|
|
34
|
+
connectionId?: string;
|
|
21
35
|
}
|
|
22
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Define options for configuring a sandbox terminal connection including workspace ID and connection parameters
|
|
38
|
+
*
|
|
39
|
+
* `connectionId`, when set, is passed to
|
|
40
|
+
* `createSandboxTerminalConnectionRoute` as the `connectionId` query
|
|
41
|
+
* parameter — pass `tabTerminalConnectionId()` here so the route mints a
|
|
42
|
+
* token whose `sid` is bound to the same id `TerminalView` will dial. Give
|
|
43
|
+
* `TerminalView` the response's echoed `connectionId` (not this input
|
|
44
|
+
* value) alongside `sidecarUrl` as `apiUrl` and `token`, since a product's
|
|
45
|
+
* `resolveConnectionId` seam may rewrite it server-side.
|
|
46
|
+
*/
|
|
23
47
|
interface UseSandboxTerminalConnectionOptions {
|
|
24
48
|
workspaceId: string;
|
|
25
49
|
connectionUrl?: string | ((workspaceId: string) => string);
|
|
50
|
+
connectionId?: string;
|
|
26
51
|
fetcher?: typeof fetch;
|
|
27
52
|
provisionPollIntervalMs?: number;
|
|
28
53
|
provisionPollTimeoutMs?: number;
|
|
@@ -32,7 +57,23 @@ interface UseSandboxTerminalConnectionOptions {
|
|
|
32
57
|
interface UseSandboxTerminalConnectionResult extends SandboxTerminalConnection {
|
|
33
58
|
connect: () => Promise<void>;
|
|
34
59
|
}
|
|
35
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Manage and maintain a sandbox terminal connection with automatic polling and token refresh handling
|
|
62
|
+
*
|
|
63
|
+
* `connectionUrl` is backed by the browser-direct scoped-token route
|
|
64
|
+
* (`createSandboxTerminalConnectionRoute`,
|
|
65
|
+
* `src/sandbox/terminal-connection.ts`). The route returns `sidecarUrl`; the
|
|
66
|
+
* hook normalizes it into both URL fields for compatibility with existing
|
|
67
|
+
* terminal panels.
|
|
68
|
+
*
|
|
69
|
+
* Pass `tabTerminalConnectionId()` as `opts.connectionId` — the hook forwards
|
|
70
|
+
* it as the `connectionId` query parameter the browser-direct route requires
|
|
71
|
+
* to mint a token whose `sid` is bound to that exact id (the orchestrator's
|
|
72
|
+
* terminal WS gate fails closed on any other value). Give `TerminalView` the
|
|
73
|
+
* RESULT's echoed `connectionId` (not the input value — a product's
|
|
74
|
+
* `resolveConnectionId` seam may rewrite it), the resolved `sidecarUrl`/
|
|
75
|
+
* `runtimeUrl` as `apiUrl`, and `token` as its token prop.
|
|
76
|
+
*/
|
|
36
77
|
declare function useSandboxTerminalConnection(opts: UseSandboxTerminalConnectionOptions): UseSandboxTerminalConnectionResult;
|
|
37
78
|
/**
|
|
38
79
|
* Stable-per-tab, unique-per-client terminal connection id.
|