@neta-art/cohub 8.21.1 → 8.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board/core/connections.d.ts +18 -1
- package/dist/board/core/connections.js +43 -2
- package/dist/board/export/scene.js +2 -1
- package/dist/board/geometry.d.ts +3 -1
- package/dist/board/geometry.js +16 -1
- package/dist/board/index.d.ts +3 -3
- package/dist/board/index.js +3 -3
- package/dist/board/render/connection-layer.d.ts +6 -1
- package/dist/board/render/connection-layer.js +274 -122
- package/dist/board/task.d.ts +2 -3
- package/dist/board/task.js +25 -95
- package/dist/chunks/environment.d.ts +174 -60
- package/dist/chunks/http.d.ts +78 -8
- package/dist/chunks/http.js +12 -0
- package/dist/chunks/websocket.d.ts +1 -1
- package/dist/generation-blocks.js +125 -0
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +123 -3
- package/dist/index.js +721 -42
- package/dist/media.d.ts +81 -0
- package/dist/media.js +177 -0
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -14,15 +14,28 @@ const appAuthorizationTargetSchema = z.discriminatedUnion("kind", [
|
|
|
14
14
|
}),
|
|
15
15
|
z.object({ kind: z.literal("pick-space") })
|
|
16
16
|
]);
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Read-only scopes the Shell may renew without a dialog for any App on the
|
|
19
|
+
* Space it shows. The API still checks the viewer's own permissions.
|
|
20
|
+
*/
|
|
21
|
+
const APP_SILENT_SHELL_SCOPES = [
|
|
18
22
|
"space.view",
|
|
19
23
|
"file.view",
|
|
20
24
|
"file.view.filtered",
|
|
21
25
|
"session.view",
|
|
22
26
|
"taskrun.view",
|
|
23
27
|
"checkpoint.view"
|
|
24
|
-
]
|
|
28
|
+
];
|
|
29
|
+
const APP_SILENT_SHELL_SCOPE_SET = new Set(APP_SILENT_SHELL_SCOPES);
|
|
25
30
|
const isAppSilentShellScope = (scope) => APP_SILENT_SHELL_SCOPE_SET.has(scope);
|
|
31
|
+
/**
|
|
32
|
+
* The API-enforced ceiling for Host consent (`consent: "host"`), given to Apps
|
|
33
|
+
* the Shell Space published or installed. Trust is decided by the Shell, the
|
|
34
|
+
* only holder of the viewer's token.
|
|
35
|
+
*/
|
|
36
|
+
const APP_HOST_CONSENT_SCOPES = [...APP_SILENT_SHELL_SCOPES, "file.edit"];
|
|
37
|
+
const APP_HOST_CONSENT_SCOPE_SET = new Set(APP_HOST_CONSENT_SCOPES);
|
|
38
|
+
const isAppHostConsentScope = (scope) => APP_HOST_CONSENT_SCOPE_SET.has(scope);
|
|
26
39
|
const appAuthorizationRequestSchema = z.object({
|
|
27
40
|
target: appAuthorizationTargetSchema,
|
|
28
41
|
scopes: z.array(z.string().min(1)).min(1).max(128),
|
|
@@ -281,8 +294,8 @@ const BUILTIN_VERSIONS = new Set(BOARD_BUILTIN_CAPABILITIES.map((c) => `${c.kind
|
|
|
281
294
|
function isBuiltinBoardCapability(kind, id, version) {
|
|
282
295
|
return BUILTIN_VERSIONS.has(`${kind}:${id}@${version}`);
|
|
283
296
|
}
|
|
284
|
-
const record = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
285
|
-
const finite = (value) => typeof value === "number" && Number.isFinite(value);
|
|
297
|
+
const record$1 = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
298
|
+
const finite$1 = (value) => typeof value === "number" && Number.isFinite(value);
|
|
286
299
|
function validateBuiltinBoardClip(clip, path = "clip") {
|
|
287
300
|
if (!CLIPS.has(clip.kind)) return [];
|
|
288
301
|
const errors = [];
|
|
@@ -300,13 +313,13 @@ function validateBuiltinBoardClip(clip, path = "clip") {
|
|
|
300
313
|
if (clip.kind === "motion.path") {
|
|
301
314
|
const points = clip.params.points;
|
|
302
315
|
if (!Array.isArray(points) || points.length < 2 || points.length > 1e4) error("motion path must contain 2 to 10000 world-offset points", "params.points", "world-offset");
|
|
303
|
-
else for (const [index, point] of points.entries()) if (!record(point) || !finite(point.x) || !finite(point.y)) error("motion path point must contain finite x and y", `params.points.${index}`, "world-offset");
|
|
316
|
+
else for (const [index, point] of points.entries()) if (!record$1(point) || !finite$1(point.x) || !finite$1(point.y)) error("motion path point must contain finite x and y", `params.points.${index}`, "world-offset");
|
|
304
317
|
}
|
|
305
318
|
if (clip.kind === "effects.particles") {
|
|
306
319
|
const count = clip.params.count;
|
|
307
320
|
if (!Number.isSafeInteger(count) || count < 1 || count > DEFAULT_BOARD_RENDER_LIMITS.particles) error(`particle count must be an integer from 1 to ${DEFAULT_BOARD_RENDER_LIMITS.particles}`, "params.count", void 0, "INVALID_PARTICLE_COUNT");
|
|
308
321
|
const bounds = clip.params.bounds;
|
|
309
|
-
if (!record(bounds) || !finite(bounds.x) || !finite(bounds.y) || !finite(bounds.width) || !finite(bounds.height) || bounds.width <= 0 || bounds.height <= 0) error("particles require positive finite world bounds", "params.bounds", "world", "PARTICLE_BOUNDS_REQUIRED");
|
|
322
|
+
if (!record$1(bounds) || !finite$1(bounds.x) || !finite$1(bounds.y) || !finite$1(bounds.width) || !finite$1(bounds.height) || bounds.width <= 0 || bounds.height <= 0) error("particles require positive finite world bounds", "params.bounds", "world", "PARTICLE_BOUNDS_REQUIRED");
|
|
310
323
|
}
|
|
311
324
|
if (clip.kind === "camera.focus") {
|
|
312
325
|
const parsed = BoardCameraFocusParamsSchema.safeParse(clip.params);
|
|
@@ -1036,14 +1049,14 @@ var GenerationPolicyError = class extends Error {
|
|
|
1036
1049
|
this.name = "GenerationPolicyError";
|
|
1037
1050
|
}
|
|
1038
1051
|
};
|
|
1039
|
-
function isRecord$
|
|
1052
|
+
function isRecord$5(value) {
|
|
1040
1053
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
1041
1054
|
}
|
|
1042
1055
|
function isPrimitiveEnumValue(value) {
|
|
1043
1056
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1044
1057
|
}
|
|
1045
1058
|
function normalizeConstraint(value) {
|
|
1046
|
-
if (!isRecord$
|
|
1059
|
+
if (!isRecord$5(value) || typeof value.kind !== "string") return null;
|
|
1047
1060
|
if (value.kind === "enum") {
|
|
1048
1061
|
if (!Array.isArray(value.values) || value.values.length === 0 || !value.values.every(isPrimitiveEnumValue)) return null;
|
|
1049
1062
|
return {
|
|
@@ -1073,7 +1086,7 @@ function normalizeConstraint(value) {
|
|
|
1073
1086
|
return null;
|
|
1074
1087
|
}
|
|
1075
1088
|
function normalizeGenerationPolicy(value) {
|
|
1076
|
-
if (!isRecord$
|
|
1089
|
+
if (!isRecord$5(value) || value.version !== 1) return null;
|
|
1077
1090
|
if (value.mode === "auto") return {
|
|
1078
1091
|
version: 1,
|
|
1079
1092
|
mode: "auto"
|
|
@@ -1081,10 +1094,10 @@ function normalizeGenerationPolicy(value) {
|
|
|
1081
1094
|
if (value.mode !== "limited" || !Array.isArray(value.models) || value.models.length === 0) return null;
|
|
1082
1095
|
const models = [];
|
|
1083
1096
|
for (const item of value.models) {
|
|
1084
|
-
if (!isRecord$
|
|
1097
|
+
if (!isRecord$5(item) || typeof item.model !== "string" || !item.model.trim()) return null;
|
|
1085
1098
|
const modelPolicy = { model: item.model.trim() };
|
|
1086
1099
|
if (item.parameters !== void 0) {
|
|
1087
|
-
if (!isRecord$
|
|
1100
|
+
if (!isRecord$5(item.parameters)) return null;
|
|
1088
1101
|
const parameters = {};
|
|
1089
1102
|
for (const [key, rawConstraint] of Object.entries(item.parameters)) {
|
|
1090
1103
|
if (!key.trim()) return null;
|
|
@@ -1372,8 +1385,7 @@ const usage = z.object({
|
|
|
1372
1385
|
}).nullable().optional()
|
|
1373
1386
|
});
|
|
1374
1387
|
const nativeOrigin = z.enum(["local_import"]);
|
|
1375
|
-
|
|
1376
|
-
const nativeTurnStartSchema = z.object({
|
|
1388
|
+
z.object({
|
|
1377
1389
|
turnId: id$1,
|
|
1378
1390
|
sessionId: id$1.nullable(),
|
|
1379
1391
|
parentTurnId: id$1.nullable(),
|
|
@@ -1383,7 +1395,8 @@ const nativeTurnStartSchema = z.object({
|
|
|
1383
1395
|
userContent: content$1,
|
|
1384
1396
|
startedAt: z.iso.datetime(),
|
|
1385
1397
|
sessionStartedAt: z.iso.datetime().optional(),
|
|
1386
|
-
origin: nativeOrigin.optional()
|
|
1398
|
+
origin: nativeOrigin.optional(),
|
|
1399
|
+
controllable: z.boolean().optional()
|
|
1387
1400
|
}).strict().refine((value) => value.sessionId !== null || value.parentTurnId === null, "A parent Turn requires a Session");
|
|
1388
1401
|
const nativeTurnMessageSchema = z.object({
|
|
1389
1402
|
content: content$1,
|
|
@@ -1393,9 +1406,10 @@ const nativeTurnMessageSchema = z.object({
|
|
|
1393
1406
|
stopReason: z.string().max(64).nullable().optional(),
|
|
1394
1407
|
errorMessage: z.string().max(16384).nullable().optional()
|
|
1395
1408
|
}).strict();
|
|
1396
|
-
/** Ephemeral display
|
|
1409
|
+
/** Ephemeral display state within a Turn; never a fork or persistence boundary. */
|
|
1397
1410
|
const nativeTurnProgressSchema = z.object({
|
|
1398
1411
|
revision: z.number().int().safe().positive(),
|
|
1412
|
+
from: z.number().int().nonnegative().max(1e4).optional(),
|
|
1399
1413
|
messages: z.array(nativeTurnMessageSchema).max(1e4)
|
|
1400
1414
|
}).strict();
|
|
1401
1415
|
/** Final, immutable Turn receipt. Native bytes are archived separately, without lossy normalization. */
|
|
@@ -1408,10 +1422,41 @@ const nativeTurnCompleteSchema = z.object({
|
|
|
1408
1422
|
]),
|
|
1409
1423
|
completedAt: z.iso.datetime()
|
|
1410
1424
|
}).strict();
|
|
1425
|
+
/** Durable ingest of one transcript's Turns. */
|
|
1426
|
+
const nativeIngestTurnSchema = z.object({
|
|
1427
|
+
turnId: id$1,
|
|
1428
|
+
parentTurnId: id$1.nullable(),
|
|
1429
|
+
userContent: content$1,
|
|
1430
|
+
startedAt: z.iso.datetime(),
|
|
1431
|
+
origin: nativeOrigin.optional(),
|
|
1432
|
+
result: nativeTurnCompleteSchema.nullable(),
|
|
1433
|
+
controllable: z.boolean().optional()
|
|
1434
|
+
}).strict();
|
|
1435
|
+
/** Turn states that end a Turn; a native Turn in one of them is settled on both sides. */
|
|
1436
|
+
const SETTLED_TURN_STATUSES = [
|
|
1437
|
+
"completed",
|
|
1438
|
+
"failed",
|
|
1439
|
+
"interrupted",
|
|
1440
|
+
"cancelled",
|
|
1441
|
+
"merged"
|
|
1442
|
+
];
|
|
1443
|
+
/** How many Turns one ingest may carry; a larger backlog is sent as consecutive batches. */
|
|
1444
|
+
const NATIVE_INGEST_MAX_TURNS = 500;
|
|
1445
|
+
const nativeIngestSchema = z.object({
|
|
1446
|
+
harness: z.enum(["pi", "codex"]),
|
|
1447
|
+
nativeSessionId: z.string().min(1).max(255),
|
|
1448
|
+
turns: z.array(nativeIngestTurnSchema).min(1).max(500)
|
|
1449
|
+
}).strict();
|
|
1450
|
+
/** Which of these Turns the Space already recorded; lets a restart resume without local receipts. */
|
|
1451
|
+
const nativeKnownSchema = z.object({ turnIds: z.array(id$1).min(1).max(500) }).strict();
|
|
1411
1452
|
const nativeRuntimeEventSchema = z.discriminatedUnion("type", [
|
|
1412
1453
|
z.object({
|
|
1413
|
-
type: z.literal("
|
|
1414
|
-
input:
|
|
1454
|
+
type: z.literal("ingest"),
|
|
1455
|
+
input: nativeIngestSchema
|
|
1456
|
+
}).strict(),
|
|
1457
|
+
z.object({
|
|
1458
|
+
type: z.literal("known"),
|
|
1459
|
+
input: nativeKnownSchema
|
|
1415
1460
|
}).strict(),
|
|
1416
1461
|
z.object({
|
|
1417
1462
|
type: z.literal("progress"),
|
|
@@ -1420,17 +1465,19 @@ const nativeRuntimeEventSchema = z.discriminatedUnion("type", [
|
|
|
1420
1465
|
progress: nativeTurnProgressSchema
|
|
1421
1466
|
}).strict(),
|
|
1422
1467
|
z.object({
|
|
1423
|
-
type: z.literal("
|
|
1468
|
+
type: z.literal("status"),
|
|
1424
1469
|
sessionId: id$1,
|
|
1425
1470
|
turnId: id$1,
|
|
1426
|
-
|
|
1427
|
-
}).strict(),
|
|
1428
|
-
z.object({
|
|
1429
|
-
type: z.literal("heartbeat"),
|
|
1430
|
-
sessionId: id$1,
|
|
1431
|
-
turnId: id$1
|
|
1471
|
+
controllable: z.boolean().optional()
|
|
1432
1472
|
}).strict()
|
|
1433
1473
|
]);
|
|
1474
|
+
/** Pushed to the Runtime: stop a running native Turn, as the web's stop button asks. */
|
|
1475
|
+
const runtimeNativeStopSchema = z.object({
|
|
1476
|
+
type: z.literal("runtime.native.stop"),
|
|
1477
|
+
spaceId: id$1,
|
|
1478
|
+
sessionId: id$1,
|
|
1479
|
+
turnId: id$1
|
|
1480
|
+
}).strict();
|
|
1434
1481
|
const NATIVE_SYNC_SOURCE = "native_client";
|
|
1435
1482
|
const isNativeClientTurn = (meta) => {
|
|
1436
1483
|
if (!meta || typeof meta !== "object") return false;
|
|
@@ -2344,8 +2391,8 @@ const APP_SURFACE_REQUEST_TIMEOUT_MS = 15e3;
|
|
|
2344
2391
|
const APP_COMPOSER_CHIP_KEY_MAX_LENGTH = 80;
|
|
2345
2392
|
const APP_COMPOSER_CHIP_LABEL_MAX_LENGTH = 120;
|
|
2346
2393
|
const APP_COMPOSER_CHIP_CONTENT_MAX_BYTES = 32768;
|
|
2347
|
-
const isRecord$
|
|
2348
|
-
const isSurfaceEnvelope = (value) => isRecord$
|
|
2394
|
+
const isRecord$4 = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
2395
|
+
const isSurfaceEnvelope = (value) => isRecord$4(value) && value.protocol === "cohub.app.surface" && value.version === 1;
|
|
2349
2396
|
const parseAppSurfaceReady = (value) => {
|
|
2350
2397
|
if (!isSurfaceEnvelope(value) || value.type !== "ready") return null;
|
|
2351
2398
|
const methods = Array.isArray(value.methods) ? value.methods.filter((method) => typeof method === "string" && Boolean(method)) : [];
|
|
@@ -2359,7 +2406,7 @@ const parseAppSurfaceReady = (value) => {
|
|
|
2359
2406
|
const parseAppSurfaceResponse = (value) => {
|
|
2360
2407
|
if (!isSurfaceEnvelope(value) || value.type !== "response") return null;
|
|
2361
2408
|
if (typeof value.requestId !== "string" || !value.requestId) return null;
|
|
2362
|
-
const error = isRecord$
|
|
2409
|
+
const error = isRecord$4(value.error) ? {
|
|
2363
2410
|
code: typeof value.error.code === "string" && value.error.code ? value.error.code : "surface_error",
|
|
2364
2411
|
message: typeof value.error.message === "string" ? value.error.message : "App surface call failed"
|
|
2365
2412
|
} : void 0;
|
|
@@ -2379,7 +2426,7 @@ const parseComposerChipKey = (value) => {
|
|
|
2379
2426
|
return key;
|
|
2380
2427
|
};
|
|
2381
2428
|
const parseAppComposerChipSet = (value) => {
|
|
2382
|
-
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.set" || !isRecord$
|
|
2429
|
+
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.set" || !isRecord$4(value.chip)) return null;
|
|
2383
2430
|
const key = parseComposerChipKey(value.chip.key);
|
|
2384
2431
|
if (!key || typeof value.chip.label !== "string" || typeof value.chip.content !== "string") return null;
|
|
2385
2432
|
const label = value.chip.label.trim();
|
|
@@ -2456,6 +2503,7 @@ const buildAppComposerChipClear = (key) => ({
|
|
|
2456
2503
|
//#endregion
|
|
2457
2504
|
//#region ../protocol/dist/app-runtime.js
|
|
2458
2505
|
const APP_RUNTIME_PROTOCOL = "cohub.app.runtime";
|
|
2506
|
+
const isRecord$3 = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
2459
2507
|
const buildAppRuntimeReady = () => ({
|
|
2460
2508
|
protocol: APP_RUNTIME_PROTOCOL,
|
|
2461
2509
|
version: 1,
|
|
@@ -2466,6 +2514,7 @@ const buildAppRuntimeCloseRequest = () => ({
|
|
|
2466
2514
|
version: 1,
|
|
2467
2515
|
type: "close.request"
|
|
2468
2516
|
});
|
|
2517
|
+
const finite = (value) => typeof value === "number" && Number.isFinite(value);
|
|
2469
2518
|
const buildAppRuntimeConfigureRequest = (input) => ({
|
|
2470
2519
|
protocol: APP_RUNTIME_PROTOCOL,
|
|
2471
2520
|
version: 1,
|
|
@@ -2480,6 +2529,154 @@ const buildAppRuntimePointer = (input) => ({
|
|
|
2480
2529
|
y: input.y,
|
|
2481
2530
|
down: input.down
|
|
2482
2531
|
});
|
|
2532
|
+
const isRuntimeMessage = (value, type) => isRecord$3(value) && value.protocol === "cohub.app.runtime" && value.version === 1 && value.type === type;
|
|
2533
|
+
const envelope$1 = (type) => ({
|
|
2534
|
+
protocol: APP_RUNTIME_PROTOCOL,
|
|
2535
|
+
version: 1,
|
|
2536
|
+
type
|
|
2537
|
+
});
|
|
2538
|
+
const boundedText = (value, max) => {
|
|
2539
|
+
if (typeof value !== "string") return null;
|
|
2540
|
+
const text = value.replace(/\s+/g, " ").trim();
|
|
2541
|
+
return text ? text.slice(0, max) : null;
|
|
2542
|
+
};
|
|
2543
|
+
const buildAppRuntimeAnnounce = () => envelope$1("announce");
|
|
2544
|
+
const parseAppRuntimeAnnounce = (value) => isRuntimeMessage(value, "announce") ? buildAppRuntimeAnnounce() : null;
|
|
2545
|
+
const buildAppRuntimeWindowState = (state) => ({
|
|
2546
|
+
...envelope$1("window.state"),
|
|
2547
|
+
title: state.title,
|
|
2548
|
+
status: state.status,
|
|
2549
|
+
dirty: state.dirty
|
|
2550
|
+
});
|
|
2551
|
+
const requestIdOf = (value) => typeof value.requestId === "string" && value.requestId && value.requestId.length <= 128 ? value.requestId : null;
|
|
2552
|
+
const buildAppRuntimeClosePrepare = (requestId) => ({
|
|
2553
|
+
...envelope$1("close.prepare"),
|
|
2554
|
+
requestId
|
|
2555
|
+
});
|
|
2556
|
+
const parseAppRuntimeClosePrepare = (value) => {
|
|
2557
|
+
if (!isRuntimeMessage(value, "close.prepare")) return null;
|
|
2558
|
+
const requestId = requestIdOf(value);
|
|
2559
|
+
return requestId ? buildAppRuntimeClosePrepare(requestId) : null;
|
|
2560
|
+
};
|
|
2561
|
+
const buildAppRuntimeClosePrepared = (input) => ({
|
|
2562
|
+
...envelope$1("close.prepared"),
|
|
2563
|
+
requestId: input.requestId,
|
|
2564
|
+
ok: input.ok
|
|
2565
|
+
});
|
|
2566
|
+
/** Select all, copy, paste, cut, undo, redo: the browser's, and the App's. */
|
|
2567
|
+
const EDITING_CHORD_KEYS = /* @__PURE__ */ new Set([
|
|
2568
|
+
"a",
|
|
2569
|
+
"c",
|
|
2570
|
+
"v",
|
|
2571
|
+
"x",
|
|
2572
|
+
"y",
|
|
2573
|
+
"z"
|
|
2574
|
+
]);
|
|
2575
|
+
/** Whether a Ctrl / Meta chord may reach the host; both sides apply this rule. */
|
|
2576
|
+
const isAppRuntimeHostChord = (input) => (input.ctrlKey || input.metaKey) && !EDITING_CHORD_KEYS.has(input.key.toLowerCase());
|
|
2577
|
+
const buildAppRuntimeKey = (input) => ({
|
|
2578
|
+
...envelope$1("key"),
|
|
2579
|
+
key: input.key,
|
|
2580
|
+
code: input.code,
|
|
2581
|
+
altKey: input.altKey,
|
|
2582
|
+
ctrlKey: input.ctrlKey,
|
|
2583
|
+
metaKey: input.metaKey,
|
|
2584
|
+
shiftKey: input.shiftKey
|
|
2585
|
+
});
|
|
2586
|
+
/** Resource kinds the Cohub host can drop into an App. */
|
|
2587
|
+
const APP_DROP_RESOURCE_TYPES = [
|
|
2588
|
+
"file",
|
|
2589
|
+
"task",
|
|
2590
|
+
"app",
|
|
2591
|
+
"session",
|
|
2592
|
+
"checkpoint"
|
|
2593
|
+
];
|
|
2594
|
+
const isDropResourceType = (value) => APP_DROP_RESOURCE_TYPES.includes(value);
|
|
2595
|
+
const MAX_DROP_RESOURCES = 100;
|
|
2596
|
+
const parseDropResource = (value) => {
|
|
2597
|
+
if (!isRecord$3(value) || !isDropResourceType(value.type)) return null;
|
|
2598
|
+
const ref = boundedText(value.ref, 4096);
|
|
2599
|
+
if (!ref) return null;
|
|
2600
|
+
const resource = {
|
|
2601
|
+
type: value.type,
|
|
2602
|
+
ref
|
|
2603
|
+
};
|
|
2604
|
+
for (const key of [
|
|
2605
|
+
"title",
|
|
2606
|
+
"path",
|
|
2607
|
+
"mimeType",
|
|
2608
|
+
"appId",
|
|
2609
|
+
"href",
|
|
2610
|
+
"taskRunId"
|
|
2611
|
+
]) {
|
|
2612
|
+
const text = boundedText(value[key], 4096);
|
|
2613
|
+
if (text) resource[key] = text;
|
|
2614
|
+
}
|
|
2615
|
+
if (finite(value.size) && value.size >= 0) resource.size = value.size;
|
|
2616
|
+
if (finite(value.mtimeMs)) resource.mtimeMs = value.mtimeMs;
|
|
2617
|
+
if (isRecord$3(value.snapshot)) resource.snapshot = value.snapshot;
|
|
2618
|
+
return resource;
|
|
2619
|
+
};
|
|
2620
|
+
const parseDropTypes = (value) => Array.isArray(value) ? [...new Set(value.filter(isDropResourceType))] : [];
|
|
2621
|
+
const buildAppRuntimeDropConfig = (accept) => ({
|
|
2622
|
+
...envelope$1("drop.config"),
|
|
2623
|
+
accept: [...accept]
|
|
2624
|
+
});
|
|
2625
|
+
const buildAppRuntimeDrag = (input) => ({
|
|
2626
|
+
...envelope$1("drag"),
|
|
2627
|
+
phase: input.phase,
|
|
2628
|
+
x: input.x,
|
|
2629
|
+
y: input.y,
|
|
2630
|
+
types: [...input.types],
|
|
2631
|
+
...input.phase === "drop" ? { resources: input.resources ?? [] } : {}
|
|
2632
|
+
});
|
|
2633
|
+
const parseAppRuntimeDrag = (value) => {
|
|
2634
|
+
if (!isRuntimeMessage(value, "drag")) return null;
|
|
2635
|
+
if (value.phase !== "over" && value.phase !== "leave" && value.phase !== "drop") return null;
|
|
2636
|
+
if (!finite(value.x) || !finite(value.y)) return null;
|
|
2637
|
+
const resources = value.phase === "drop" && Array.isArray(value.resources) ? value.resources.slice(0, MAX_DROP_RESOURCES).map(parseDropResource).filter((resource) => resource !== null) : void 0;
|
|
2638
|
+
return buildAppRuntimeDrag({
|
|
2639
|
+
phase: value.phase,
|
|
2640
|
+
x: value.x,
|
|
2641
|
+
y: value.y,
|
|
2642
|
+
types: parseDropTypes(value.types),
|
|
2643
|
+
...resources ? { resources } : {}
|
|
2644
|
+
});
|
|
2645
|
+
};
|
|
2646
|
+
/** Public design tokens, sent as resolved CSS values. */
|
|
2647
|
+
const APP_APPEARANCE_TOKENS = [
|
|
2648
|
+
"bg-primary",
|
|
2649
|
+
"bg-content",
|
|
2650
|
+
"bg-surface",
|
|
2651
|
+
"bg-elevated",
|
|
2652
|
+
"bg-input",
|
|
2653
|
+
"bg-hover",
|
|
2654
|
+
"bg-active",
|
|
2655
|
+
"text-primary",
|
|
2656
|
+
"text-secondary",
|
|
2657
|
+
"text-tertiary",
|
|
2658
|
+
"text-placeholder",
|
|
2659
|
+
"text-disabled",
|
|
2660
|
+
"border-primary",
|
|
2661
|
+
"border-subtle",
|
|
2662
|
+
"brand",
|
|
2663
|
+
"brand-hover",
|
|
2664
|
+
"brand-soft",
|
|
2665
|
+
"brand-muted",
|
|
2666
|
+
"brand-border",
|
|
2667
|
+
"brand-ring",
|
|
2668
|
+
"brand-contrast-fg",
|
|
2669
|
+
"error-fg",
|
|
2670
|
+
"selection-bg",
|
|
2671
|
+
"overlay-scrim",
|
|
2672
|
+
"shadow-subtle",
|
|
2673
|
+
"shadow-medium",
|
|
2674
|
+
"shadow-strong",
|
|
2675
|
+
"font-sans",
|
|
2676
|
+
"font-mono"
|
|
2677
|
+
];
|
|
2678
|
+
/** CSS custom property an App reads a shared token from, e.g. `--cohub-bg-primary`. */
|
|
2679
|
+
const appAppearanceVar = (token) => `--cohub-${token}`;
|
|
2483
2680
|
//#endregion
|
|
2484
2681
|
//#region ../protocol/dist/app-navigation.js
|
|
2485
2682
|
const APP_NAVIGATION_PROTOCOL = "cohub.app.navigation";
|
|
@@ -3104,6 +3301,8 @@ var AppSurfaceApi = class {
|
|
|
3104
3301
|
listening = false;
|
|
3105
3302
|
allowedOrigins = null;
|
|
3106
3303
|
trustedOrigin;
|
|
3304
|
+
/** The chip on show, so it can be announced again. */
|
|
3305
|
+
chip = null;
|
|
3107
3306
|
allowHostOrigins(origins) {
|
|
3108
3307
|
this.allowedOrigins = origins.map((origin) => origin.trim()).filter(Boolean).map((origin) => {
|
|
3109
3308
|
try {
|
|
@@ -3134,11 +3333,14 @@ var AppSurfaceApi = class {
|
|
|
3134
3333
|
setComposerChip(chip) {
|
|
3135
3334
|
const message = parseAppComposerChipSet(buildAppComposerChipSet(chip));
|
|
3136
3335
|
if (!message) throw new Error("Invalid App composer chip");
|
|
3336
|
+
this.chip = message.chip;
|
|
3337
|
+
this.start();
|
|
3137
3338
|
this.post(message);
|
|
3138
3339
|
}
|
|
3139
3340
|
clearComposerChip(key) {
|
|
3140
3341
|
const message = parseAppComposerChipClear(buildAppComposerChipClear(key));
|
|
3141
3342
|
if (!message) throw new Error("Invalid App composer chip key");
|
|
3343
|
+
if (this.chip?.key === message.key) this.chip = null;
|
|
3142
3344
|
this.post(message);
|
|
3143
3345
|
}
|
|
3144
3346
|
announce() {
|
|
@@ -3163,6 +3365,11 @@ var AppSurfaceApi = class {
|
|
|
3163
3365
|
onMessage = (event) => {
|
|
3164
3366
|
if (typeof window === "undefined" || event.source !== window.parent) return;
|
|
3165
3367
|
if (!this.isTrusted(event.origin)) return;
|
|
3368
|
+
if (parseAppRuntimeAnnounce(event.data)) {
|
|
3369
|
+
if (this.handlers.size > 0) this.announce();
|
|
3370
|
+
if (this.chip) this.post(buildAppComposerChipSet(this.chip));
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3166
3373
|
const request = parseAppSurfaceRequest(event.data);
|
|
3167
3374
|
if (!request) return;
|
|
3168
3375
|
const commandId = request.commandId;
|
|
@@ -3267,6 +3474,171 @@ function attachAppEmbed(frame, options) {
|
|
|
3267
3474
|
};
|
|
3268
3475
|
}
|
|
3269
3476
|
//#endregion
|
|
3477
|
+
//#region src/app-window.ts
|
|
3478
|
+
/** One document listener for all clients, so a chord reaches the host once. */
|
|
3479
|
+
const keyTransports = /* @__PURE__ */ new Set();
|
|
3480
|
+
function forwardKey(event) {
|
|
3481
|
+
if (event.isComposing || !isAppRuntimeHostChord(event)) return;
|
|
3482
|
+
setTimeout(() => {
|
|
3483
|
+
if (event.defaultPrevented) return;
|
|
3484
|
+
[...keyTransports].find((candidate) => candidate.isHostConnected?.())?.notify?.(buildAppRuntimeKey({
|
|
3485
|
+
key: event.key,
|
|
3486
|
+
code: event.code,
|
|
3487
|
+
altKey: event.altKey,
|
|
3488
|
+
ctrlKey: event.ctrlKey,
|
|
3489
|
+
metaKey: event.metaKey,
|
|
3490
|
+
shiftKey: event.shiftKey
|
|
3491
|
+
}));
|
|
3492
|
+
}, 0);
|
|
3493
|
+
}
|
|
3494
|
+
function attachKeys(transport) {
|
|
3495
|
+
if (keyTransports.size === 0) window.addEventListener("keydown", forwardKey);
|
|
3496
|
+
keyTransports.add(transport);
|
|
3497
|
+
}
|
|
3498
|
+
function detachKeys(transport) {
|
|
3499
|
+
if (!keyTransports.delete(transport)) return;
|
|
3500
|
+
if (keyTransports.size === 0) window.removeEventListener("keydown", forwardKey);
|
|
3501
|
+
}
|
|
3502
|
+
/** The App's side of its host window; a no-op outside a Cohub host. */
|
|
3503
|
+
var AppWindowApi = class {
|
|
3504
|
+
transport;
|
|
3505
|
+
runtime;
|
|
3506
|
+
state = {
|
|
3507
|
+
title: null,
|
|
3508
|
+
status: "idle",
|
|
3509
|
+
dirty: false
|
|
3510
|
+
};
|
|
3511
|
+
/** Only a client that reported state re-announces it; others must not reset it. */
|
|
3512
|
+
stateReported = false;
|
|
3513
|
+
beforeClose = null;
|
|
3514
|
+
dropHandler = null;
|
|
3515
|
+
hostUnsubscribe = null;
|
|
3516
|
+
constructor(transport, runtime) {
|
|
3517
|
+
this.transport = transport;
|
|
3518
|
+
this.runtime = runtime;
|
|
3519
|
+
if (typeof window === "undefined" || !transport.notify) return;
|
|
3520
|
+
if (window.parent === window || typeof window.addEventListener !== "function") return;
|
|
3521
|
+
attachKeys(transport);
|
|
3522
|
+
}
|
|
3523
|
+
/** Report the tab title, save status, and whether work is still unsaved. */
|
|
3524
|
+
setState(patch) {
|
|
3525
|
+
this.state = {
|
|
3526
|
+
...this.state,
|
|
3527
|
+
...patch
|
|
3528
|
+
};
|
|
3529
|
+
this.stateReported = true;
|
|
3530
|
+
this.listen();
|
|
3531
|
+
this.transport.notify?.(buildAppRuntimeWindowState(this.state));
|
|
3532
|
+
}
|
|
3533
|
+
/** Persist work before a `dirty` window closes; `false` or throw keeps it open. */
|
|
3534
|
+
onBeforeClose(handler) {
|
|
3535
|
+
this.beforeClose = handler;
|
|
3536
|
+
this.listen();
|
|
3537
|
+
return () => {
|
|
3538
|
+
if (this.beforeClose === handler) this.beforeClose = null;
|
|
3539
|
+
};
|
|
3540
|
+
}
|
|
3541
|
+
/** Accept Cohub resources dragged from the host onto this App. */
|
|
3542
|
+
onDrop(handler) {
|
|
3543
|
+
this.dropHandler = handler;
|
|
3544
|
+
this.listen();
|
|
3545
|
+
this.transport.notify?.(buildAppRuntimeDropConfig(handler.accept));
|
|
3546
|
+
return () => {
|
|
3547
|
+
if (this.dropHandler !== handler) return;
|
|
3548
|
+
this.dropHandler = null;
|
|
3549
|
+
this.transport.notify?.(buildAppRuntimeDropConfig([]));
|
|
3550
|
+
};
|
|
3551
|
+
}
|
|
3552
|
+
/** The window's file: on open, on reopen, and after a rename or move. */
|
|
3553
|
+
onLaunch(listener) {
|
|
3554
|
+
let last = null;
|
|
3555
|
+
const handle = (context) => {
|
|
3556
|
+
const invocation = context?.invocation;
|
|
3557
|
+
if (!invocation?.file || !invocation.spaceId) return;
|
|
3558
|
+
const key = `${invocation.id ?? ""}:${invocation.spaceId}:${invocation.file.path}`;
|
|
3559
|
+
if (key === last) return;
|
|
3560
|
+
last = key;
|
|
3561
|
+
listener({ file: {
|
|
3562
|
+
spaceId: invocation.spaceId,
|
|
3563
|
+
path: invocation.file.path
|
|
3564
|
+
} });
|
|
3565
|
+
};
|
|
3566
|
+
const unsubscribe = this.runtime.onContextChanged(handle);
|
|
3567
|
+
this.runtime.context().then(handle, () => {});
|
|
3568
|
+
return unsubscribe;
|
|
3569
|
+
}
|
|
3570
|
+
dispose() {
|
|
3571
|
+
this.hostUnsubscribe?.();
|
|
3572
|
+
this.hostUnsubscribe = null;
|
|
3573
|
+
detachKeys(this.transport);
|
|
3574
|
+
}
|
|
3575
|
+
listen() {
|
|
3576
|
+
if (this.hostUnsubscribe || !this.transport.subscribeHostMessages) return;
|
|
3577
|
+
this.hostUnsubscribe = this.transport.subscribeHostMessages((data) => {
|
|
3578
|
+
if (parseAppRuntimeAnnounce(data)) {
|
|
3579
|
+
this.announce();
|
|
3580
|
+
return;
|
|
3581
|
+
}
|
|
3582
|
+
if (!this.transport.isHostConnected?.()) return;
|
|
3583
|
+
const prepare = parseAppRuntimeClosePrepare(data);
|
|
3584
|
+
if (prepare) {
|
|
3585
|
+
this.prepareClose(prepare.requestId);
|
|
3586
|
+
return;
|
|
3587
|
+
}
|
|
3588
|
+
const drag = parseAppRuntimeDrag(data);
|
|
3589
|
+
if (drag) this.dispatchDrag(drag);
|
|
3590
|
+
});
|
|
3591
|
+
this.runtime.context().catch(() => {});
|
|
3592
|
+
}
|
|
3593
|
+
/** A reloaded frame forgot the tab state and drops; report them again. */
|
|
3594
|
+
announce() {
|
|
3595
|
+
if (this.stateReported) this.transport.notify?.(buildAppRuntimeWindowState(this.state));
|
|
3596
|
+
if (this.dropHandler) this.transport.notify?.(buildAppRuntimeDropConfig(this.dropHandler.accept));
|
|
3597
|
+
}
|
|
3598
|
+
async prepareClose(requestId) {
|
|
3599
|
+
let ok;
|
|
3600
|
+
try {
|
|
3601
|
+
ok = this.beforeClose ? await this.beforeClose() !== false : !this.state.dirty;
|
|
3602
|
+
} catch {
|
|
3603
|
+
ok = false;
|
|
3604
|
+
}
|
|
3605
|
+
this.transport.notify?.(buildAppRuntimeClosePrepared({
|
|
3606
|
+
requestId,
|
|
3607
|
+
ok
|
|
3608
|
+
}));
|
|
3609
|
+
}
|
|
3610
|
+
dispatchDrag(drag) {
|
|
3611
|
+
const handler = this.dropHandler;
|
|
3612
|
+
if (!handler) return;
|
|
3613
|
+
const point = {
|
|
3614
|
+
x: drag.x,
|
|
3615
|
+
y: drag.y,
|
|
3616
|
+
types: drag.types
|
|
3617
|
+
};
|
|
3618
|
+
if (drag.phase === "over") handler.over?.(point);
|
|
3619
|
+
else if (drag.phase === "leave") handler.leave?.();
|
|
3620
|
+
else handler.drop({
|
|
3621
|
+
...point,
|
|
3622
|
+
resources: drag.resources ?? []
|
|
3623
|
+
});
|
|
3624
|
+
}
|
|
3625
|
+
};
|
|
3626
|
+
/** Writes host tokens (`--cohub-*`), color scheme, and `lang` onto `root`. */
|
|
3627
|
+
function applyAppAppearance(root, context) {
|
|
3628
|
+
const appearance = context?.appearance;
|
|
3629
|
+
for (const token of APP_APPEARANCE_TOKENS) {
|
|
3630
|
+
const value = appearance?.tokens[token];
|
|
3631
|
+
if (value) root.style.setProperty(appAppearanceVar(token), value);
|
|
3632
|
+
else root.style.removeProperty(appAppearanceVar(token));
|
|
3633
|
+
}
|
|
3634
|
+
if (appearance) {
|
|
3635
|
+
root.style.colorScheme = appearance.colorScheme;
|
|
3636
|
+
root.dataset.cohubColorScheme = appearance.colorScheme;
|
|
3637
|
+
root.dataset.cohubReducedMotion = String(appearance.reducedMotion);
|
|
3638
|
+
}
|
|
3639
|
+
if (context?.locale) root.lang = context.locale;
|
|
3640
|
+
}
|
|
3641
|
+
//#endregion
|
|
3270
3642
|
//#region src/app-runtime.ts
|
|
3271
3643
|
var AppRuntimeError = class extends Error {
|
|
3272
3644
|
code;
|
|
@@ -3306,6 +3678,36 @@ var ParentBridgeTransport = class {
|
|
|
3306
3678
|
contextListener = null;
|
|
3307
3679
|
diagnosticListeners = /* @__PURE__ */ new Set();
|
|
3308
3680
|
diagnosticListener = null;
|
|
3681
|
+
hostListeners = /* @__PURE__ */ new Set();
|
|
3682
|
+
hostListener = null;
|
|
3683
|
+
announceListener = null;
|
|
3684
|
+
isHostConnected() {
|
|
3685
|
+
return this.trustedParentOrigin !== null;
|
|
3686
|
+
}
|
|
3687
|
+
isFromParent(event) {
|
|
3688
|
+
if (event.source !== window.parent) return false;
|
|
3689
|
+
const parentOrigin = this.trustedParentOrigin ?? getParentOrigin();
|
|
3690
|
+
return !parentOrigin || event.origin === parentOrigin;
|
|
3691
|
+
}
|
|
3692
|
+
subscribeHostMessages(listener) {
|
|
3693
|
+
if (!hasParent() || typeof window.addEventListener !== "function") return () => {};
|
|
3694
|
+
this.hostListeners.add(listener);
|
|
3695
|
+
this.announceReady();
|
|
3696
|
+
if (!this.hostListener) {
|
|
3697
|
+
this.hostListener = (event) => {
|
|
3698
|
+
if (!this.isFromParent(event)) return;
|
|
3699
|
+
for (const current of this.hostListeners) current(event.data);
|
|
3700
|
+
};
|
|
3701
|
+
window.addEventListener("message", this.hostListener);
|
|
3702
|
+
}
|
|
3703
|
+
return () => {
|
|
3704
|
+
this.hostListeners.delete(listener);
|
|
3705
|
+
if (this.hostListeners.size === 0 && this.hostListener) {
|
|
3706
|
+
window.removeEventListener("message", this.hostListener);
|
|
3707
|
+
this.hostListener = null;
|
|
3708
|
+
}
|
|
3709
|
+
};
|
|
3710
|
+
}
|
|
3309
3711
|
/**
|
|
3310
3712
|
* Tells the host the runtime is ready once, before any subscription. Hosts
|
|
3311
3713
|
* gate unsolicited messages (context pushes, diagnostics) on this handshake,
|
|
@@ -3319,8 +3721,19 @@ var ParentBridgeTransport = class {
|
|
|
3319
3721
|
try {
|
|
3320
3722
|
window.parent.postMessage(buildAppRuntimeReady(), parentOrigin);
|
|
3321
3723
|
this.readyAnnounced = true;
|
|
3724
|
+
this.answerAnnounceRequests();
|
|
3322
3725
|
} catch {}
|
|
3323
3726
|
}
|
|
3727
|
+
/** Says ready again when a reloaded host asks. */
|
|
3728
|
+
answerAnnounceRequests() {
|
|
3729
|
+
if (this.announceListener || typeof window.addEventListener !== "function") return;
|
|
3730
|
+
this.announceListener = (event) => {
|
|
3731
|
+
if (!this.isFromParent(event) || !parseAppRuntimeAnnounce(event.data)) return;
|
|
3732
|
+
this.readyAnnounced = false;
|
|
3733
|
+
this.announceReady();
|
|
3734
|
+
};
|
|
3735
|
+
window.addEventListener("message", this.announceListener);
|
|
3736
|
+
}
|
|
3324
3737
|
subscribeDiagnostics(listener) {
|
|
3325
3738
|
if (!hasParent() || typeof window.addEventListener !== "function") return () => {};
|
|
3326
3739
|
this.diagnosticListeners.add(listener);
|
|
@@ -4299,6 +4712,7 @@ var CohubClient = class {
|
|
|
4299
4712
|
transport;
|
|
4300
4713
|
websocketClient;
|
|
4301
4714
|
appRuntime;
|
|
4715
|
+
appWindow;
|
|
4302
4716
|
constructor(options = {}) {
|
|
4303
4717
|
const apiBaseUrl = resolveApiBaseUrl(options);
|
|
4304
4718
|
const appRuntime = options.app ?? options.work;
|
|
@@ -4314,6 +4728,10 @@ var CohubClient = class {
|
|
|
4314
4728
|
fetch: options.fetch
|
|
4315
4729
|
}), resolveWebBaseUrl({ env: options.env }));
|
|
4316
4730
|
this.appRuntime = createAppRuntime(appTransport, appRuntime?.appId, appIdResolver);
|
|
4731
|
+
this.appWindow = new AppWindowApi(appTransport, {
|
|
4732
|
+
context: () => this.appRuntime.context(),
|
|
4733
|
+
onContextChanged: (listener) => this.appRuntime.onContextChanged(listener)
|
|
4734
|
+
});
|
|
4317
4735
|
const executionToken = resolveExecutionToken();
|
|
4318
4736
|
const getAccessToken = options.getAccessToken ?? (executionToken ? () => executionToken : (tokenOptions) => this.appRuntime.getAccessToken(tokenOptions));
|
|
4319
4737
|
const resolvedOptions = {
|
|
@@ -4369,6 +4787,7 @@ var CohubClient = class {
|
|
|
4369
4787
|
/** Releases listeners this client registered. Safe to call more than once. */
|
|
4370
4788
|
dispose() {
|
|
4371
4789
|
this.appRuntime.dispose();
|
|
4790
|
+
this.appWindow.dispose();
|
|
4372
4791
|
}
|
|
4373
4792
|
auth = {
|
|
4374
4793
|
authorize: (input) => this.appRuntime.authorize(input),
|
|
@@ -4390,6 +4809,26 @@ var CohubClient = class {
|
|
|
4390
4809
|
/** Expose callable methods from inside a published app. */
|
|
4391
4810
|
surface: new AppSurfaceApi(),
|
|
4392
4811
|
onContextChanged: (listener) => this.appRuntime.onContextChanged(listener),
|
|
4812
|
+
/** Files the host opens with this App — the first one and every later open. */
|
|
4813
|
+
onLaunch: (listener) => this.appWindow.onLaunch(listener),
|
|
4814
|
+
/** Accept Cohub resources the viewer drags from the host onto this App. */
|
|
4815
|
+
onDrop: (handler) => this.appWindow.onDrop(handler),
|
|
4816
|
+
window: {
|
|
4817
|
+
/** Report the tab title, save status, and whether work is still unsaved. */
|
|
4818
|
+
setState: (patch) => this.appWindow.setState(patch),
|
|
4819
|
+
/** Persist pending work before the host closes a `dirty` window. */
|
|
4820
|
+
onBeforeClose: (handler) => this.appWindow.onBeforeClose(handler)
|
|
4821
|
+
},
|
|
4822
|
+
appearance: {
|
|
4823
|
+
/** Keep `root` (default `<html>`) in sync with the host theme and locale. */
|
|
4824
|
+
sync: (root) => {
|
|
4825
|
+
const target = root ?? (typeof document === "undefined" ? null : document.documentElement);
|
|
4826
|
+
if (!target) return () => {};
|
|
4827
|
+
const apply = (context) => applyAppAppearance(target, context);
|
|
4828
|
+
const stop = this.appRuntime.onContextChanged(apply);
|
|
4829
|
+
this.appRuntime.context().then(apply, () => {});
|
|
4830
|
+
return stop;
|
|
4831
|
+
} },
|
|
4393
4832
|
/** Ask the host to close this App's surface. */
|
|
4394
4833
|
requestClose: () => this.appRuntime.requestClose(),
|
|
4395
4834
|
/**
|
|
@@ -4759,7 +5198,17 @@ function cloneInvocation(invocation) {
|
|
|
4759
5198
|
...invocation.embedder ? { embedder: {
|
|
4760
5199
|
appId: invocation.embedder.appId,
|
|
4761
5200
|
slug: invocation.embedder.slug
|
|
4762
|
-
} } : {}
|
|
5201
|
+
} } : {},
|
|
5202
|
+
...invocation.file ? { file: { path: invocation.file.path } } : {}
|
|
5203
|
+
};
|
|
5204
|
+
}
|
|
5205
|
+
/** Host appearance can be reactive state too; copy it into plain data. */
|
|
5206
|
+
function cloneAppearance(appearance) {
|
|
5207
|
+
return {
|
|
5208
|
+
colorScheme: appearance.colorScheme,
|
|
5209
|
+
theme: appearance.theme,
|
|
5210
|
+
tokens: { ...appearance.tokens },
|
|
5211
|
+
reducedMotion: appearance.reducedMotion
|
|
4763
5212
|
};
|
|
4764
5213
|
}
|
|
4765
5214
|
/**
|
|
@@ -5012,6 +5461,9 @@ function createAppBridgeCore(config) {
|
|
|
5012
5461
|
async function getContext() {
|
|
5013
5462
|
const invocation = activeInvocation !== void 0 ? activeInvocation : config.getInvocation?.() ?? config.invocation;
|
|
5014
5463
|
const shell = config.getShell?.() ?? config.shell;
|
|
5464
|
+
const locale = config.getLocale?.();
|
|
5465
|
+
const appearance = config.getAppearance?.();
|
|
5466
|
+
const windowState = config.getWindow?.();
|
|
5015
5467
|
const appScopes = clonePermissionScopes(app.appScopes);
|
|
5016
5468
|
const viewerUuid = await getViewerUuid();
|
|
5017
5469
|
synchronizeViewer(viewerUuid);
|
|
@@ -5040,6 +5492,9 @@ function createAppBridgeCore(config) {
|
|
|
5040
5492
|
session: shell.session ? { ...shell.session } : null,
|
|
5041
5493
|
turn: shell.turn ? { ...shell.turn } : null
|
|
5042
5494
|
} } : {},
|
|
5495
|
+
...locale ? { locale } : {},
|
|
5496
|
+
...appearance ? { appearance: cloneAppearance(appearance) } : {},
|
|
5497
|
+
...windowState ? { window: { visible: windowState.visible } } : {},
|
|
5043
5498
|
permissions: {
|
|
5044
5499
|
scopes: normalizePermissionScopes([...appScopes, ...viewerGrants.flatMap((grant) => grant.scopes)]),
|
|
5045
5500
|
appScopes,
|
|
@@ -5217,8 +5672,7 @@ function createAppBridgeCore(config) {
|
|
|
5217
5672
|
/**
|
|
5218
5673
|
* Calls the authorize endpoint. `silent` marks a background refresh of a
|
|
5219
5674
|
* previous consent: the server then only renews a live grant and never
|
|
5220
|
-
* creates or revives one
|
|
5221
|
-
* fresh dialog.
|
|
5675
|
+
* creates or revives one. `consent: "host"` may also create or widen one.
|
|
5222
5676
|
*/
|
|
5223
5677
|
async function authorize(scopes, spaceId, options) {
|
|
5224
5678
|
const incremental = Boolean(state.pendingAuth && authorizationRequests.has(state.pendingAuth.requestId));
|
|
@@ -5242,6 +5696,7 @@ function createAppBridgeCore(config) {
|
|
|
5242
5696
|
scopes,
|
|
5243
5697
|
...spaceId ? { spaceId } : {},
|
|
5244
5698
|
...options?.silent ? { silent: true } : {},
|
|
5699
|
+
...options?.consent ? { consent: options.consent } : {},
|
|
5245
5700
|
...incremental ? { scopeMode: "extend" } : {}
|
|
5246
5701
|
})
|
|
5247
5702
|
});
|
|
@@ -5288,17 +5743,15 @@ function createAppBridgeCore(config) {
|
|
|
5288
5743
|
}
|
|
5289
5744
|
}
|
|
5290
5745
|
/**
|
|
5291
|
-
*
|
|
5746
|
+
* Grants scopes on the current Shell Space without opening the dialog.
|
|
5292
5747
|
*
|
|
5293
5748
|
* Deciding that a request needs no dialog is the Host's job: it compares the
|
|
5294
|
-
* target
|
|
5295
|
-
* *whether to ask*; the server still decides *what may be granted* through
|
|
5296
|
-
* the silent path, so a revoked consent can never come back on its own.
|
|
5749
|
+
* target and trust; the server still caps what may be granted.
|
|
5297
5750
|
*/
|
|
5298
5751
|
const shellAuthorizationInFlight = /* @__PURE__ */ new Map();
|
|
5299
5752
|
const shellAuthorizationCache = /* @__PURE__ */ new Map();
|
|
5300
5753
|
const SHELL_AUTH_CACHE_MS = 3e4;
|
|
5301
|
-
async function authorizeShellSilently(scopes, spaceId) {
|
|
5754
|
+
async function authorizeShellSilently(scopes, spaceId, consent) {
|
|
5302
5755
|
const shellContext = config.getShell?.() ?? config.shell;
|
|
5303
5756
|
const shell = shellContext?.space ?? null;
|
|
5304
5757
|
if (!shellContext || authorizationContext.surface === "broker" || !shell || shell.id !== spaceId) throw new AppAuthorizationError("Shell authorization is unavailable for this surface.", 403, "consent_required");
|
|
@@ -5307,13 +5760,16 @@ function createAppBridgeCore(config) {
|
|
|
5307
5760
|
await startSignIn();
|
|
5308
5761
|
throw new AppLoginRedirect();
|
|
5309
5762
|
}
|
|
5310
|
-
const cacheKey = `${viewerUuid}:${app.id}:${spaceId}:${[...scopes].sort().join(",")}`;
|
|
5763
|
+
const cacheKey = `${viewerUuid}:${app.id}:${spaceId}:${consent}:${[...scopes].sort().join(",")}`;
|
|
5311
5764
|
const cached = shellAuthorizationCache.get(cacheKey);
|
|
5312
5765
|
if (cached && cached.expiresAt > Date.now()) return cached.result;
|
|
5313
5766
|
if (cached) shellAuthorizationCache.delete(cacheKey);
|
|
5314
5767
|
const pending = shellAuthorizationInFlight.get(cacheKey);
|
|
5315
5768
|
if (pending) return pending;
|
|
5316
|
-
const request = authorize(scopes, spaceId,
|
|
5769
|
+
const request = authorize(scopes, spaceId, consent === "host" ? {
|
|
5770
|
+
silent: true,
|
|
5771
|
+
consent: "host"
|
|
5772
|
+
} : { silent: true });
|
|
5317
5773
|
shellAuthorizationInFlight.set(cacheKey, request);
|
|
5318
5774
|
try {
|
|
5319
5775
|
const result = await request;
|
|
@@ -5326,6 +5782,20 @@ function createAppBridgeCore(config) {
|
|
|
5326
5782
|
shellAuthorizationInFlight.delete(cacheKey);
|
|
5327
5783
|
}
|
|
5328
5784
|
}
|
|
5785
|
+
/** Trusted Apps get Host consent; others may only renew read-only grants. */
|
|
5786
|
+
async function shellConsentFor(scopes, spaceId) {
|
|
5787
|
+
if (!scopes.every(isAppHostConsentScope)) return null;
|
|
5788
|
+
if (await isTrustedIn(spaceId)) return "host";
|
|
5789
|
+
return scopes.every(isAppSilentShellScope) ? "renew" : null;
|
|
5790
|
+
}
|
|
5791
|
+
async function isTrustedIn(spaceId) {
|
|
5792
|
+
if (app.spaceId === spaceId) return true;
|
|
5793
|
+
try {
|
|
5794
|
+
return await config.isInstalledIn?.(spaceId) === true;
|
|
5795
|
+
} catch {
|
|
5796
|
+
return false;
|
|
5797
|
+
}
|
|
5798
|
+
}
|
|
5329
5799
|
/**
|
|
5330
5800
|
* Reads the Shell Space supplied by the current Host. Invocation context is
|
|
5331
5801
|
* deliberately excluded: an App may be opened from one Space while the Shell
|
|
@@ -5789,9 +6259,11 @@ function createAppBridgeCore(config) {
|
|
|
5789
6259
|
return;
|
|
5790
6260
|
}
|
|
5791
6261
|
const shellSpace = resolveShellSpace();
|
|
5792
|
-
const shellTargetId = spaceId
|
|
5793
|
-
|
|
5794
|
-
|
|
6262
|
+
const shellTargetId = !alwaysAsk && !selectSpace && shellSpace && (!spaceId || spaceId === shellSpace.id) ? shellSpace.id : null;
|
|
6263
|
+
const shellConsent = shellTargetId ? await shellConsentFor(scopes, shellTargetId) : null;
|
|
6264
|
+
if (state.pendingAuth !== reserved) return;
|
|
6265
|
+
if (shellConsent && shellTargetId) try {
|
|
6266
|
+
const result = await authorizeShellSilently(scopes, shellTargetId, shellConsent);
|
|
5795
6267
|
if (state.pendingAuth !== reserved) return;
|
|
5796
6268
|
setGrantedAppScopes(await getViewerUuid(), app.id, result.scopes, result.spaceId);
|
|
5797
6269
|
replyPendingAuth(reserved, authorizeResult(result.token, result.spaceId, shellSpace?.name ?? null));
|
|
@@ -6044,6 +6516,213 @@ function createAppBridgeCore(config) {
|
|
|
6044
6516
|
};
|
|
6045
6517
|
}
|
|
6046
6518
|
//#endregion
|
|
6519
|
+
//#region src/generation-blocks.ts
|
|
6520
|
+
/** Tolerant readers for generation payloads, shared by every task projection. */
|
|
6521
|
+
const EXCERPT_LIMIT = 240;
|
|
6522
|
+
function record(value) {
|
|
6523
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
6524
|
+
}
|
|
6525
|
+
function cleanExcerpt(value, limit = EXCERPT_LIMIT) {
|
|
6526
|
+
if (typeof value !== "string") return void 0;
|
|
6527
|
+
const clean = value.replace(/\s+/g, " ").trim();
|
|
6528
|
+
if (!clean) return void 0;
|
|
6529
|
+
return clean.length > limit ? `${clean.slice(0, limit - 3).trimEnd()}...` : clean;
|
|
6530
|
+
}
|
|
6531
|
+
function blockText(block) {
|
|
6532
|
+
return cleanExcerpt(block.text ?? block.content ?? block.value);
|
|
6533
|
+
}
|
|
6534
|
+
function blockUrl(block) {
|
|
6535
|
+
const source = record(block.source);
|
|
6536
|
+
return normalizeBoardRemoteUrl(source?.url ?? source?.src ?? block.url ?? block.src);
|
|
6537
|
+
}
|
|
6538
|
+
function blockMimeType(block) {
|
|
6539
|
+
const source = record(block.source);
|
|
6540
|
+
const value = source?.mediaType ?? source?.media_type ?? source?.mimeType ?? block.mediaType ?? block.media_type ?? block.mimeType;
|
|
6541
|
+
return typeof value === "string" ? value : void 0;
|
|
6542
|
+
}
|
|
6543
|
+
function positiveNumber(value) {
|
|
6544
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
6545
|
+
}
|
|
6546
|
+
function blockNaturalSize(block) {
|
|
6547
|
+
const source = record(block.source);
|
|
6548
|
+
const naturalWidth = positiveNumber(source?.width ?? source?.naturalWidth ?? block.width ?? block.naturalWidth);
|
|
6549
|
+
const naturalHeight = positiveNumber(source?.height ?? source?.naturalHeight ?? block.height ?? block.naturalHeight);
|
|
6550
|
+
return {
|
|
6551
|
+
...naturalWidth ? { naturalWidth } : {},
|
|
6552
|
+
...naturalHeight ? { naturalHeight } : {}
|
|
6553
|
+
};
|
|
6554
|
+
}
|
|
6555
|
+
function contentBlocks(value) {
|
|
6556
|
+
return Array.isArray(value) ? value.filter((item) => record(item)) : [];
|
|
6557
|
+
}
|
|
6558
|
+
function taskData(run) {
|
|
6559
|
+
const payload = record(run.payload);
|
|
6560
|
+
return record(payload?.data) ?? payload;
|
|
6561
|
+
}
|
|
6562
|
+
function generationOutput(run) {
|
|
6563
|
+
return contentBlocks(record(run.result)?.output);
|
|
6564
|
+
}
|
|
6565
|
+
function generationPrompt(run) {
|
|
6566
|
+
for (const block of contentBlocks(taskData(run)?.content)) {
|
|
6567
|
+
const text = blockText(block);
|
|
6568
|
+
if (text) return text;
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
function blockMeta(block) {
|
|
6572
|
+
return record(block.meta);
|
|
6573
|
+
}
|
|
6574
|
+
function blockIdentity(block) {
|
|
6575
|
+
const meta = blockMeta(block);
|
|
6576
|
+
const value = meta?.id ?? meta?.clip_id ?? meta?.clipId ?? block.id ?? block.clip_id ?? block.clipId;
|
|
6577
|
+
if (typeof value !== "string" && typeof value !== "number") return void 0;
|
|
6578
|
+
return cleanExcerpt(String(value), 220);
|
|
6579
|
+
}
|
|
6580
|
+
function blockTitle(block) {
|
|
6581
|
+
return cleanExcerpt(blockMeta(block)?.title ?? block.title ?? block.name, 240);
|
|
6582
|
+
}
|
|
6583
|
+
function blockDurationMs(block) {
|
|
6584
|
+
const source = record(block.source);
|
|
6585
|
+
const meta = blockMeta(block);
|
|
6586
|
+
const milliseconds = positiveNumber(source?.durationMs ?? meta?.durationMs ?? block.durationMs);
|
|
6587
|
+
if (milliseconds) return Math.round(milliseconds);
|
|
6588
|
+
const seconds = positiveNumber(source?.duration ?? meta?.duration ?? block.duration);
|
|
6589
|
+
return seconds ? Math.round(seconds * 1e3) : void 0;
|
|
6590
|
+
}
|
|
6591
|
+
function blockPreviewUrl(block) {
|
|
6592
|
+
const source = record(block.source);
|
|
6593
|
+
return normalizeBoardRemoteUrl(source?.poster ?? source?.thumbnail ?? source?.previewUrl ?? block.poster ?? block.thumbnail ?? block.previewUrl);
|
|
6594
|
+
}
|
|
6595
|
+
/**
|
|
6596
|
+
* Image roles that depict playable media, by the media types they may cover;
|
|
6597
|
+
* `last_frame` stays a result of its own.
|
|
6598
|
+
*/
|
|
6599
|
+
const COVER_ROLES = /* @__PURE__ */ new Map([
|
|
6600
|
+
["first_frame", /* @__PURE__ */ new Set(["video"])],
|
|
6601
|
+
["cover", /* @__PURE__ */ new Set(["video", "audio"])],
|
|
6602
|
+
["poster", /* @__PURE__ */ new Set(["video", "audio"])],
|
|
6603
|
+
["thumbnail", /* @__PURE__ */ new Set(["video", "audio"])]
|
|
6604
|
+
]);
|
|
6605
|
+
function isPlayable(block) {
|
|
6606
|
+
return block.type === "video" || block.type === "audio";
|
|
6607
|
+
}
|
|
6608
|
+
/**
|
|
6609
|
+
* Pair playable media with its cover image, returning media index → cover
|
|
6610
|
+
* index. An image sharing the provider id wins (music tracks and their art,
|
|
6611
|
+
* shared by every media of that id); otherwise cover-role images pair in
|
|
6612
|
+
* order with remaining media their role fits (a video and its `first_frame`).
|
|
6613
|
+
* Covers need a remote URL, so an inline image is never folded away.
|
|
6614
|
+
*/
|
|
6615
|
+
function generationCovers(blocks) {
|
|
6616
|
+
const covers = /* @__PURE__ */ new Map();
|
|
6617
|
+
const isCover = (block) => block.type === "image" && blockUrl(block) !== void 0 && blockMeta(block)?.role !== "last_frame";
|
|
6618
|
+
blocks.forEach((block, index) => {
|
|
6619
|
+
const id = blockIdentity(block);
|
|
6620
|
+
if (!isPlayable(block) || id === void 0) return;
|
|
6621
|
+
const cover = blocks.findIndex((candidate) => isCover(candidate) && blockIdentity(candidate) === id);
|
|
6622
|
+
if (cover >= 0) covers.set(index, cover);
|
|
6623
|
+
});
|
|
6624
|
+
const paired = new Set(covers.values());
|
|
6625
|
+
const roleCovers = blocks.flatMap((block, index) => {
|
|
6626
|
+
const role = blockMeta(block)?.role;
|
|
6627
|
+
const types = typeof role === "string" ? COVER_ROLES.get(role) : void 0;
|
|
6628
|
+
return isCover(block) && !paired.has(index) && types ? [{
|
|
6629
|
+
index,
|
|
6630
|
+
types
|
|
6631
|
+
}] : [];
|
|
6632
|
+
});
|
|
6633
|
+
blocks.forEach((block, index) => {
|
|
6634
|
+
if (!isPlayable(block) || covers.has(index)) return;
|
|
6635
|
+
const at = roleCovers.findIndex(({ types }) => types.has(String(block.type)));
|
|
6636
|
+
const [cover] = at < 0 ? [] : roleCovers.splice(at, 1);
|
|
6637
|
+
if (cover) covers.set(index, cover.index);
|
|
6638
|
+
});
|
|
6639
|
+
return covers;
|
|
6640
|
+
}
|
|
6641
|
+
//#endregion
|
|
6642
|
+
//#region src/generation-task.ts
|
|
6643
|
+
const INLINE_KEYS = [
|
|
6644
|
+
"data",
|
|
6645
|
+
"base64",
|
|
6646
|
+
"contentBase64"
|
|
6647
|
+
];
|
|
6648
|
+
function isDeferred(block) {
|
|
6649
|
+
return block.deferredBase64 === true || record(block.source)?.deferredBase64 === true;
|
|
6650
|
+
}
|
|
6651
|
+
const MEDIA_TYPE_PATTERN = /^(image|video|audio)\/[\w.+-]+$/;
|
|
6652
|
+
const DEFAULT_MEDIA_TYPES = {
|
|
6653
|
+
image: "image/png",
|
|
6654
|
+
video: "video/mp4",
|
|
6655
|
+
audio: "audio/mpeg"
|
|
6656
|
+
};
|
|
6657
|
+
function outputType(value) {
|
|
6658
|
+
return value === "image" || value === "video" || value === "audio" || value === "text" ? value : null;
|
|
6659
|
+
}
|
|
6660
|
+
/** Covers fold into the media they depict instead of listing as images. */
|
|
6661
|
+
function projectOutputs(run) {
|
|
6662
|
+
const blocks = generationOutput(run);
|
|
6663
|
+
const covers = generationCovers(blocks);
|
|
6664
|
+
const coverIndexes = new Set(covers.values());
|
|
6665
|
+
const coverUrl = (index) => {
|
|
6666
|
+
const cover = covers.get(index);
|
|
6667
|
+
return cover === void 0 ? void 0 : blockUrl(blocks[cover] ?? {});
|
|
6668
|
+
};
|
|
6669
|
+
return blocks.flatMap((block, index) => {
|
|
6670
|
+
const type = outputType(block.type);
|
|
6671
|
+
if (!type || coverIndexes.has(index)) return [];
|
|
6672
|
+
const size = blockNaturalSize(block);
|
|
6673
|
+
const text = type === "text" ? blockText(block) ?? null : null;
|
|
6674
|
+
if (type === "text" && !text) return [];
|
|
6675
|
+
return [{
|
|
6676
|
+
index,
|
|
6677
|
+
type,
|
|
6678
|
+
url: type === "text" ? null : blockUrl(block) ?? null,
|
|
6679
|
+
previewUrl: blockPreviewUrl(block) ?? coverUrl(index) ?? null,
|
|
6680
|
+
title: blockTitle(block) ?? null,
|
|
6681
|
+
mimeType: blockMimeType(block) ?? null,
|
|
6682
|
+
text,
|
|
6683
|
+
width: size.naturalWidth ?? null,
|
|
6684
|
+
height: size.naturalHeight ?? null,
|
|
6685
|
+
durationMs: blockDurationMs(block) ?? null,
|
|
6686
|
+
deferred: type !== "text" && isDeferred(block)
|
|
6687
|
+
}];
|
|
6688
|
+
});
|
|
6689
|
+
}
|
|
6690
|
+
function toGenerationTaskView(run) {
|
|
6691
|
+
const data = taskData(run);
|
|
6692
|
+
const result = record(run.result);
|
|
6693
|
+
const model = data?.model ?? result?.model;
|
|
6694
|
+
return {
|
|
6695
|
+
id: run.id,
|
|
6696
|
+
status: run.status,
|
|
6697
|
+
spaceId: run.spaceId,
|
|
6698
|
+
sessionId: run.sessionId,
|
|
6699
|
+
turnId: run.turnId,
|
|
6700
|
+
model: typeof model === "string" && model ? model : null,
|
|
6701
|
+
prompt: generationPrompt(run) ?? null,
|
|
6702
|
+
errorMessage: run.errorMessage,
|
|
6703
|
+
outputs: run.status === "completed" ? projectOutputs(run) : [],
|
|
6704
|
+
createdAt: run.createdAt,
|
|
6705
|
+
startedAt: run.startedAt,
|
|
6706
|
+
finishedAt: run.finishedAt,
|
|
6707
|
+
updatedAt: run.updatedAt
|
|
6708
|
+
};
|
|
6709
|
+
}
|
|
6710
|
+
function isActiveGenerationTask(task) {
|
|
6711
|
+
return task.status === "pending" || task.status === "running";
|
|
6712
|
+
}
|
|
6713
|
+
/** Playable source of an output: its URL, or a data URL for inline payloads. */
|
|
6714
|
+
function generationOutputSource(result, outputIndex) {
|
|
6715
|
+
const block = contentBlocks(record(result)?.output)[outputIndex];
|
|
6716
|
+
if (!block) return null;
|
|
6717
|
+
const url = blockUrl(block);
|
|
6718
|
+
if (url) return url;
|
|
6719
|
+
const source = record(block.source);
|
|
6720
|
+
const data = INLINE_KEYS.map((key) => source?.[key] ?? block[key]).find((value) => typeof value === "string" && value !== "");
|
|
6721
|
+
if (!data) return null;
|
|
6722
|
+
const declared = blockMimeType(block);
|
|
6723
|
+
return `data:${declared && MEDIA_TYPE_PATTERN.test(declared) ? declared : DEFAULT_MEDIA_TYPES[String(block.type)] ?? "application/octet-stream"};base64,${data}`;
|
|
6724
|
+
}
|
|
6725
|
+
//#endregion
|
|
6047
6726
|
//#region src/board/animation.ts
|
|
6048
6727
|
function track(input) {
|
|
6049
6728
|
return BoardTrackSchema.parse(input);
|
|
@@ -6289,4 +6968,4 @@ function createBoardExtensionRegistry() {
|
|
|
6289
6968
|
}
|
|
6290
6969
|
const BOARD_CHANNELS = BOARD_ANIMATION_CHANNELS;
|
|
6291
6970
|
//#endregion
|
|
6292
|
-
export { APP_COMPOSER_CHIP_CONTENT_MAX_BYTES, APP_COMPOSER_CHIP_KEY_MAX_LENGTH, APP_COMPOSER_CHIP_LABEL_MAX_LENGTH, APP_SURFACE_READY_TIMEOUT_MS, APP_SURFACE_REQUEST_TIMEOUT_MS, AppCommerceApi, AppRealtimeApi, AppRefParseError, AppRoom, AppRuntimeApi, AppRuntimeApi as WorkRuntimeApi, AppRuntimeError, AppSurfaceApi, AppsApi, BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_ANIMATION_CHANNEL_CAPABILITIES, BOARD_CHANNELS, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BillingApi, BoardAnimationSpecSchema, BoardAuthoringItemSchema, BoardClient, BoardCompositionInputSchema, BoardCompositionSchema, BoardDealParamsSchema, BoardEffectInputSchema, BoardEffectSchema, BoardExtensionRegistry, BoardItemPatchSchema, BoardPlaybackPolicySchema, BoardSemanticCommandSchema, COHUB_ENVIRONMENTS, COHUB_SOURCE_HEADER, COHUB_SOURCE_HEADER_NAMES, CohubClient, CohubHttpClient, DEFAULT_BOARD_LIMITS, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS, DESKTOP_COMMAND_MAX_TIMEOUT_MS, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES, DESKTOP_COMMAND_PENDING_TTL_SECONDS, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS, DESKTOP_COMMAND_VERSION, DesktopCommandsApi, FEATURE_NOT_ENTITLED_ERROR_CODE, GenerationPolicyError, HttpError, NATIVE_SYNC_SOURCE, OriginBrokerTransport, PERMISSIONS, ParentBridgeTransport, PopupBrokerTransport, REQUEST_SOURCE_VIA_MAX_LENGTH, RUNTIME_ARCHIVE_SEGMENT_BYTES, RUNTIME_MAX_FRAME_BYTES, RUNTIME_PROTOCOL_VERSION, RUNTIME_RECOVERY_BATCH_SIZE, ReferencesApi, ReferralsApi, SessionGenerationStreamClient, SessionPatchReducer, SpacePublicFilesApi, SpaceWebhooksApi, USER_LEVEL_PERMISSIONS, UiCommandsApi, UsersApi, VoiceApi, VoiceInputClient, WebsocketClient, WorkCommerceApi, WorkRealtimeApi, WorkRefParseError, WorkRoom, WorkSurfaceApi, assertGenerationRequestAllowedByPolicy, attachAppEmbed, buildAppSurfaceRequest, buildSpaceInvitePath, buildSpacePath, clearGrantedAppScopes, compileComposition, composition, contextToPiMessages, createAppBridgeCore, createAppBridgeCore as createWorkBridgeCore, createAppRuntime, createAppRuntime as createWorkRuntime, createBoardExtensionRegistry, createCohubClient, createHttpClient, createOriginAppResolver, createSessionGenerationStreamClient, createSessionPatchReducer, createSlugAppIdResolver, createSlugAppIdResolver as createSlugWorkIdResolver, createVoiceInputClient, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, extractBillingPayload, filterDiscoverableGenerationModels, filterGenerationDeclarationsByPolicy, filterSpacePickerItems, findGenerationModelPolicy, fingerprintProjectionTurns, formatAppRef, formatWorkRef, getAllowedGenerationModelIds, getCohubContext, harnessArchiveIndexSchema, hasGrantedAppScopes, hasRequestSourceIdentity, isAppId, isBillingAccessBlockedCode, isBillingAccessBlockedError, isDesktopCallMethod, isFeatureNotEntitledError, isGenerationModelHidden, isHttpErrorCode, isLocalHarness, isNativeClientTurn, isProjectionCompaction, isRequestSourceClientId, isRequestSourceEmpty, isRequestSourceUuid, isTerminalDesktopCommandStatus, isUserLevelPermission, isUuid, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, nativeTurnCompleteSchema, nativeTurnProgressSchema,
|
|
6971
|
+
export { APP_APPEARANCE_TOKENS, APP_COMPOSER_CHIP_CONTENT_MAX_BYTES, APP_COMPOSER_CHIP_KEY_MAX_LENGTH, APP_COMPOSER_CHIP_LABEL_MAX_LENGTH, APP_SURFACE_READY_TIMEOUT_MS, APP_SURFACE_REQUEST_TIMEOUT_MS, AppCommerceApi, AppRealtimeApi, AppRefParseError, AppRoom, AppRuntimeApi, AppRuntimeApi as WorkRuntimeApi, AppRuntimeError, AppSurfaceApi, AppWindowApi, AppsApi, BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_ANIMATION_CHANNEL_CAPABILITIES, BOARD_CHANNELS, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BillingApi, BoardAnimationSpecSchema, BoardAuthoringItemSchema, BoardClient, BoardCompositionInputSchema, BoardCompositionSchema, BoardDealParamsSchema, BoardEffectInputSchema, BoardEffectSchema, BoardExtensionRegistry, BoardItemPatchSchema, BoardPlaybackPolicySchema, BoardSemanticCommandSchema, COHUB_ENVIRONMENTS, COHUB_SOURCE_HEADER, COHUB_SOURCE_HEADER_NAMES, CohubClient, CohubHttpClient, DEFAULT_BOARD_LIMITS, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS, DESKTOP_COMMAND_MAX_TIMEOUT_MS, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES, DESKTOP_COMMAND_PENDING_TTL_SECONDS, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS, DESKTOP_COMMAND_VERSION, DesktopCommandsApi, FEATURE_NOT_ENTITLED_ERROR_CODE, GenerationPolicyError, HttpError, NATIVE_INGEST_MAX_TURNS, NATIVE_SYNC_SOURCE, OriginBrokerTransport, PERMISSIONS, ParentBridgeTransport, PopupBrokerTransport, REQUEST_SOURCE_VIA_MAX_LENGTH, RUNTIME_ARCHIVE_SEGMENT_BYTES, RUNTIME_MAX_FRAME_BYTES, RUNTIME_PROTOCOL_VERSION, RUNTIME_RECOVERY_BATCH_SIZE, ReferencesApi, ReferralsApi, SETTLED_TURN_STATUSES, SessionGenerationStreamClient, SessionPatchReducer, SpacePublicFilesApi, SpaceWebhooksApi, USER_LEVEL_PERMISSIONS, UiCommandsApi, UsersApi, VoiceApi, VoiceInputClient, WebsocketClient, WorkCommerceApi, WorkRealtimeApi, WorkRefParseError, WorkRoom, WorkSurfaceApi, appAppearanceVar, applyAppAppearance, assertGenerationRequestAllowedByPolicy, attachAppEmbed, buildAppSurfaceRequest, buildSpaceInvitePath, buildSpacePath, clearGrantedAppScopes, compileComposition, composition, contextToPiMessages, createAppBridgeCore, createAppBridgeCore as createWorkBridgeCore, createAppRuntime, createAppRuntime as createWorkRuntime, createBoardExtensionRegistry, createCohubClient, createHttpClient, createOriginAppResolver, createSessionGenerationStreamClient, createSessionPatchReducer, createSlugAppIdResolver, createSlugAppIdResolver as createSlugWorkIdResolver, createVoiceInputClient, createWebsocketClient, decodeGenerationPolicy, encodeGenerationPolicy, extractBillingPayload, filterDiscoverableGenerationModels, filterGenerationDeclarationsByPolicy, filterSpacePickerItems, findGenerationModelPolicy, fingerprintProjectionTurns, formatAppRef, formatWorkRef, generationOutputSource, getAllowedGenerationModelIds, getCohubContext, harnessArchiveIndexSchema, hasGrantedAppScopes, hasRequestSourceIdentity, isActiveGenerationTask, isAppId, isBillingAccessBlockedCode, isBillingAccessBlockedError, isDesktopCallMethod, isFeatureNotEntitledError, isGenerationModelHidden, isHttpErrorCode, isLocalHarness, isNativeClientTurn, isProjectionCompaction, isRequestSourceClientId, isRequestSourceEmpty, isRequestSourceUuid, isTerminalDesktopCommandStatus, isUserLevelPermission, isUuid, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, nativeIngestTurnSchema, nativeRuntimeEventSchema, nativeTurnCompleteSchema, nativeTurnProgressSchema, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeSpacePickerQuery, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, orderSpacePickerItems, parseAppRef, parseAppSurfaceReady, parseAppSurfaceResponse, parseAssistantMessageCommit, parseBoardCompositionInput, parseBoardEffectInput, parseBoardPlaybackPolicy, parseDesktopCommand, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseWorkRef, proceduralClip, projectNativeMessageMeta, projectNativeSession, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveAppTransport, resolveAppTransport as resolveWorkTransport, resolveCohubEnvironment, resolveExecutionAppId, resolveExecutionToken, resolveHarness, resolveOpenSurface, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebBaseUrl, resolveWebsocketUrl, runtimeCommandSchema, runtimeEventSchema, runtimeNativeStopSchema, runtimeReadySchema, sampleCompositionTracks, sampleEasing, sampleTrack, sanitizeAccessToken, scopeListHasPermission, selectRuntimeContextMessages, selectSpacePickerItems, serializeProjection, serializeProjectionRecords, setGrantedAppScopes, toGenerationTaskView, track, trimProjectionTurnsToCompaction, validateArchiveBoundary };
|