@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/assistant/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import "../chunk-GINKOZFD.js";
|
|
|
9
9
|
import "../chunk-YTMKRL3L.js";
|
|
10
10
|
import "../chunk-GEYACSFW.js";
|
|
11
11
|
import "../chunk-6MUJROBT.js";
|
|
12
|
-
import "../chunk-
|
|
12
|
+
import "../chunk-BATKJP3P.js";
|
|
13
13
|
import "../chunk-QY4BRKRJ.js";
|
|
14
14
|
import "../chunk-WBHPN5DY.js";
|
|
15
15
|
import "../chunk-UXMIPX3Z.js";
|
|
@@ -100,7 +100,7 @@ import {
|
|
|
100
100
|
flattenHistory,
|
|
101
101
|
readSandboxBinaryBytes,
|
|
102
102
|
statSandboxFileSize
|
|
103
|
-
} from "../chunk-
|
|
103
|
+
} from "../chunk-EC7CUA4L.js";
|
|
104
104
|
import "../chunk-LWSJK546.js";
|
|
105
105
|
import "../chunk-CQZSAR77.js";
|
|
106
106
|
import "../chunk-ICOHEZK6.js";
|
|
@@ -21,9 +21,11 @@ function useSandboxTerminalConnection(opts) {
|
|
|
21
21
|
const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS;
|
|
22
22
|
const refreshSkewMs = opts.tokenRefreshSkewMs ?? DEFAULT_TOKEN_REFRESH_SKEW_MS;
|
|
23
23
|
const connectionUrl = useCallback(() => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const base = typeof opts.connectionUrl === "function" ? opts.connectionUrl(opts.workspaceId) : opts.connectionUrl ?? `/api/workspaces/${encodeURIComponent(opts.workspaceId)}/sandbox/connection`;
|
|
25
|
+
if (!opts.connectionId) return base;
|
|
26
|
+
const separator = base.includes("?") ? "&" : "?";
|
|
27
|
+
return `${base}${separator}connectionId=${encodeURIComponent(opts.connectionId)}`;
|
|
28
|
+
}, [opts.connectionUrl, opts.workspaceId, opts.connectionId]);
|
|
27
29
|
const connect = useCallback(async () => {
|
|
28
30
|
const generation = generationRef.current + 1;
|
|
29
31
|
generationRef.current = generation;
|
|
@@ -49,7 +51,8 @@ function useSandboxTerminalConnection(opts) {
|
|
|
49
51
|
status: data.status ?? "running",
|
|
50
52
|
error: null,
|
|
51
53
|
loading: false,
|
|
52
|
-
...data.sandboxId ? { sandboxId: data.sandboxId } : {}
|
|
54
|
+
...data.sandboxId ? { sandboxId: data.sandboxId } : {},
|
|
55
|
+
...data.connectionId ? { connectionId: data.connectionId } : {}
|
|
53
56
|
});
|
|
54
57
|
return;
|
|
55
58
|
}
|
|
@@ -163,4 +166,4 @@ export {
|
|
|
163
166
|
useSandboxTerminalConnection,
|
|
164
167
|
tabTerminalConnectionId
|
|
165
168
|
};
|
|
166
|
-
//# sourceMappingURL=chunk-
|
|
169
|
+
//# sourceMappingURL=chunk-BATKJP3P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/web-react/sandbox-terminal.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react'\n\n/** Define the connection details and status for a sandbox terminal session */\nexport interface SandboxTerminalConnection {\n runtimeUrl: string | null\n sidecarUrl: string | null\n token: string | null\n expiresAt: string | null\n status: string\n error: string | null\n loading: boolean\n sandboxId?: string\n connectionId?: string\n}\n\n/**\n * Define the response structure for a sandbox terminal connection including URLs, token, status, and errors\n *\n * The browser-direct scoped-token route (`createSandboxTerminalConnectionRoute`,\n * `src/sandbox/terminal-connection.ts`) returns `sidecarUrl`. The hook also\n * exposes that URL through the historical `runtimeUrl` state field so existing\n * terminal panels do not need transport-specific branching.\n *\n * `connectionId` is the id the route's minted token's `sid` is bound to\n * (echoed back from the `connectionId` the hook sent) — pass it straight\n * through as `TerminalView`'s `connectionId` prop, since any other value\n * fails the WS upgrade on the current platform.\n */\nexport interface SandboxTerminalConnectionResponse {\n runtimeUrl?: string\n sidecarUrl?: string\n token?: string\n expiresAt?: string\n status?: string\n error?: string\n sandboxId?: string\n connectionId?: string\n}\n\n/**\n * Define options for configuring a sandbox terminal connection including workspace ID and connection parameters\n *\n * `connectionId`, when set, is passed to\n * `createSandboxTerminalConnectionRoute` as the `connectionId` query\n * parameter — pass `tabTerminalConnectionId()` here so the route mints a\n * token whose `sid` is bound to the same id `TerminalView` will dial. Give\n * `TerminalView` the response's echoed `connectionId` (not this input\n * value) alongside `sidecarUrl` as `apiUrl` and `token`, since a product's\n * `resolveConnectionId` seam may rewrite it server-side.\n */\nexport interface UseSandboxTerminalConnectionOptions {\n workspaceId: string\n connectionUrl?: string | ((workspaceId: string) => string)\n connectionId?: string\n fetcher?: typeof fetch\n provisionPollIntervalMs?: number\n provisionPollTimeoutMs?: number\n tokenRefreshSkewMs?: number\n}\n\n/** Resolve sandbox terminal connection status and provide a method to initiate the connection */\nexport interface UseSandboxTerminalConnectionResult extends SandboxTerminalConnection {\n connect: () => Promise<void>\n}\n\nconst DEFAULT_PROVISION_POLL_INTERVAL_MS = 2_000\nconst DEFAULT_PROVISION_POLL_TIMEOUT_MS = 90_000\nconst DEFAULT_TOKEN_REFRESH_SKEW_MS = 120_000\n\nconst EMPTY_CONNECTION: SandboxTerminalConnection = {\n runtimeUrl: null,\n sidecarUrl: null,\n token: null,\n expiresAt: null,\n status: 'idle',\n error: null,\n loading: false,\n}\n\n/**\n * Manage and maintain a sandbox terminal connection with automatic polling and token refresh handling\n *\n * `connectionUrl` is backed by the browser-direct scoped-token route\n * (`createSandboxTerminalConnectionRoute`,\n * `src/sandbox/terminal-connection.ts`). The route returns `sidecarUrl`; the\n * hook normalizes it into both URL fields for compatibility with existing\n * terminal panels.\n *\n * Pass `tabTerminalConnectionId()` as `opts.connectionId` — the hook forwards\n * it as the `connectionId` query parameter the browser-direct route requires\n * to mint a token whose `sid` is bound to that exact id (the orchestrator's\n * terminal WS gate fails closed on any other value). Give `TerminalView` the\n * RESULT's echoed `connectionId` (not the input value — a product's\n * `resolveConnectionId` seam may rewrite it), the resolved `sidecarUrl`/\n * `runtimeUrl` as `apiUrl`, and `token` as its token prop.\n */\nexport function useSandboxTerminalConnection(opts: UseSandboxTerminalConnectionOptions): UseSandboxTerminalConnectionResult {\n const [conn, setConn] = useState<SandboxTerminalConnection>(EMPTY_CONNECTION)\n const mountedRef = useRef(false)\n const generationRef = useRef(0)\n const fetcher = opts.fetcher ?? fetch\n const pollIntervalMs = opts.provisionPollIntervalMs ?? DEFAULT_PROVISION_POLL_INTERVAL_MS\n const pollTimeoutMs = opts.provisionPollTimeoutMs ?? DEFAULT_PROVISION_POLL_TIMEOUT_MS\n const refreshSkewMs = opts.tokenRefreshSkewMs ?? DEFAULT_TOKEN_REFRESH_SKEW_MS\n\n const connectionUrl = useCallback(() => {\n const base = typeof opts.connectionUrl === 'function'\n ? opts.connectionUrl(opts.workspaceId)\n : opts.connectionUrl ?? `/api/workspaces/${encodeURIComponent(opts.workspaceId)}/sandbox/connection`\n if (!opts.connectionId) return base\n // `base` may be relative (SSR-safe), so a plain `URL` parse isn't always\n // possible — string-append with proper encoding covers both shapes.\n const separator = base.includes('?') ? '&' : '?'\n return `${base}${separator}connectionId=${encodeURIComponent(opts.connectionId)}`\n }, [opts.connectionUrl, opts.workspaceId, opts.connectionId])\n\n const connect = useCallback(async () => {\n const generation = generationRef.current + 1\n generationRef.current = generation\n const isCurrent = () => mountedRef.current && generationRef.current === generation\n const setCurrentConn: typeof setConn = (value) => {\n if (!isCurrent()) return\n setConn(value)\n }\n\n setCurrentConn((current) => ({ ...current, loading: true, error: null }))\n const deadline = Date.now() + pollTimeoutMs\n while (isCurrent()) {\n try {\n const res = await fetcher(connectionUrl())\n const data = (await res.json()) as SandboxTerminalConnectionResponse\n if (!isCurrent()) return\n const runtimeUrl = data.runtimeUrl ?? data.sidecarUrl\n if (res.ok && runtimeUrl && data.token && data.expiresAt) {\n setCurrentConn({\n runtimeUrl,\n sidecarUrl: data.sidecarUrl ?? runtimeUrl,\n token: data.token,\n expiresAt: data.expiresAt,\n status: data.status ?? 'running',\n error: null,\n loading: false,\n ...(data.sandboxId ? { sandboxId: data.sandboxId } : {}),\n ...(data.connectionId ? { connectionId: data.connectionId } : {}),\n })\n return\n }\n if (res.ok) {\n setCurrentConn({\n runtimeUrl: null,\n sidecarUrl: null,\n token: null,\n expiresAt: null,\n loading: false,\n error: 'Sandbox connection response is missing required fields',\n status: data.status ?? 'error',\n ...(data.sandboxId ? { sandboxId: data.sandboxId } : {}),\n })\n return\n }\n if (res.status === 503 && Date.now() < deadline) {\n setCurrentConn((current) => ({\n ...current,\n loading: true,\n status: data.status ?? 'provisioning',\n error: null,\n }))\n await sleep(pollIntervalMs)\n continue\n }\n setCurrentConn((current) => ({\n ...current,\n runtimeUrl: null,\n sidecarUrl: null,\n token: null,\n expiresAt: null,\n loading: false,\n error: data.error ?? 'Sandbox not available',\n status: data.status ?? 'error',\n }))\n return\n } catch (err) {\n if (!isCurrent()) return\n if (Date.now() < deadline) {\n await sleep(pollIntervalMs)\n continue\n }\n setCurrentConn((current) => ({\n ...current,\n runtimeUrl: null,\n sidecarUrl: null,\n token: null,\n expiresAt: null,\n loading: false,\n error: err instanceof Error ? err.message : 'Connection failed',\n }))\n return\n }\n }\n }, [connectionUrl, fetcher, pollIntervalMs, pollTimeoutMs])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n generationRef.current += 1\n }\n }, [])\n\n useEffect(() => {\n void connect()\n }, [connect])\n\n useEffect(() => {\n if (!conn.runtimeUrl || !conn.token || !conn.expiresAt) return\n const refreshAt = Date.parse(conn.expiresAt) - Date.now() - refreshSkewMs\n if (!Number.isFinite(refreshAt)) {\n setConn((current) => ({\n ...current,\n runtimeUrl: null,\n sidecarUrl: null,\n token: null,\n expiresAt: null,\n status: 'error',\n error: 'Sandbox token expiry is invalid',\n }))\n return\n }\n const timer = window.setTimeout(() => {\n void connect()\n }, Math.max(1_000, refreshAt))\n return () => window.clearTimeout(timer)\n }, [conn.runtimeUrl, conn.token, conn.expiresAt, connect, refreshSkewMs])\n\n return { ...conn, connect }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => window.setTimeout(resolve, ms))\n}\n\nconst DEFAULT_TERMINAL_CID_KEY = 'agent-app:terminal-connection-id'\n\nfunction newConnectionId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') return crypto.randomUUID()\n return `cid-${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`\n}\n\n/**\n * Stable-per-tab, unique-per-client terminal connection id.\n *\n * Persists in `sessionStorage` so a reload in the same tab reuses the id (the\n * sidecar restores the same PTY session via `TerminalView.connectionId`), while\n * separate tabs/windows each get a distinct id. Pass the result as\n * `TerminalView`'s `connectionId`. Without it (e.g. gtm-agent today) every tab\n * shares one connection id and their reconnects evict each other.\n *\n * Falls back to an ephemeral id when `sessionStorage` is unavailable (SSR,\n * privacy mode) — still unique per call, just not reload-stable.\n */\nexport function tabTerminalConnectionId(storageKey: string = DEFAULT_TERMINAL_CID_KEY): string {\n try {\n const store = globalThis.sessionStorage\n const existing = store?.getItem(storageKey)\n if (existing) return existing\n const id = newConnectionId()\n store?.setItem(storageKey, id)\n return id\n } catch {\n return newConnectionId()\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -8,12 +8,6 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
buildAppToolMcpServer
|
|
10
10
|
} from "./chunk-3EJ6SFJI.js";
|
|
11
|
-
import {
|
|
12
|
-
base64UrlDecodeText,
|
|
13
|
-
base64UrlEncodeText,
|
|
14
|
-
constantTimeEqual,
|
|
15
|
-
hmacSha256Base64Url
|
|
16
|
-
} from "./chunk-S5SRJJQG.js";
|
|
17
11
|
import {
|
|
18
12
|
resolveTangleExecutionEnvironment,
|
|
19
13
|
trimOrNull
|
|
@@ -161,35 +155,7 @@ async function readSandboxBinaryBytes(box, absolutePath, expectedSize, options)
|
|
|
161
155
|
return { succeeded: true, value: { bytes, size: expectedSize } };
|
|
162
156
|
}
|
|
163
157
|
|
|
164
|
-
// src/sandbox/
|
|
165
|
-
var TERMINAL_PROXY_TOKEN_TTL_MS = 15 * 60 * 1e3;
|
|
166
|
-
async function mintTerminalProxyToken(secret, identity, ttlMs = TERMINAL_PROXY_TOKEN_TTL_MS, now = Date.now) {
|
|
167
|
-
if (!secret) return fail(new Error("mintTerminalProxyToken: secret is required"));
|
|
168
|
-
if (!identity.userId || !identity.workspaceId || !identity.sandboxId) {
|
|
169
|
-
return fail(new Error("mintTerminalProxyToken: userId/workspaceId/sandboxId are required"));
|
|
170
|
-
}
|
|
171
|
-
const expiresAt = new Date(now() + ttlMs);
|
|
172
|
-
const payload = { ...identity, exp: Math.floor(expiresAt.getTime() / 1e3) };
|
|
173
|
-
const encoded = base64UrlEncodeText(JSON.stringify(payload));
|
|
174
|
-
const sig = await hmacSha256Base64Url(encoded, secret);
|
|
175
|
-
return ok({ token: `${encoded}.${sig}`, expiresAt });
|
|
176
|
-
}
|
|
177
|
-
async function verifyTerminalProxyToken(secret, token, expected, now = Date.now) {
|
|
178
|
-
if (!secret) return false;
|
|
179
|
-
const [encoded, sig, extra] = token.split(".");
|
|
180
|
-
if (!encoded || !sig || extra !== void 0) return false;
|
|
181
|
-
const expectedSig = await hmacSha256Base64Url(encoded, secret);
|
|
182
|
-
if (!constantTimeEqual(sig, expectedSig)) return false;
|
|
183
|
-
let payload;
|
|
184
|
-
try {
|
|
185
|
-
payload = JSON.parse(base64UrlDecodeText(encoded));
|
|
186
|
-
} catch {
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
return payload.userId === expected.userId && payload.workspaceId === expected.workspaceId && payload.sandboxId === expected.sandboxId && Number.isFinite(payload.exp) && payload.exp > Math.floor(now() / 1e3);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/sandbox/workspace-terminal.ts
|
|
158
|
+
// src/sandbox/workspace-sandbox-manager.ts
|
|
193
159
|
function createWorkspaceSandboxManager(opts) {
|
|
194
160
|
return {
|
|
195
161
|
async ensureWorkspaceSandbox(workspaceId, userId, options) {
|
|
@@ -222,293 +188,70 @@ function createWorkspaceSandboxManager(opts) {
|
|
|
222
188
|
}
|
|
223
189
|
};
|
|
224
190
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
var
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
const minted = await mintTerminalProxyToken(secret, subject, expiresInMs, now);
|
|
236
|
-
if (!minted.succeeded) throw minted.error;
|
|
237
|
-
return minted.value;
|
|
238
|
-
}
|
|
239
|
-
async function verifySandboxTerminalToken(token, expected, opts) {
|
|
240
|
-
validateTerminalSubject(expected);
|
|
241
|
-
const secret = opts.secret?.trim();
|
|
242
|
-
const now = opts.now ?? Date.now;
|
|
243
|
-
const normalized = token.startsWith(LEGACY_TERMINAL_TOKEN_PREFIX) ? token.slice(LEGACY_TERMINAL_TOKEN_PREFIX.length) : token;
|
|
244
|
-
return verifyTerminalProxyToken(secret ?? "", normalized, expected, now);
|
|
245
|
-
}
|
|
246
|
-
function createWorkspaceSandboxConnectionHandler(opts) {
|
|
247
|
-
return async function handleWorkspaceSandboxConnection({ request, params }) {
|
|
191
|
+
|
|
192
|
+
// src/sandbox/terminal-connection.ts
|
|
193
|
+
var DEFAULT_TTL_MINUTES = 15;
|
|
194
|
+
var TERMINAL_SCOPE = "session-runtime";
|
|
195
|
+
function defaultResolveConnectionId(ctx) {
|
|
196
|
+
return ctx.requested;
|
|
197
|
+
}
|
|
198
|
+
function createSandboxTerminalConnectionRoute(opts) {
|
|
199
|
+
const resolveConnectionId = opts.resolveConnectionId ?? defaultResolveConnectionId;
|
|
200
|
+
return async function handleSandboxTerminalConnection(request) {
|
|
248
201
|
const user = await opts.requireUser(request);
|
|
249
|
-
|
|
250
|
-
if (!workspaceId) return Response.json({ error: "workspaceId is required" }, { status: 400 });
|
|
251
|
-
await opts.requireWorkspaceAccess({ request, userId: user.id, workspaceId });
|
|
202
|
+
if (user instanceof Response) return user;
|
|
252
203
|
let box;
|
|
253
204
|
try {
|
|
254
|
-
box = await opts.
|
|
205
|
+
box = await opts.ensureSandbox(user, request);
|
|
255
206
|
} catch (err) {
|
|
256
207
|
return Response.json(
|
|
257
|
-
{ error: err instanceof Error ? err.message : "Failed to provision
|
|
208
|
+
{ error: err instanceof Error ? err.message : "Failed to provision sandbox" },
|
|
258
209
|
{ status: 500 }
|
|
259
210
|
);
|
|
260
211
|
}
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
const directSidecarExpiresAt = box.connection?.authTokenExpiresAt;
|
|
264
|
-
if (opts.exposeDirectSidecar && directSidecarUrl && directSidecarToken && directSidecarExpiresAt) {
|
|
265
|
-
return Response.json({
|
|
266
|
-
runtimeUrl: directSidecarUrl,
|
|
267
|
-
sidecarUrl: directSidecarUrl,
|
|
268
|
-
token: directSidecarToken,
|
|
269
|
-
expiresAt: directSidecarExpiresAt,
|
|
270
|
-
status: box.status,
|
|
271
|
-
sandboxId: box.id
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (!directSidecarUrl) {
|
|
212
|
+
const runtimeUrl = box.connection?.runtimeUrl;
|
|
213
|
+
if (!runtimeUrl) {
|
|
275
214
|
return Response.json(
|
|
276
215
|
{
|
|
277
|
-
error: "
|
|
216
|
+
error: "Sandbox runtime not ready. The sandbox is still initializing -- retry in a few seconds.",
|
|
278
217
|
status: box.status
|
|
279
218
|
},
|
|
280
219
|
{ status: 503 }
|
|
281
220
|
);
|
|
282
221
|
}
|
|
283
|
-
const
|
|
222
|
+
const requested = new URL(request.url).searchParams.get("connectionId");
|
|
223
|
+
const connectionId = await resolveConnectionId({ request, user, box, requested });
|
|
224
|
+
if (!connectionId) {
|
|
225
|
+
return Response.json(
|
|
226
|
+
{
|
|
227
|
+
error: "connectionId is required \u2014 pass the same id TerminalView dials (tabTerminalConnectionId()) as the 'connectionId' query parameter"
|
|
228
|
+
},
|
|
229
|
+
{ status: 400 }
|
|
230
|
+
);
|
|
231
|
+
}
|
|
284
232
|
let scoped;
|
|
285
233
|
try {
|
|
286
|
-
scoped = await
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
234
|
+
scoped = await box.mintScopedToken({
|
|
235
|
+
scope: TERMINAL_SCOPE,
|
|
236
|
+
ttlMinutes: opts.ttlMinutes ?? DEFAULT_TTL_MINUTES,
|
|
237
|
+
sessionId: connectionId
|
|
238
|
+
});
|
|
290
239
|
} catch (err) {
|
|
291
240
|
return Response.json(
|
|
292
241
|
{ error: err instanceof Error ? err.message : "Failed to mint sandbox token" },
|
|
293
242
|
{ status: 503 }
|
|
294
243
|
);
|
|
295
244
|
}
|
|
296
|
-
const runtimeUrl = opts.proxyRuntimeUrl ? opts.proxyRuntimeUrl({ request, workspaceId, sandboxId: box.id, box }) : `/api/workspaces/${encodeURIComponent(workspaceId)}/sandbox/runtime/${encodeURIComponent(box.id)}`;
|
|
297
245
|
return Response.json({
|
|
298
|
-
|
|
299
|
-
sidecarUrl: runtimeUrl,
|
|
246
|
+
sidecarUrl: scoped.sidecarProxyUrl,
|
|
300
247
|
token: scoped.token,
|
|
301
248
|
expiresAt: scoped.expiresAt.toISOString(),
|
|
302
249
|
status: box.status,
|
|
303
|
-
sandboxId: box.id
|
|
250
|
+
sandboxId: box.id,
|
|
251
|
+
connectionId
|
|
304
252
|
});
|
|
305
253
|
};
|
|
306
254
|
}
|
|
307
|
-
function sandboxSidecarProxyUrl(baseUrl, sandboxId) {
|
|
308
|
-
if (!baseUrl) throw new Error("baseUrl is required");
|
|
309
|
-
if (!sandboxId) throw new Error("sandboxId is required");
|
|
310
|
-
return new URL(`/v1/sidecar-proxy/${encodeURIComponent(sandboxId)}`, baseUrl).toString().replace(/\/+$/, "");
|
|
311
|
-
}
|
|
312
|
-
function createWorkspaceSandboxRuntimeProxyHandler(opts) {
|
|
313
|
-
return async function handleWorkspaceSandboxRuntimeProxy({ request, params }) {
|
|
314
|
-
const user = await opts.requireUser(request);
|
|
315
|
-
const workspaceId = params.workspaceId;
|
|
316
|
-
const sandboxId = params.sandboxId;
|
|
317
|
-
const runtimePath = params["*"];
|
|
318
|
-
if (!workspaceId || !sandboxId || !runtimePath) {
|
|
319
|
-
return Response.json({ error: "workspaceId, sandboxId, and runtime path are required" }, { status: 400 });
|
|
320
|
-
}
|
|
321
|
-
const encodedRuntimePath = encodeSandboxRuntimePath(runtimePath);
|
|
322
|
-
if (!encodedRuntimePath) return Response.json({ error: "Invalid sandbox runtime path" }, { status: 400 });
|
|
323
|
-
await opts.requireWorkspaceAccess({ request, userId: user.id, workspaceId, sandboxId });
|
|
324
|
-
const token = terminalTokenFromRequest(request.headers);
|
|
325
|
-
const secret = typeof opts.tokenSecret === "function" ? opts.tokenSecret() : opts.tokenSecret;
|
|
326
|
-
if (!token || !await verifySandboxTerminalToken(token, { userId: user.id, workspaceId, sandboxId }, { secret })) {
|
|
327
|
-
return Response.json({ error: "Invalid terminal token" }, { status: 403 });
|
|
328
|
-
}
|
|
329
|
-
const requestUrl = new URL(request.url);
|
|
330
|
-
const runtimeConnection = await opts.getSandboxRuntimeConnection?.({ request, userId: user.id, workspaceId, sandboxId });
|
|
331
|
-
const directRuntimeConnection = runtimeConnection?.runtimeUrl && runtimeConnection.authToken ? runtimeConnection : null;
|
|
332
|
-
const credentials = directRuntimeConnection ? null : await opts.getSandboxApiCredentials({ request, userId: user.id, workspaceId, sandboxId });
|
|
333
|
-
const upstreamUrl = directRuntimeConnection ? new URL(encodedRuntimePath, `${directRuntimeConnection.runtimeUrl.replace(/\/+$/, "")}/`) : new URL(encodedRuntimePath, `${sandboxSidecarProxyUrl(credentials.baseUrl, sandboxId)}/`);
|
|
334
|
-
upstreamUrl.search = requestUrl.search;
|
|
335
|
-
const headers = buildSandboxRuntimeProxyHeaders(
|
|
336
|
-
request.headers,
|
|
337
|
-
directRuntimeConnection?.authToken ?? credentials.apiKey,
|
|
338
|
-
opts.forwardHeaders
|
|
339
|
-
);
|
|
340
|
-
const init = {
|
|
341
|
-
method: request.method,
|
|
342
|
-
headers,
|
|
343
|
-
redirect: "manual"
|
|
344
|
-
};
|
|
345
|
-
if (request.method !== "GET" && request.method !== "HEAD" && request.body) {
|
|
346
|
-
init.body = request.body;
|
|
347
|
-
init.duplex = "half";
|
|
348
|
-
}
|
|
349
|
-
const fetchImpl = opts.fetch ?? fetch;
|
|
350
|
-
const response = await fetchImpl(upstreamUrl, init);
|
|
351
|
-
const responseHeaders = new Headers(response.headers);
|
|
352
|
-
responseHeaders.delete("set-cookie");
|
|
353
|
-
return new Response(response.body, {
|
|
354
|
-
status: response.status,
|
|
355
|
-
statusText: response.statusText,
|
|
356
|
-
headers: responseHeaders
|
|
357
|
-
});
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
var SANDBOX_TERMINAL_WS_PATHNAME = /^\/api\/workspaces\/([^/]+)\/sandbox\/runtime\/([^/]+)\/(terminals\/[^/]+\/ws)$/;
|
|
361
|
-
function matchSandboxTerminalWsPath(pathname) {
|
|
362
|
-
const m = SANDBOX_TERMINAL_WS_PATHNAME.exec(pathname);
|
|
363
|
-
if (!m) return null;
|
|
364
|
-
const [, workspaceId, sandboxId, subPath] = m;
|
|
365
|
-
if (!workspaceId || !sandboxId || !subPath) return null;
|
|
366
|
-
const decodedWorkspaceId = safeDecodeURIComponent(workspaceId);
|
|
367
|
-
const decodedSandboxId = safeDecodeURIComponent(sandboxId);
|
|
368
|
-
if (!decodedWorkspaceId || !decodedSandboxId) return null;
|
|
369
|
-
return { workspaceId: decodedWorkspaceId, sandboxId: decodedSandboxId, subPath };
|
|
370
|
-
}
|
|
371
|
-
function isSandboxTerminalWsUpgrade(request) {
|
|
372
|
-
if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") return false;
|
|
373
|
-
try {
|
|
374
|
-
return matchSandboxTerminalWsPath(new URL(request.url).pathname) !== null;
|
|
375
|
-
} catch {
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
function createWorkspaceSandboxTerminalUpgradeHandler(opts) {
|
|
380
|
-
return async function handleWorkspaceSandboxTerminalUpgrade(request) {
|
|
381
|
-
if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") return null;
|
|
382
|
-
let url;
|
|
383
|
-
try {
|
|
384
|
-
url = new URL(request.url);
|
|
385
|
-
} catch {
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
const match = matchSandboxTerminalWsPath(url.pathname);
|
|
389
|
-
if (!match) return null;
|
|
390
|
-
const { workspaceId, sandboxId, subPath } = match;
|
|
391
|
-
let user;
|
|
392
|
-
try {
|
|
393
|
-
user = await opts.requireUser(request);
|
|
394
|
-
} catch {
|
|
395
|
-
return new Response("Unauthorized", { status: 401 });
|
|
396
|
-
}
|
|
397
|
-
try {
|
|
398
|
-
await opts.requireWorkspaceAccess({ request, userId: user.id, workspaceId, sandboxId });
|
|
399
|
-
} catch {
|
|
400
|
-
return new Response("Forbidden", { status: 403 });
|
|
401
|
-
}
|
|
402
|
-
const token = terminalTokenFromRequest(request.headers);
|
|
403
|
-
const secret = typeof opts.tokenSecret === "function" ? opts.tokenSecret() : opts.tokenSecret;
|
|
404
|
-
if (!token || !await verifySandboxTerminalToken(token, { userId: user.id, workspaceId, sandboxId }, { secret })) {
|
|
405
|
-
return new Response("Invalid terminal token", { status: 403 });
|
|
406
|
-
}
|
|
407
|
-
const runtimeConnection = await opts.getSandboxRuntimeConnection?.({ request, userId: user.id, workspaceId, sandboxId });
|
|
408
|
-
const directRuntimeConnection = runtimeConnection?.runtimeUrl && runtimeConnection.authToken ? runtimeConnection : null;
|
|
409
|
-
const credentials = directRuntimeConnection ? null : await opts.getSandboxApiCredentials({ request, userId: user.id, workspaceId, sandboxId });
|
|
410
|
-
const upstreamUrl = directRuntimeConnection ? new URL(subPath, `${directRuntimeConnection.runtimeUrl.replace(/\/+$/, "")}/`) : new URL(subPath, `${sandboxSidecarProxyUrl(credentials.baseUrl, sandboxId)}/`);
|
|
411
|
-
upstreamUrl.search = url.search;
|
|
412
|
-
const upstreamHeaders = new Headers(request.headers);
|
|
413
|
-
const upstreamBearer = directRuntimeConnection?.authToken ?? credentials.apiKey;
|
|
414
|
-
upstreamHeaders.set("Authorization", `Bearer ${upstreamBearer}`);
|
|
415
|
-
upstreamHeaders.delete("host");
|
|
416
|
-
const browserProtocol = selectedBearerSubprotocol(request.headers.get("Sec-WebSocket-Protocol"));
|
|
417
|
-
stripBearerSubprotocol(upstreamHeaders);
|
|
418
|
-
const fetchImpl = opts.fetch ?? fetch;
|
|
419
|
-
const upstream = await fetchImpl(upstreamUrl.toString(), { method: request.method, headers: upstreamHeaders });
|
|
420
|
-
const echo = terminalUpgradeSubprotocolEcho(upstream, browserProtocol);
|
|
421
|
-
if (!echo) return upstream;
|
|
422
|
-
return new Response(null, {
|
|
423
|
-
status: echo.status,
|
|
424
|
-
statusText: echo.statusText,
|
|
425
|
-
headers: echo.headers,
|
|
426
|
-
webSocket: upstream.webSocket ?? null
|
|
427
|
-
});
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
function terminalUpgradeSubprotocolEcho(upstream, browserProtocol) {
|
|
431
|
-
if (upstream.status !== 101 || !browserProtocol) return null;
|
|
432
|
-
if (upstream.headers.has("Sec-WebSocket-Protocol")) return null;
|
|
433
|
-
const headers = new Headers(upstream.headers);
|
|
434
|
-
headers.set("Sec-WebSocket-Protocol", browserProtocol);
|
|
435
|
-
return { status: upstream.status, statusText: upstream.statusText ?? "", headers };
|
|
436
|
-
}
|
|
437
|
-
function selectedBearerSubprotocol(value) {
|
|
438
|
-
if (!value) return null;
|
|
439
|
-
for (const part of value.split(",")) {
|
|
440
|
-
const protocol = part.trim();
|
|
441
|
-
if (protocol.toLowerCase().startsWith(BEARER_SUBPROTOCOL_PREFIX)) return protocol;
|
|
442
|
-
}
|
|
443
|
-
return null;
|
|
444
|
-
}
|
|
445
|
-
var DEFAULT_RUNTIME_PROXY_HEADERS = ["accept", "content-type", "last-event-id", "x-session-id"];
|
|
446
|
-
function buildSandboxRuntimeProxyHeaders(source, sandboxApiKey, forwardHeaders = DEFAULT_RUNTIME_PROXY_HEADERS) {
|
|
447
|
-
const headers = new Headers();
|
|
448
|
-
headers.set("Authorization", `Bearer ${sandboxApiKey}`);
|
|
449
|
-
for (const name of forwardHeaders) {
|
|
450
|
-
const value = source.get(name);
|
|
451
|
-
if (value) headers.set(name, value);
|
|
452
|
-
}
|
|
453
|
-
return headers;
|
|
454
|
-
}
|
|
455
|
-
function encodeSandboxRuntimePath(runtimePath) {
|
|
456
|
-
const segments = runtimePath.split("/");
|
|
457
|
-
if (segments.some((segment) => !segment || segment === "." || segment === "..")) return null;
|
|
458
|
-
return segments.map((segment) => encodeURIComponent(segment)).join("/");
|
|
459
|
-
}
|
|
460
|
-
function bearerToken(value) {
|
|
461
|
-
if (!value) return null;
|
|
462
|
-
const trimmed = value.trim();
|
|
463
|
-
if (!trimmed) return null;
|
|
464
|
-
if (trimmed.toLowerCase() === "bearer") return null;
|
|
465
|
-
if (trimmed.toLowerCase().startsWith("bearer ")) {
|
|
466
|
-
const token = trimmed.slice("bearer ".length).trim();
|
|
467
|
-
return token || null;
|
|
468
|
-
}
|
|
469
|
-
return trimmed;
|
|
470
|
-
}
|
|
471
|
-
function bearerSubprotocolToken(value) {
|
|
472
|
-
if (!value) return null;
|
|
473
|
-
for (const part of value.split(",")) {
|
|
474
|
-
const protocol = part.trim();
|
|
475
|
-
if (!protocol.toLowerCase().startsWith(BEARER_SUBPROTOCOL_PREFIX)) continue;
|
|
476
|
-
const encoded = protocol.slice(BEARER_SUBPROTOCOL_PREFIX.length);
|
|
477
|
-
if (!encoded) return null;
|
|
478
|
-
try {
|
|
479
|
-
const token = base64UrlDecodeText(encoded).trim();
|
|
480
|
-
return token || null;
|
|
481
|
-
} catch {
|
|
482
|
-
return null;
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
return null;
|
|
486
|
-
}
|
|
487
|
-
function terminalTokenFromRequest(headers) {
|
|
488
|
-
return bearerToken(headers.get("Authorization")) ?? bearerSubprotocolToken(headers.get("Sec-WebSocket-Protocol"));
|
|
489
|
-
}
|
|
490
|
-
function safeDecodeURIComponent(value) {
|
|
491
|
-
try {
|
|
492
|
-
return decodeURIComponent(value);
|
|
493
|
-
} catch {
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
function stripBearerSubprotocol(headers) {
|
|
498
|
-
const value = headers.get("Sec-WebSocket-Protocol");
|
|
499
|
-
if (!value) return;
|
|
500
|
-
const protocols = value.split(",").map((part) => part.trim()).filter((part) => part && !part.toLowerCase().startsWith(BEARER_SUBPROTOCOL_PREFIX));
|
|
501
|
-
if (protocols.length) {
|
|
502
|
-
headers.set("Sec-WebSocket-Protocol", protocols.join(", "));
|
|
503
|
-
} else {
|
|
504
|
-
headers.delete("Sec-WebSocket-Protocol");
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
function validateTerminalSubject(subject) {
|
|
508
|
-
if (!subject.userId) throw new Error("userId is required");
|
|
509
|
-
if (!subject.workspaceId) throw new Error("workspaceId is required");
|
|
510
|
-
if (!subject.sandboxId) throw new Error("sandboxId is required");
|
|
511
|
-
}
|
|
512
255
|
|
|
513
256
|
// src/sandbox/prewarm.ts
|
|
514
257
|
function prewarmKey(scope) {
|
|
@@ -1982,24 +1725,8 @@ export {
|
|
|
1982
1725
|
shellQuote,
|
|
1983
1726
|
statSandboxFileSize,
|
|
1984
1727
|
readSandboxBinaryBytes,
|
|
1985
|
-
mintTerminalProxyToken,
|
|
1986
|
-
verifyTerminalProxyToken,
|
|
1987
1728
|
createWorkspaceSandboxManager,
|
|
1988
|
-
|
|
1989
|
-
verifySandboxTerminalToken,
|
|
1990
|
-
createWorkspaceSandboxConnectionHandler,
|
|
1991
|
-
sandboxSidecarProxyUrl,
|
|
1992
|
-
createWorkspaceSandboxRuntimeProxyHandler,
|
|
1993
|
-
matchSandboxTerminalWsPath,
|
|
1994
|
-
isSandboxTerminalWsUpgrade,
|
|
1995
|
-
createWorkspaceSandboxTerminalUpgradeHandler,
|
|
1996
|
-
terminalUpgradeSubprotocolEcho,
|
|
1997
|
-
selectedBearerSubprotocol,
|
|
1998
|
-
buildSandboxRuntimeProxyHeaders,
|
|
1999
|
-
encodeSandboxRuntimePath,
|
|
2000
|
-
bearerToken,
|
|
2001
|
-
bearerSubprotocolToken,
|
|
2002
|
-
terminalTokenFromRequest,
|
|
1729
|
+
createSandboxTerminalConnectionRoute,
|
|
2003
1730
|
createSandboxPrewarmer,
|
|
2004
1731
|
DEFAULT_PREWARM_CLAIM_TABLE,
|
|
2005
1732
|
PREWARM_CLAIM_TABLE_DDL,
|
|
@@ -2049,4 +1776,4 @@ export {
|
|
|
2049
1776
|
isTerminalPromptEvent,
|
|
2050
1777
|
detectInteractiveQuestion
|
|
2051
1778
|
};
|
|
2052
|
-
//# sourceMappingURL=chunk-
|
|
1779
|
+
//# sourceMappingURL=chunk-EC7CUA4L.js.map
|