@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.
@@ -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 identity details for a terminal proxy including user, workspace, and sandbox identifiers */
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 and interacting with workspace sandboxes */
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
- /** Create a manager to handle workspace sandbox instances with client and options configuration */
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
- /** Define options for generating a sandbox terminal token including secret and expiration settings */
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
- * Build the sandbox API's sidecar-proxy base for a box:
375
- * `{baseUrl}/v1/sidecar-proxy/{sandboxId}`.
310
+ * Browser-direct scoped-token terminal connection route (#341/#349).
376
311
  *
377
- * This is the ONLY upstream that serves the interactive terminal. Measured on
378
- * production (`sandbox.tangle.tools`, one box, `ws` client, same credential in
379
- * every arm):
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
- * | upstream base | result |
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
- * The box's own `connection.runtimeUrl` (`https://sandbox-*.tangle.sh`) accepts
388
- * the upgrade — its Caddy front end upgrades every path, including ones that do
389
- * not exist and then hangs up without a PTY. A 101 from that host therefore
390
- * proves nothing; only a `ready` control frame does. Two products shipped a
391
- * terminal against it and rendered a permanent spinner.
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
- * Exported so no product writes the path literal a fourth time.
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
- declare function sandboxSidecarProxyUrl(baseUrl: string, sandboxId: string): string;
396
- /** Define a connection configuration for sandbox runtime including URL and optional server-side auth token */
397
- interface SandboxRuntimeConnection {
398
- runtimeUrl: string;
399
- /** Server-side sidecar bearer. Must authorize terminal routes; never expose it to browser code. */
400
- authToken?: string;
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
- /** Create a proxy handler to resolve sandbox runtime requests with user and workspace access validation */
437
- declare function createWorkspaceSandboxRuntimeProxyHandler(opts: WorkspaceSandboxRuntimeProxyHandlerOptions): ({ request, params }: WorkspaceSandboxRuntimeProxyArgs) => Promise<Response>;
438
- /** Define the structure for matching a sandbox terminal WebSocket with workspace and path details */
439
- interface SandboxTerminalWsMatch {
440
- workspaceId: string;
441
- sandboxId: string;
442
- subPath: string;
443
- }
444
- /**
445
- * Parse a same-origin terminal-WS pathname into its parts, or `null` when the
446
- * path is not a sandbox terminal WebSocket. Matches the default `runtimeUrl`
447
- * convention emitted by {@link createWorkspaceSandboxConnectionHandler}
448
- * (`/api/workspaces/:workspaceId/sandbox/runtime/:sandboxId`) with a canonical
449
- * `terminals/:id/ws` sub-path. `subPath` is left URL-encoded for re-use in the
450
- * upstream URL; the ids are decoded for auth checks.
451
- */
452
- declare function matchSandboxTerminalWsPath(pathname: string): SandboxTerminalWsMatch | null;
453
- /** True when `request` is a WebSocket upgrade for a sandbox terminal path. */
454
- declare function isSandboxTerminalWsUpgrade(request: Request): boolean;
455
- /** Define options to handle user authentication, workspace access, and sandbox API credential retrieval */
456
- interface WorkspaceSandboxTerminalUpgradeHandlerOptions {
457
- requireUser: (request: Request) => Promise<AuthenticatedSandboxUser>;
458
- requireWorkspaceAccess: (args: {
459
- request: Request;
460
- userId: string;
461
- workspaceId: string;
462
- sandboxId: string;
463
- }) => Promise<void>;
464
- getSandboxApiCredentials: (args: {
465
- request: Request;
466
- userId: string;
467
- workspaceId: string;
468
- sandboxId: string;
469
- }) => Promise<SandboxApiCredentials>;
470
- getSandboxRuntimeConnection?: (args: {
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
- userId: string;
473
- workspaceId: string;
474
- sandboxId: string;
475
- }) => Promise<SandboxRuntimeConnection | null | undefined>;
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
- * Decide whether a terminal upgrade's 101 needs the browser's own subprotocol
499
- * echoed back onto it, and return the headers to answer with. `null` means
500
- * "pass the upstream response through untouched".
501
- *
502
- * Why this exists: the browser's terminal credential rides in a
503
- * `bearer.<base64url>` WebSocket subprotocol, because a browser cannot set
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
- * Takes the raw `Sec-WebSocket-Protocol` value rather than the `Headers`, to
523
- * match its siblings `bearerSubprotocolToken` and `stripBearerSubprotocol`
524
- * one shape for the whole family, and the caller reads the header once.
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 selectedBearerSubprotocol(value: string | null): string | null;
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 AuthenticatedSandboxUser, 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 SandboxApiCredentials, 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 SandboxRuntimeConnection, type SandboxScope, type SandboxStepTransition, type SandboxTerminalTokenOptions, type SandboxTerminalTokenResult, type SandboxTerminalTokenSubject, type SandboxTerminalWsMatch, type SandboxToolPathOptions, type SandboxToolSpec, type ScopedTokenResult, type SecretStore, type StoppedSandboxResumeFailure, type StoppedSandboxResumeRecovery, type StreamSandboxPromptOptions, type TerminalProxyIdentity, type TerminalUpgradeResponseLike, type WorkspaceSandboxConnectionArgs, type WorkspaceSandboxConnectionHandlerOptions, type WorkspaceSandboxEnsureContext, type WorkspaceSandboxInstanceLike, type WorkspaceSandboxManager, type WorkspaceSandboxManagerOptions, type WorkspaceSandboxRuntimeProxyArgs, type WorkspaceSandboxRuntimeProxyHandlerOptions, type WorkspaceSandboxTerminalUpgradeHandlerOptions, type WriteProfileFilesOptions, assertEnvWithinLimits, assertProvisionPayloadWithinCap, attachReasoningEffort, bearerSubprotocolToken, bearerToken, buildAppToolMcpServers, buildSandboxRuntimeProxyHeaders, buildSandboxToolFileMounts, buildSandboxToolPathSetupScript, classifySeveredStream, collectSandboxPromptText, createD1PrewarmClaimStore, createSandboxPrewarmer, createSandboxTerminalToken, createWorkspaceSandboxConnectionHandler, createWorkspaceSandboxManager, createWorkspaceSandboxRuntimeProxyHandler, createWorkspaceSandboxTerminalUpgradeHandler, deferredCorpusHash, deleteSecret, detectInteractiveQuestion, driveSandboxTurn, encodeSandboxRuntimePath, ensureWorkspaceSandbox, flattenHistory, getClient, isSandboxTerminalWsUpgrade, isTerminalPromptEvent, matchSandboxTerminalWsPath, mergeExtraMcp, mergeHistoryIntoParts, mintSandboxScopedToken, mintTerminalProxyToken, peekWorkspaceSandbox, readSandboxBinaryBytes, readSecret, requireTransportableModel, resetClientCache, resolveModel, resolveModelSelection, resolveSandboxClientCredentials, runSandboxPrompt, runSandboxToolPathSetup, sandboxSidecarProxyUrl, sandboxToolBinDir, sandboxToolPath, sandboxToolRootDir, secretStoreFromClient, selectedBearerSubprotocol, shellQuote, splitDeferredProfileFiles, statSandboxFileSize, storeSecret, streamSandboxPrompt, syncSandboxMemberAdd, syncSandboxMemberRemove, syncSandboxMemberRole, terminalTokenFromRequest, terminalUpgradeSubprotocolEcho, verifySandboxTerminalToken, verifyTerminalProxyToken, writeProfileFilesToBox };
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 };
@@ -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
- createSandboxTerminalToken,
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-2UDJH6QR.js";
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
- createSandboxTerminalToken,
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
@@ -102,7 +102,7 @@ import {
102
102
  import {
103
103
  tabTerminalConnectionId,
104
104
  useSandboxTerminalConnection
105
- } from "../chunk-HCOROIRT.js";
105
+ } from "../chunk-BATKJP3P.js";
106
106
  import "../chunk-QY4BRKRJ.js";
107
107
  import {
108
108
  ATTACHMENT_ACCEPT
@@ -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
- /** Define the response structure for a sandbox terminal connection including URLs, token, status, and errors */
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
- /** Define options for configuring a sandbox terminal connection including workspace ID and connection parameters */
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
- /** Manage and maintain a sandbox terminal connection with automatic polling and token refresh handling */
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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  tabTerminalConnectionId,
3
3
  useSandboxTerminalConnection
4
- } from "../chunk-HCOROIRT.js";
4
+ } from "../chunk-BATKJP3P.js";
5
5
  export {
6
6
  tabTerminalConnectionId,
7
7
  useSandboxTerminalConnection