@neta-art/cohub 6.0.0 → 7.0.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.
Files changed (55) hide show
  1. package/README.md +6 -5
  2. package/dist/board/animation.d.ts +2 -1
  3. package/dist/board/animation.js +0 -1
  4. package/dist/board/core/connections.js +4 -4
  5. package/dist/board/core/export-plan.js +1 -1
  6. package/dist/board/core/shape-types.js +0 -1
  7. package/dist/board/index.d.ts +6 -5
  8. package/dist/board/index.js +7 -7
  9. package/dist/board/mutation.d.ts +2 -11
  10. package/dist/board/mutation.js +2 -56
  11. package/dist/board/render/renderers/text-card-renderer.js +1 -1
  12. package/dist/board/semantic-document.d.ts +30 -0
  13. package/dist/board/semantic-document.js +271 -0
  14. package/dist/board/semantic-mutation.d.ts +10 -0
  15. package/dist/board/semantic-mutation.js +203 -0
  16. package/dist/chunks/http.d.ts +15 -94
  17. package/dist/chunks/http.js +248 -1588
  18. package/dist/chunks/transport.js +1 -1
  19. package/dist/chunks/websocket.d.ts +3646 -3139
  20. package/dist/chunks/websocket.js +1 -1
  21. package/dist/http.d.ts +3 -3
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +1045 -195
  24. package/dist/protocol/dist/board-authoring.d.ts +1305 -1
  25. package/dist/protocol/dist/board-authoring.js +80 -6
  26. package/dist/protocol/dist/board-codec.d.ts +2 -2
  27. package/dist/protocol/dist/board-codec.js +19 -4
  28. package/dist/protocol/dist/board-composition.d.ts +126 -1
  29. package/dist/protocol/dist/board-composition.js +1 -9
  30. package/dist/protocol/dist/board-connection.d.ts +16 -16
  31. package/dist/protocol/dist/board-connection.js +16 -16
  32. package/dist/protocol/dist/board-document.d.ts +34 -3
  33. package/dist/protocol/dist/board-document.js +3 -1
  34. package/dist/protocol/dist/board-effect.d.ts +94 -0
  35. package/dist/protocol/dist/board-effect.js +53 -0
  36. package/dist/protocol/dist/board-json.js +16 -0
  37. package/dist/protocol/dist/board.d.ts +34 -164
  38. package/dist/protocol/dist/board.js +44 -45
  39. package/dist/protocol/dist/index.d.ts +7 -7
  40. package/dist/types.d.ts +3 -1
  41. package/package.json +1 -2
  42. package/dist/board/codec.d.ts +0 -27
  43. package/dist/board/codec.js +0 -277
  44. package/dist/protocol/dist/board-content.js +0 -26
  45. package/dist/protocol/dist/board-upgrade.d.ts +0 -1
  46. package/dist/protocol/dist/board-upgrade.js +0 -2
  47. package/dist/protocol/dist/identifiers.js +0 -10
  48. package/dist/protocol/dist/index.js +0 -19
  49. package/dist/protocol/dist/provenance.js +0 -15
  50. package/dist/protocol/dist/public-identifiers.js +0 -38
  51. package/dist/protocol/dist/realtime/board-awareness.js +0 -119
  52. package/dist/protocol/dist/ui-command.js +0 -2
  53. package/dist/protocol/dist/work-promotion-stats.js +0 -11
  54. package/dist/protocol/dist/work-surface.js +0 -2
  55. package/dist/protocol/dist/work-view-stats.js +0 -3
package/dist/index.js CHANGED
@@ -1,9 +1,880 @@
1
- import { $ as BOARD_GEO_KINDS, A as buildWorkComposerChipSet, B as UI_COMMAND_MAX_TIMEOUT_MS, C as ensureRealtimeConnected, Ct as SkillsApi, D as WORK_SURFACE_READY_TIMEOUT_MS, Dt as CronJobsApi, E as WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH, Et as GenerationsApi, F as parseWorkComposerChipSet, G as UI_COMMAND_VERSION, H as UI_COMMAND_PENDING_TTL_SECONDS, I as parseWorkSurfaceReady, J as parseUiCommand, K as isTerminalUiCommandStatus, L as parseWorkSurfaceRequest, M as buildWorkSurfaceRequest, N as buildWorkSurfaceResponse, O as WORK_SURFACE_REQUEST_TIMEOUT_MS, Ot as ChannelsApi, P as parseWorkComposerChipClear, Q as BOARD_COLOR_IDS, R as parseWorkSurfaceResponse, S as createSessionPatchReducer, St as PublicAssetsApi, T as WORK_COMPOSER_CHIP_KEY_MAX_LENGTH, Tt as ModelsApi, U as UI_COMMAND_SETTLEMENT_GRACE_SECONDS, V as UI_COMMAND_PAYLOAD_MAX_BYTES, W as UI_COMMAND_TERMINAL_TTL_SECONDS, X as parseUsername, Y as parseSpaceSlug, Z as BoardAwarenessClientPayloadSchema, _ as buildSpacePath, _t as BOARD_BUILTIN_CAPABILITIES, a as ReferralsApi, at as BoardEffectSchema, b as parseAssistantMessageCommit, bt as ReferencesApi, c as UiCommandsApi, ct as BoardAuthoringItemSchema, d as BoardTransactionError, dt as BOARD_ANIMATION_CHANNEL_CAPABILITIES, et as BOARD_NATIVE_NODE_TYPES, f as SpaceClient, ft as BoardCompositionInputSchema, g as buildSpaceInvitePath, gt as parseBoardCompositionInput, h as PublicInviteApi, ht as BoardTrackSchema, i as WorksApi, it as validateBuiltinBoardClip, j as buildWorkSurfaceReady, k as buildWorkComposerChipClear, l as TasksApi, lt as BoardItemPatchSchema, m as SpacesApi, mt as BoardProceduralClipSchema, n as createHttpClient, nt as validateBoardNodeInput, o as UsersApi, ot as BoardPlaybackPolicySchema, p as SpacePublicFilesApi, pt as BoardCompositionSchema, q as isUiSurfaceMethod, r as WorkCommerceApi, rt as estimateBuiltinBoardClipCost, s as UserApi, st as parseBoardPlaybackPolicy, t as CohubHttpClient, tt as BOARD_NODE_CONTRACT, u as BoardClient, ut as BOARD_ANIMATION_CHANNELS, v as SessionGenerationStreamClient, vt as DEFAULT_BOARD_RENDER_LIMITS, w as WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES, wt as PromptsApi, x as SessionPatchReducer, xt as SearchApi, y as createSessionGenerationStreamClient, yt as SessionAccessApi, z as UI_COMMAND_DEFAULT_TIMEOUT_MS } from "./chunks/http.js";
2
- import { _ as requestSourceToHeaders, a as sanitizeAccessToken, b as REALTIME_DOMAINS, c as REQUEST_SOURCE_VIA_MAX_LENGTH, d as isRequestSourceEmpty, f as isRequestSourceUuid, g as readRequestSourceFromEnv, h as parseRequestSourceFromHeaders, i as matchesUnauthorizedErrorToken, l as hasRequestSourceIdentity, m as normalizeRequestSource, n as HttpTransport, o as COHUB_SOURCE_HEADER, p as mergeRequestSourceIntoMeta, r as joinApiUrl, s as COHUB_SOURCE_HEADER_NAMES, t as HttpError, u as isRequestSourceClientId, v as resolveRequestSourceChannel, x as REALTIME_ROOM_EVENT_NAME_PATTERN, y as isUuid } from "./chunks/transport.js";
1
+ import { $ as SessionAccessApi, A as isTerminalUiCommandStatus, B as BOARD_ANIMATION_CHANNELS, C as UI_COMMAND_DEFAULT_TIMEOUT_MS, D as UI_COMMAND_SETTLEMENT_GRACE_SECONDS, E as UI_COMMAND_PENDING_TTL_SECONDS, F as BoardItemPatchSchema, G as BoardTrackSchema, H as BoardCompositionInputSchema, I as BoardSemanticMutationSchema, J as BOARD_ARROW_STROKE_SIZE, K as parseBoardCompositionInput, L as BoardEffectInputSchema, M as parseUiCommand, N as parseUiCommandId, O as UI_COMMAND_TERMINAL_TTL_SECONDS, P as BoardAuthoringItemSchema, Q as DEFAULT_BOARD_RENDER_LIMITS, R as BoardEffectSchema, S as ensureRealtimeConnected, T as UI_COMMAND_PAYLOAD_MAX_BYTES, U as BoardCompositionSchema, V as BOARD_ANIMATION_CHANNEL_CAPABILITIES, W as BoardProceduralClipSchema, X as BOARD_BUILTIN_CLIP_KINDS, Y as BOARD_BUILTIN_CAPABILITIES, Z as BOARD_BUILTIN_EFFECT_KINDS, _ as SessionGenerationStreamClient, a as ReferralsApi, at as ModelsApi, b as SessionPatchReducer, c as UiCommandsApi, ct as ChannelsApi, d as SpaceClient, et as ReferencesApi, f as SpacePublicFilesApi, g as buildSpacePath, h as buildSpaceInvitePath, i as WorksApi, it as PromptsApi, j as isUiSurfaceMethod, k as UI_COMMAND_VERSION, l as TasksApi, m as PublicInviteApi, n as createHttpClient, nt as PublicAssetsApi, o as UsersApi, ot as GenerationsApi, p as SpacesApi, q as BoardConnectionSchema, r as WorkCommerceApi, rt as SkillsApi, s as UserApi, st as CronJobsApi, t as CohubHttpClient, tt as SearchApi, u as BoardClient, v as createSessionGenerationStreamClient, w as UI_COMMAND_MAX_TIMEOUT_MS, x as createSessionPatchReducer, y as parseAssistantMessageCommit, z as parseBoardEffectInput } from "./chunks/http.js";
2
+ import { _ as requestSourceToHeaders, a as sanitizeAccessToken, b as REALTIME_ROOM_EVENT_NAME_PATTERN, c as REQUEST_SOURCE_VIA_MAX_LENGTH, d as isRequestSourceEmpty, f as isRequestSourceUuid, g as readRequestSourceFromEnv, h as parseRequestSourceFromHeaders, i as matchesUnauthorizedErrorToken, l as hasRequestSourceIdentity, m as normalizeRequestSource, n as HttpTransport, o as COHUB_SOURCE_HEADER, p as mergeRequestSourceIntoMeta, r as joinApiUrl, s as COHUB_SOURCE_HEADER_NAMES, t as HttpError, u as isRequestSourceClientId, v as resolveRequestSourceChannel, y as isUuid } from "./chunks/transport.js";
3
3
  import { a as resolveApiBaseUrl, c as resolveWebsocketUrl, i as normalizeWebsocketUrl, n as normalizeBaseUrl, o as resolveCohubEnvironment, r as normalizeVoiceInputWebsocketUrl, s as resolveVoiceInputWebsocketUrl, t as COHUB_ENVIRONMENTS } from "./chunks/environment.js";
4
4
  import { a as extractBillingPayload, c as isFeatureNotEntitledError, i as FEATURE_NOT_ENTITLED_ERROR_CODE, l as isHttpErrorCode, n as createWebsocketClient, o as isBillingAccessBlockedCode, r as BILLING_ACCESS_BLOCKED_ERROR_CODE, s as isBillingAccessBlockedError, t as WebsocketClient } from "./chunks/websocket.js";
5
5
  import { VoiceApi, VoiceInputClient, createVoiceInputClient } from "./voice-input.js";
6
6
  import { z } from "zod";
7
+ //#region ../protocol/dist/board.js
8
+ const BOARD_DOCUMENT_KIND = "cohub.board";
9
+ const BOARD_MANIFEST_KIND = "cohub.board.manifest";
10
+ const idSchema = z.string().min(1).max(160);
11
+ const jsonObjectSchema = z.record(z.string(), z.unknown());
12
+ const finiteSchema = z.number().finite();
13
+ z.object({
14
+ kind: z.literal(BOARD_MANIFEST_KIND),
15
+ version: z.literal(1),
16
+ boardId: z.string().uuid(),
17
+ title: z.string().min(1).max(255)
18
+ });
19
+ z.object({
20
+ centerX: finiteSchema,
21
+ centerY: finiteSchema,
22
+ zoom: finiteSchema.positive()
23
+ });
24
+ const BoardCameraFocusSchema = z.discriminatedUnion("type", [
25
+ z.object({
26
+ type: z.literal("rect"),
27
+ rect: z.object({
28
+ x: finiteSchema,
29
+ y: finiteSchema,
30
+ width: finiteSchema.positive(),
31
+ height: finiteSchema.positive()
32
+ })
33
+ }),
34
+ z.object({
35
+ type: z.literal("item"),
36
+ itemId: idSchema
37
+ }),
38
+ z.object({
39
+ type: z.literal("items"),
40
+ itemIds: z.array(idSchema).min(1).max(1e3)
41
+ }),
42
+ z.object({
43
+ type: z.literal("frame"),
44
+ frameId: idSchema
45
+ })
46
+ ]);
47
+ const BoardCameraFocusParamsSchema = z.object({
48
+ focus: BoardCameraFocusSchema,
49
+ fit: z.enum(["contain", "cover"]).default("contain"),
50
+ padding: finiteSchema.nonnegative().default(32),
51
+ minZoom: finiteSchema.positive().optional(),
52
+ maxZoom: finiteSchema.positive().optional()
53
+ }).superRefine((value, context) => {
54
+ if (value.minZoom !== void 0 && value.maxZoom !== void 0 && value.minZoom > value.maxZoom) context.addIssue({
55
+ code: "custom",
56
+ message: "minZoom must not exceed maxZoom",
57
+ path: ["minZoom"]
58
+ });
59
+ });
60
+ z.object({
61
+ nodeId: idSchema,
62
+ type: z.string().min(1).max(40),
63
+ parentId: idSchema.nullable(),
64
+ orderKey: z.string().max(4096).nullable(),
65
+ x: finiteSchema,
66
+ y: finiteSchema,
67
+ width: finiteSchema.positive(),
68
+ height: finiteSchema.positive(),
69
+ rotation: finiteSchema,
70
+ refKind: z.string().max(40).nullable(),
71
+ refPath: z.string().max(4096).nullable(),
72
+ refUrl: z.string().max(4096).nullable(),
73
+ view: jsonObjectSchema,
74
+ style: jsonObjectSchema,
75
+ data: jsonObjectSchema
76
+ });
77
+ const stripBoardServerFields = (value) => {
78
+ if (!value || typeof value !== "object" || Array.isArray(value)) return value;
79
+ const { boardId: _boardId, revision: _revision, ...input } = value;
80
+ return input;
81
+ };
82
+ const BoardCreateEffectInputSchema = z.preprocess(stripBoardServerFields, BoardEffectInputSchema);
83
+ const BoardCreateCompositionInputSchema = z.preprocess(stripBoardServerFields, BoardCompositionInputSchema);
84
+ const BoardCreateInputSchema = z.object({
85
+ path: z.string().min(1),
86
+ /** Reused by clients when board creation is interrupted and retried. */
87
+ mutationId: z.string().max(128).optional(),
88
+ title: z.string().min(1).max(255).optional(),
89
+ metadata: jsonObjectSchema.optional(),
90
+ items: z.array(BoardAuthoringItemSchema).max(5e4).optional(),
91
+ connections: z.array(BoardConnectionSchema).max(5e4).optional(),
92
+ effects: z.array(BoardCreateEffectInputSchema).max(5e4).optional(),
93
+ compositions: z.array(BoardCreateCompositionInputSchema).max(5e4).optional()
94
+ });
95
+ const jsonSchema$1 = (schema) => z.toJSONSchema(schema);
96
+ const authoringSchemaFactories = {
97
+ item: () => jsonSchema$1(BoardAuthoringItemSchema),
98
+ itemPatch: () => jsonSchema$1(BoardItemPatchSchema),
99
+ mutation: () => jsonSchema$1(BoardSemanticMutationSchema),
100
+ composition: () => jsonSchema$1(BoardCompositionInputSchema),
101
+ effect: () => jsonSchema$1(BoardEffectInputSchema),
102
+ create: () => jsonSchema$1(BoardCreateInputSchema)
103
+ };
104
+ /**
105
+ * JSON Schemas for the semantic authoring surface. Each property is enumerable
106
+ * for Object.keys/JSON.stringify, but generated only when that property is
107
+ * requested. This keeps protocol imports cheap while capabilities still returns
108
+ * the complete machine-readable schema object.
109
+ */
110
+ const BOARD_AUTHORING_SCHEMAS = {};
111
+ for (const key of Object.keys(authoringSchemaFactories)) {
112
+ let cached;
113
+ Object.defineProperty(BOARD_AUTHORING_SCHEMAS, key, {
114
+ enumerable: true,
115
+ configurable: false,
116
+ get() {
117
+ cached ??= authoringSchemaFactories[key]();
118
+ return cached;
119
+ }
120
+ });
121
+ }
122
+ z.object({
123
+ include: z.array(z.enum([
124
+ "nodes",
125
+ "connections",
126
+ "effects",
127
+ "compositions",
128
+ "playback"
129
+ ])).optional(),
130
+ nodeIds: z.array(idSchema).max(5e4).optional(),
131
+ connectionIds: z.array(idSchema).max(5e4).optional(),
132
+ effectIds: z.array(idSchema).max(5e4).optional(),
133
+ compositionIds: z.array(idSchema).max(5e4).optional(),
134
+ viewport: z.object({
135
+ x: finiteSchema,
136
+ y: finiteSchema,
137
+ width: finiteSchema.positive(),
138
+ height: finiteSchema.positive()
139
+ }).optional()
140
+ });
141
+ /** Persisted on `boards.metadata.playback`: how a Board plays when opened. */
142
+ const BoardPlaybackPolicySchema = z.object({
143
+ compositionId: idSchema,
144
+ /** Delay before the first local playback after opening the Board, in milliseconds. */
145
+ delayMs: finiteSchema.nonnegative().default(0)
146
+ });
147
+ function parseBoardPlaybackPolicy(metadata) {
148
+ const parsed = BoardPlaybackPolicySchema.safeParse(metadata.playback);
149
+ return parsed.success ? parsed.data : null;
150
+ }
151
+ z.discriminatedUnion("type", [
152
+ z.object({
153
+ commandId: idSchema,
154
+ type: z.literal("play"),
155
+ compositionId: idSchema,
156
+ position: finiteSchema.nonnegative().optional(),
157
+ timeScale: finiteSchema.positive().max(4).optional(),
158
+ shared: z.boolean().optional(),
159
+ seed: idSchema.optional()
160
+ }),
161
+ z.object({
162
+ commandId: idSchema,
163
+ type: z.literal("pause"),
164
+ playbackId: z.string().uuid()
165
+ }),
166
+ z.object({
167
+ commandId: idSchema,
168
+ type: z.literal("seek"),
169
+ playbackId: z.string().uuid(),
170
+ position: finiteSchema.nonnegative()
171
+ }),
172
+ z.object({
173
+ commandId: idSchema,
174
+ type: z.literal("stop"),
175
+ playbackId: z.string().uuid()
176
+ })
177
+ ]);
178
+ //#endregion
179
+ //#region ../protocol/dist/board-capability-registry.js
180
+ const CLIPS = new Set(BOARD_BUILTIN_CLIP_KINDS);
181
+ new Set(BOARD_BUILTIN_EFFECT_KINDS);
182
+ const record = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
183
+ const finite = (value) => typeof value === "number" && Number.isFinite(value);
184
+ function validateBuiltinBoardClip(clip, path = "clip") {
185
+ if (!CLIPS.has(clip.kind)) return [];
186
+ const errors = [];
187
+ const error = (message, suffix, coordinateSpace, code = "INVALID_BOARD_CLIP") => {
188
+ errors.push({
189
+ severity: "error",
190
+ code,
191
+ message,
192
+ path: `${path}.${suffix}`,
193
+ ...coordinateSpace ? { coordinateSpace } : {}
194
+ });
195
+ };
196
+ if ((clip.kind.startsWith("motion.") || clip.kind.startsWith("draw.") || clip.kind === "text.reveal" || clip.kind === "effects.trail") && clip.target.type !== "item") error(`${clip.kind} must target an item`, "target");
197
+ if (clip.kind.startsWith("camera.") && clip.target.type !== "camera") error(`${clip.kind} must target the camera`, "target");
198
+ if (clip.kind === "motion.path") {
199
+ const points = clip.params.points;
200
+ 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");
201
+ 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");
202
+ }
203
+ if (clip.kind === "effects.particles") {
204
+ const count = clip.params.count;
205
+ 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");
206
+ const bounds = clip.params.bounds;
207
+ 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");
208
+ }
209
+ if (clip.kind === "camera.focus") {
210
+ const parsed = BoardCameraFocusParamsSchema.safeParse(clip.params);
211
+ if (!parsed.success) error(parsed.error.issues[0]?.message ?? "invalid camera focus", "params", "world");
212
+ }
213
+ return errors;
214
+ }
215
+ function estimateBuiltinBoardClipCost(clip) {
216
+ switch (clip.kind) {
217
+ case "effects.particles": {
218
+ const count = Number.isSafeInteger(clip.params.count) ? Math.max(0, clip.params.count) : 0;
219
+ return {
220
+ particles: count,
221
+ vertices: count * 4,
222
+ dynamicVertices: count * 4,
223
+ drawCalls: 1,
224
+ bufferBytes: count * 48,
225
+ simulationSteps: count
226
+ };
227
+ }
228
+ case "effects.trail": return {
229
+ vertices: 32,
230
+ dynamicVertices: 32,
231
+ drawCalls: 1,
232
+ bufferBytes: 1024,
233
+ simulationSteps: 16
234
+ };
235
+ case "effects.impact":
236
+ case "effects.flash": return {
237
+ vertices: 64,
238
+ drawCalls: 1
239
+ };
240
+ case "draw.reveal":
241
+ case "draw.handwrite": return {
242
+ drawCalls: 1,
243
+ dynamicVertices: 1
244
+ };
245
+ case "motion.path": return { simulationSteps: Array.isArray(clip.params.points) ? clip.params.points.length : 0 };
246
+ default: return {};
247
+ }
248
+ }
249
+ //#endregion
250
+ //#region ../protocol/dist/board-url.js
251
+ const BOARD_REMOTE_URL_MAX_LENGTH = 4096;
252
+ function parseIpv4(host) {
253
+ const parts = host.split(".").map(Number);
254
+ return parts.length === 4 && parts.every((part) => Number.isInteger(part) && part >= 0 && part <= 255) ? parts : null;
255
+ }
256
+ function isBlockedIpv4(host) {
257
+ const parts = parseIpv4(host);
258
+ if (!parts) return false;
259
+ const [first, second, third] = parts;
260
+ if (first === 0 || first === 10 || first === 127) return true;
261
+ if (first === 100 && second >= 64 && second <= 127) return true;
262
+ if (first === 169 && second === 254) return true;
263
+ if (first === 172 && second >= 16 && second <= 31) return true;
264
+ if (first === 192 && second === 168) return true;
265
+ if (first === 192 && second === 0 && (third === 0 || third === 2)) return true;
266
+ if (first === 192 && second === 88 && third === 99) return true;
267
+ if (first === 198 && (second === 18 || second === 19)) return true;
268
+ if (first === 198 && second === 51 && third === 100) return true;
269
+ if (first === 203 && second === 0 && third === 113) return true;
270
+ return first >= 224;
271
+ }
272
+ function expandIpv6(host) {
273
+ const [head, tail, extra] = host.toLowerCase().split("::");
274
+ if (extra !== void 0) return null;
275
+ const headParts = head ? head.split(":").filter(Boolean) : [];
276
+ const tailParts = tail ? tail.split(":").filter(Boolean) : [];
277
+ const missing = 8 - headParts.length - tailParts.length;
278
+ if (missing < 0 || tail === void 0 && missing !== 0) return null;
279
+ const parts = [
280
+ ...headParts,
281
+ ...Array.from({ length: missing }, () => "0"),
282
+ ...tailParts
283
+ ];
284
+ if (parts.length !== 8 || parts.some((part) => !/^[0-9a-f]{1,4}$/.test(part))) return null;
285
+ return parts.map((part) => part.padStart(4, "0"));
286
+ }
287
+ function isBlockedIpv6(host) {
288
+ const parts = expandIpv6(host);
289
+ if (!parts) return true;
290
+ if (parts.every((part) => part === "0000")) return true;
291
+ if (parts.slice(0, 7).every((part) => part === "0000") && parts[7] === "0001") return true;
292
+ if (parts.slice(0, 5).every((part) => part === "0000") && parts[5] === "ffff") {
293
+ const high = Number.parseInt(parts[6] ?? "0", 16);
294
+ const low = Number.parseInt(parts[7] ?? "0", 16);
295
+ return isBlockedIpv4(`${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`);
296
+ }
297
+ if (parts.slice(0, 6).every((part) => part === "0000")) return true;
298
+ const first = Number.parseInt(parts[0] ?? "0", 16);
299
+ if ((first & 65024) === 64512) return true;
300
+ if ((first & 65472) === 65152 || (first & 65472) === 65216) return true;
301
+ if ((first & 65280) === 65280) return true;
302
+ return parts[0] === "2001" && parts[1] === "0db8";
303
+ }
304
+ function isPublicBoardRemoteAddress(value) {
305
+ const address = value.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
306
+ if (parseIpv4(address)) return !isBlockedIpv4(address);
307
+ return address.includes(":") && !isBlockedIpv6(address);
308
+ }
309
+ function isBlockedHost(hostname) {
310
+ const host = hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
311
+ if (host === "localhost" || host.endsWith(".localhost") || host.endsWith(".local") || host.endsWith(".internal")) return true;
312
+ if (parseIpv4(host) || host.includes(":")) return !isPublicBoardRemoteAddress(host);
313
+ return false;
314
+ }
315
+ /**
316
+ * Normalize a browser-loadable public HTTP(S) URL. This blocks explicit local
317
+ * addresses; any future server-side fetcher must additionally validate DNS
318
+ * resolution to defend against rebinding.
319
+ */
320
+ function normalizeBoardRemoteUrl(value) {
321
+ if (typeof value !== "string") return void 0;
322
+ const input = value.trim();
323
+ if (!input || input.length > 4096) return void 0;
324
+ try {
325
+ const url = new URL(input);
326
+ if (url.protocol !== "https:" && url.protocol !== "http:") return void 0;
327
+ if (url.username || url.password || isBlockedHost(url.hostname)) return;
328
+ const normalized = url.toString();
329
+ return normalized.length <= 4096 ? normalized : void 0;
330
+ } catch {
331
+ return;
332
+ }
333
+ }
334
+ const BoardRemoteUrlSchema = z.string().max(BOARD_REMOTE_URL_MAX_LENGTH).refine((value) => normalizeBoardRemoteUrl(value) !== void 0, { message: "URL must be a public HTTP(S) URL without credentials" });
335
+ //#endregion
336
+ //#region ../protocol/dist/board-document.js
337
+ const BoardFrameSchema = z.object({
338
+ x: z.number().finite(),
339
+ y: z.number().finite(),
340
+ width: z.number().finite().positive(),
341
+ height: z.number().finite().positive(),
342
+ rotation: z.number().finite().default(0)
343
+ });
344
+ /**
345
+ * The board camera. This is local UI state, not synced content: semantic ops
346
+ * (see diffBoardDocuments) never describe the viewport, and the editor holds
347
+ * the live camera separately from the persisted document. Here it only serves
348
+ * as an initial camera hint when a document is first loaded.
349
+ */
350
+ const BoardViewportSchema = z.object({
351
+ x: z.number().finite(),
352
+ y: z.number().finite(),
353
+ zoom: z.number().finite().min(.05).max(8)
354
+ });
355
+ const BoardAppearanceSchema = z.object({
356
+ theme: z.string().min(1).default("clean"),
357
+ background: z.object({
358
+ kind: z.enum([
359
+ "solid",
360
+ "dots",
361
+ "grid",
362
+ "image",
363
+ "shader",
364
+ "custom"
365
+ ]).default("dots"),
366
+ color: z.string().optional(),
367
+ imageUrl: BoardRemoteUrlSchema.optional(),
368
+ fit: z.enum([
369
+ "cover",
370
+ "contain",
371
+ "repeat"
372
+ ]).optional(),
373
+ position: z.enum([
374
+ "center",
375
+ "top",
376
+ "bottom",
377
+ "left",
378
+ "right"
379
+ ]).optional(),
380
+ opacity: z.number().finite().min(0).max(1).optional()
381
+ }).default({ kind: "solid" }),
382
+ grid: z.object({
383
+ visible: z.boolean().default(false),
384
+ size: z.number().finite().min(4).default(24),
385
+ opacity: z.number().finite().min(0).max(1).default(.12)
386
+ }).default({
387
+ visible: false,
388
+ size: 24,
389
+ opacity: .12
390
+ }),
391
+ mood: z.enum([
392
+ "clean",
393
+ "playful",
394
+ "arcane",
395
+ "cyber",
396
+ "natural"
397
+ ]).default("clean")
398
+ });
399
+ /** Optional visual chrome still carried by a few older shapes. */
400
+ const BoardItemStyleSchema = z.object({
401
+ variant: z.string().min(1).default("default"),
402
+ theme: z.string().min(1).optional(),
403
+ accentColor: z.string().optional(),
404
+ size: z.enum([
405
+ "sm",
406
+ "md",
407
+ "lg"
408
+ ]).default("md"),
409
+ emphasis: z.enum([
410
+ "normal",
411
+ "rare",
412
+ "epic",
413
+ "legendary"
414
+ ]).default("normal"),
415
+ effects: z.array(z.string().min(1)).default([])
416
+ });
417
+ const SpaceFileRefSchema = z.object({
418
+ kind: z.literal("space-file"),
419
+ path: z.string().min(1)
420
+ });
421
+ const BoardMediaSnapshotSchema = z.object({
422
+ title: z.string().optional(),
423
+ mimeType: z.string().optional(),
424
+ size: z.number().finite().nonnegative().optional(),
425
+ mtimeMs: z.number().finite().nonnegative().optional(),
426
+ /** Intrinsic pixel size once known. */
427
+ naturalWidth: z.number().finite().positive().optional(),
428
+ naturalHeight: z.number().finite().positive().optional()
429
+ });
430
+ const BoardItemBaseSchema = z.object({
431
+ id: z.string().min(1),
432
+ frame: BoardFrameSchema,
433
+ parentId: z.string().min(1).nullable().optional(),
434
+ /** When true the shape cannot be moved, resized, or deleted. */
435
+ locked: z.boolean().optional(),
436
+ style: BoardItemStyleSchema.optional(),
437
+ metadata: z.record(z.string(), z.unknown()).optional()
438
+ });
439
+ /** Freestanding text — no card chrome; its frame always follows the glyphs. */
440
+ const BoardTextItemSchema = BoardItemBaseSchema.extend({
441
+ type: z.literal("text"),
442
+ text: z.string().default(""),
443
+ color: z.string().min(1).default("neutral"),
444
+ fontSize: z.number().finite().min(2).max(512).default(24)
445
+ });
446
+ const BoardGeoItemSchema = BoardItemBaseSchema.extend({
447
+ type: z.literal("geo"),
448
+ geo: z.string().min(1).default("rectangle"),
449
+ text: z.string().default(""),
450
+ color: z.string().min(1).default("brand"),
451
+ fillOpacity: z.number().finite().min(0).max(1).default(0)
452
+ });
453
+ /** A raw freehand sample. Pressure defaults to 0.5 (mouse) when absent. */
454
+ const DrawPointSchema = z.object({
455
+ x: z.number().finite(),
456
+ y: z.number().finite(),
457
+ p: z.number().finite().min(0).max(1).default(.5)
458
+ });
459
+ /** A world-space point. */
460
+ const BoardPointSchema = z.object({
461
+ x: z.number().finite(),
462
+ y: z.number().finite()
463
+ });
464
+ const BoardDrawItemSchema = BoardItemBaseSchema.extend({
465
+ type: z.literal("draw"),
466
+ points: z.array(DrawPointSchema).default([]),
467
+ color: z.string().min(1).default("brand"),
468
+ size: z.number().finite().positive().default(4)
469
+ });
470
+ /**
471
+ * A free arrow — a standalone annotation stroke between two world points.
472
+ *
473
+ * Arrows do not relate nodes. A relation between two nodes is a
474
+ * `BoardConnection`, which is stored separately and resolves its geometry from
475
+ * the live node frames. Keeping the two apart is what lets an arrow be a plain
476
+ * shape (its own frame, freely movable) while a connection stays purely
477
+ * semantic — neither has to pretend to be the other.
478
+ */
479
+ const BoardArrowItemSchema = BoardItemBaseSchema.extend({
480
+ type: z.literal("arrow"),
481
+ start: BoardPointSchema,
482
+ end: BoardPointSchema,
483
+ bend: z.number().finite().min(-.85).max(.85).default(0),
484
+ color: z.string().min(1).default("brand"),
485
+ size: z.number().finite().positive().default(BOARD_ARROW_STROKE_SIZE),
486
+ arrowStart: z.boolean().default(false),
487
+ arrowEnd: z.boolean().default(true),
488
+ label: z.string().default("")
489
+ });
490
+ /** A frame container for organising shapes. */
491
+ const BoardFrameItemSchema = BoardItemBaseSchema.extend({
492
+ type: z.literal("frame"),
493
+ label: z.string().default("Frame"),
494
+ color: z.string().min(1).default("neutral")
495
+ });
496
+ /** Image node — space file only, natural aspect, no chrome. */
497
+ const BoardImageItemSchema = BoardItemBaseSchema.extend({
498
+ type: z.literal("image"),
499
+ ref: SpaceFileRefSchema,
500
+ snapshot: BoardMediaSnapshotSchema.optional(),
501
+ /** Optional normalized crop in source image space (0..1). */
502
+ crop: z.object({
503
+ x: z.number().finite().min(0).max(1).default(0),
504
+ y: z.number().finite().min(0).max(1).default(0),
505
+ w: z.number().finite().min(0).max(1).default(1),
506
+ h: z.number().finite().min(0).max(1).default(1)
507
+ }).optional()
508
+ });
509
+ /** Video node — space file only. Playback state is local UI, never synced. */
510
+ const BoardVideoItemSchema = BoardItemBaseSchema.extend({
511
+ type: z.literal("video"),
512
+ ref: SpaceFileRefSchema,
513
+ snapshot: BoardMediaSnapshotSchema.optional()
514
+ });
515
+ /** Audio node — space file only. Playback state is local UI, never synced. */
516
+ const BoardAudioItemSchema = BoardItemBaseSchema.extend({
517
+ type: z.literal("audio"),
518
+ ref: SpaceFileRefSchema,
519
+ snapshot: BoardMediaSnapshotSchema.extend({ durationMs: z.number().finite().nonnegative().optional() }).optional()
520
+ });
521
+ /**
522
+ * Cached display facts for a file card.
523
+ *
524
+ * Purely derived from the referenced file and versioned by `mtimeMs`, so it is a
525
+ * cache and never a second source of truth: the workspace file remains
526
+ * authoritative, and a stale snapshot is detectable rather than silently wrong.
527
+ * It is stored so that opening a board renders complete cards immediately, with
528
+ * no per-node file read on the first paint.
529
+ */
530
+ const BoardFileSnapshotSchema = z.object({
531
+ title: z.string().optional(),
532
+ mimeType: z.string().optional(),
533
+ size: z.number().finite().nonnegative().optional(),
534
+ mtimeMs: z.number().finite().nonnegative().optional(),
535
+ /** Cleaned leading prose. Capped when written (see FILE_EXCERPT_MAX_CHARS). */
536
+ excerpt: z.string().optional(),
537
+ /** Cover image inside the space, already resolved to a workspace path. */
538
+ coverPath: z.string().optional(),
539
+ /** Cover image at an absolute https URL, as declared by the file itself. */
540
+ coverUrl: z.string().optional()
541
+ });
542
+ /**
543
+ * File node — a thumbnail entry point to any workspace file.
544
+ *
545
+ * This is the fallback for every dropped file that is not natively an image or
546
+ * video, including binaries and unknown extensions: a board should never refuse
547
+ * a file, only present it with less detail. Presentation tiers are derived from
548
+ * the snapshot (see filePreviewKind), not stored, so there is no display state
549
+ * to drift from the facts.
550
+ */
551
+ const BoardFileItemSchema = BoardItemBaseSchema.extend({
552
+ type: z.literal("file"),
553
+ ref: SpaceFileRefSchema,
554
+ snapshot: BoardFileSnapshotSchema.optional()
555
+ });
556
+ const BoardTaskMediaArtifactFields = {
557
+ id: z.string().min(1).max(240),
558
+ title: z.string().max(240).optional(),
559
+ url: BoardRemoteUrlSchema,
560
+ mimeType: z.string().max(160).optional()
561
+ };
562
+ const BoardTaskArtifactSchema = z.discriminatedUnion("type", [
563
+ z.object({
564
+ ...BoardTaskMediaArtifactFields,
565
+ type: z.literal("image"),
566
+ naturalWidth: z.number().positive().optional(),
567
+ naturalHeight: z.number().positive().optional()
568
+ }).strict(),
569
+ z.object({
570
+ ...BoardTaskMediaArtifactFields,
571
+ type: z.literal("video"),
572
+ previewUrl: BoardRemoteUrlSchema.optional(),
573
+ durationMs: z.number().int().positive().optional(),
574
+ naturalWidth: z.number().positive().optional(),
575
+ naturalHeight: z.number().positive().optional()
576
+ }).strict(),
577
+ z.object({
578
+ ...BoardTaskMediaArtifactFields,
579
+ type: z.literal("audio"),
580
+ previewUrl: BoardRemoteUrlSchema.optional(),
581
+ durationMs: z.number().int().positive().optional()
582
+ }).strict(),
583
+ z.object({
584
+ id: z.string().min(1).max(240),
585
+ type: z.literal("text"),
586
+ title: z.string().max(240).optional(),
587
+ textExcerpt: z.string().min(1).max(480)
588
+ }).strict()
589
+ ]);
590
+ /**
591
+ * Cached task facts used for an immediate first paint. The task run remains the
592
+ * source of truth and live clients refresh this projection by `taskRunId`.
593
+ */
594
+ const BoardTaskSnapshotSchema = z.object({
595
+ taskType: z.string().min(1).max(120),
596
+ status: z.enum([
597
+ "pending",
598
+ "running",
599
+ "completed",
600
+ "failed"
601
+ ]),
602
+ title: z.string().min(1).max(240),
603
+ model: z.string().max(160).optional(),
604
+ promptExcerpt: z.string().max(480).optional(),
605
+ artifactCount: z.number().int().nonnegative(),
606
+ artifacts: z.array(BoardTaskArtifactSchema).max(6).default([]),
607
+ updatedAt: z.string().optional()
608
+ }).strict();
609
+ /** A stable reference to a task run with a small, replaceable display cache. */
610
+ const BoardTaskItemSchema = BoardItemBaseSchema.extend({
611
+ type: z.literal("task"),
612
+ taskRunId: z.string().min(1),
613
+ snapshot: BoardTaskSnapshotSchema
614
+ });
615
+ /**
616
+ * A forward-compatible carrier for shape types this client does not recognise.
617
+ * Its discriminant is the literal `"unknown"` so the item union still narrows
618
+ * cleanly on `type`. The real type string and every original field are preserved
619
+ * verbatim in `raw`.
620
+ */
621
+ const UNKNOWN_BOARD_ITEM_TYPE = "unknown";
622
+ const BoardItemSchema = z.any().transform((raw) => parseBoardItemLoose(raw));
623
+ /**
624
+ * Parse a single item leniently: known types are validated and normalised;
625
+ * anything else becomes a lossless unknown item. Never throws on shape data —
626
+ * a malformed known item degrades to unknown rather than failing the document.
627
+ */
628
+ function parseBoardItemLoose(raw) {
629
+ if (!raw || typeof raw !== "object") return makeUnknownItem(raw);
630
+ switch (raw.type) {
631
+ case "image": {
632
+ const parsed = BoardImageItemSchema.safeParse(raw);
633
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
634
+ }
635
+ case "video": {
636
+ const parsed = BoardVideoItemSchema.safeParse(raw);
637
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
638
+ }
639
+ case "audio": {
640
+ const parsed = BoardAudioItemSchema.safeParse(raw);
641
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
642
+ }
643
+ case "file": {
644
+ const parsed = BoardFileItemSchema.safeParse(raw);
645
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
646
+ }
647
+ case "task": {
648
+ const parsed = BoardTaskItemSchema.safeParse(raw);
649
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
650
+ }
651
+ case "text": {
652
+ const parsed = BoardTextItemSchema.safeParse(raw);
653
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
654
+ }
655
+ case "geo": {
656
+ const parsed = BoardGeoItemSchema.safeParse(raw);
657
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
658
+ }
659
+ case "draw": {
660
+ const parsed = BoardDrawItemSchema.safeParse(raw);
661
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
662
+ }
663
+ case "arrow": {
664
+ const parsed = BoardArrowItemSchema.safeParse(raw);
665
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
666
+ }
667
+ case "frame": {
668
+ const parsed = BoardFrameItemSchema.safeParse(raw);
669
+ return parsed.success ? parsed.data : makeUnknownItem(raw);
670
+ }
671
+ default: return makeUnknownItem(raw);
672
+ }
673
+ }
674
+ function makeUnknownItem(raw) {
675
+ const record = raw && typeof raw === "object" ? raw : {};
676
+ const frameParsed = BoardFrameSchema.safeParse(record.frame);
677
+ const styleParsed = BoardItemStyleSchema.safeParse(record.style);
678
+ return {
679
+ id: typeof record.id === "string" && record.id ? record.id : "unknown",
680
+ type: UNKNOWN_BOARD_ITEM_TYPE,
681
+ frame: frameParsed.success ? frameParsed.data : {
682
+ x: 0,
683
+ y: 0,
684
+ width: 120,
685
+ height: 80,
686
+ rotation: 0
687
+ },
688
+ ...typeof record.parentId === "string" || record.parentId === null ? { parentId: record.parentId } : {},
689
+ ...record.locked === true ? { locked: true } : {},
690
+ ...styleParsed.success && record.style ? { style: styleParsed.data } : {},
691
+ ...record.metadata && typeof record.metadata === "object" ? { metadata: record.metadata } : {},
692
+ raw: record
693
+ };
694
+ }
695
+ z.object({
696
+ kind: z.literal(BOARD_DOCUMENT_KIND),
697
+ version: z.literal(1),
698
+ appearance: BoardAppearanceSchema.default({
699
+ theme: "clean",
700
+ background: { kind: "solid" },
701
+ grid: {
702
+ visible: false,
703
+ size: 24,
704
+ opacity: .12
705
+ },
706
+ mood: "clean"
707
+ }),
708
+ viewport: BoardViewportSchema,
709
+ items: z.array(BoardItemSchema),
710
+ /**
711
+ * Node relations. Separate from `items` because a connection has no frame of
712
+ * its own — its geometry is derived from the nodes it joins, so it is a
713
+ * relation over the item set rather than a member of it.
714
+ *
715
+ * Connections referencing a missing node are dropped on parse: a relation to
716
+ * nothing is not a relation, and keeping one would let an invisible dangling
717
+ * edge accumulate silently. Callers that need to know write through the
718
+ * transaction API, which reports the reference error instead.
719
+ */
720
+ connections: z.array(BoardConnectionSchema).default([])
721
+ });
722
+ //#endregion
723
+ //#region ../protocol/dist/board-node.js
724
+ const BOARD_COLOR_IDS = [
725
+ "brand",
726
+ "neutral",
727
+ "black",
728
+ "white",
729
+ "blue",
730
+ "green",
731
+ "amber",
732
+ "violet",
733
+ "rose"
734
+ ];
735
+ const BoardColorIdSchema = z.enum(BOARD_COLOR_IDS);
736
+ const BOARD_GEO_KINDS = [
737
+ "rectangle",
738
+ "rounded",
739
+ "ellipse",
740
+ "diamond",
741
+ "triangle"
742
+ ];
743
+ const BoardGeoKindSchema = z.enum(BOARD_GEO_KINDS);
744
+ const BOARD_NATIVE_NODE_TYPES = [
745
+ "image",
746
+ "video",
747
+ "audio",
748
+ "file",
749
+ "task",
750
+ "text",
751
+ "geo",
752
+ "draw",
753
+ "arrow",
754
+ "frame"
755
+ ];
756
+ const metadataSchema = z.record(z.string(), z.unknown());
757
+ const commonData = {
758
+ locked: z.boolean().optional(),
759
+ metadata: metadataSchema.optional()
760
+ };
761
+ const pointSchema = z.object({
762
+ x: z.number().finite(),
763
+ y: z.number().finite(),
764
+ p: z.number().finite().min(0).max(1).default(.5)
765
+ }).strict();
766
+ const worldPointSchema = z.object({
767
+ x: z.number().finite(),
768
+ y: z.number().finite()
769
+ }).strict();
770
+ const strokeSizeSchema = z.number().finite().min(1).max(64);
771
+ const mediaViewSchema = z.object({
772
+ title: z.string().optional(),
773
+ mimeType: z.string().optional(),
774
+ size: z.number().finite().nonnegative().optional(),
775
+ mtimeMs: z.number().finite().nonnegative().optional(),
776
+ naturalWidth: z.number().finite().positive().optional(),
777
+ naturalHeight: z.number().finite().positive().optional()
778
+ }).strict();
779
+ const audioViewSchema = mediaViewSchema.extend({ durationMs: z.number().finite().nonnegative().optional() });
780
+ const dataSchemas = {
781
+ text: z.object({
782
+ ...commonData,
783
+ text: z.string().default(""),
784
+ color: BoardColorIdSchema.default("neutral"),
785
+ fontSize: z.number().finite().min(2).max(512).default(24)
786
+ }).strict(),
787
+ geo: z.object({
788
+ ...commonData,
789
+ geo: BoardGeoKindSchema.default("rectangle"),
790
+ text: z.string().default(""),
791
+ color: BoardColorIdSchema.default("brand"),
792
+ fillOpacity: z.number().finite().min(0).max(1).default(0)
793
+ }).strict(),
794
+ draw: z.object({
795
+ ...commonData,
796
+ points: z.array(pointSchema).min(1),
797
+ color: BoardColorIdSchema.default("brand"),
798
+ size: strokeSizeSchema.default(4)
799
+ }).strict(),
800
+ arrow: z.object({
801
+ ...commonData,
802
+ start: worldPointSchema,
803
+ end: worldPointSchema,
804
+ bend: z.number().finite().min(-.85).max(.85).default(0),
805
+ color: BoardColorIdSchema.default("brand"),
806
+ size: strokeSizeSchema.default(BOARD_ARROW_STROKE_SIZE),
807
+ arrowStart: z.boolean().default(false),
808
+ arrowEnd: z.boolean().default(true),
809
+ label: z.string().default("")
810
+ }).strict(),
811
+ frame: z.object({
812
+ ...commonData,
813
+ label: z.string().default("Frame"),
814
+ color: BoardColorIdSchema.default("neutral")
815
+ }).strict(),
816
+ image: z.object({
817
+ ...commonData,
818
+ crop: z.object({
819
+ x: z.number().finite().min(0).max(1),
820
+ y: z.number().finite().min(0).max(1),
821
+ w: z.number().finite().min(0).max(1),
822
+ h: z.number().finite().min(0).max(1)
823
+ }).strict().optional()
824
+ }).strict(),
825
+ video: z.object(commonData).strict(),
826
+ audio: z.object(commonData).strict(),
827
+ file: z.object(commonData).strict(),
828
+ task: z.object({
829
+ ...commonData,
830
+ taskRunId: z.string().min(1)
831
+ }).strict()
832
+ };
833
+ const fileViewSchema = z.object({
834
+ title: z.string().optional(),
835
+ mimeType: z.string().optional(),
836
+ size: z.number().finite().nonnegative().optional(),
837
+ mtimeMs: z.number().finite().nonnegative().optional(),
838
+ excerpt: z.string().optional(),
839
+ coverPath: z.string().optional(),
840
+ coverUrl: z.string().url().optional()
841
+ }).strict();
842
+ const taskViewSchema = BoardTaskSnapshotSchema;
843
+ const emptyViewSchema = z.object({}).strict();
844
+ const viewSchemas = {
845
+ image: mediaViewSchema,
846
+ video: mediaViewSchema,
847
+ audio: audioViewSchema,
848
+ file: fileViewSchema,
849
+ task: taskViewSchema,
850
+ text: emptyViewSchema,
851
+ geo: emptyViewSchema,
852
+ draw: emptyViewSchema,
853
+ arrow: emptyViewSchema,
854
+ frame: emptyViewSchema
855
+ };
856
+ const nodeEnvelopeSchema = z.object({
857
+ nodeId: z.string().min(1).max(160),
858
+ type: z.string().min(1).max(40),
859
+ parentId: z.string().min(1).max(160).nullable(),
860
+ orderKey: z.string().max(4096).nullable(),
861
+ x: z.number().finite(),
862
+ y: z.number().finite(),
863
+ width: z.number().finite().positive(),
864
+ height: z.number().finite().positive(),
865
+ rotation: z.number().finite(),
866
+ refKind: z.string().max(40).nullable(),
867
+ refPath: z.string().max(4096).nullable(),
868
+ refUrl: z.string().max(4096).nullable(),
869
+ view: z.record(z.string(), z.unknown()),
870
+ style: z.record(z.string(), z.unknown()),
871
+ data: z.record(z.string(), z.unknown())
872
+ }).strict();
873
+ function jsonSchema(schema) {
874
+ return z.toJSONSchema(schema);
875
+ }
876
+ jsonSchema(nodeEnvelopeSchema), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(dataSchemas[type])])), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(viewSchemas[type])]));
877
+ //#endregion
7
878
  //#region ../protocol/dist/generation/catalog.js
8
879
  function isGenerationModelHidden(model) {
9
880
  return model.hidden === true;
@@ -21,14 +892,14 @@ var GenerationPolicyError = class extends Error {
21
892
  this.name = "GenerationPolicyError";
22
893
  }
23
894
  };
24
- function isRecord(value) {
895
+ function isRecord$1(value) {
25
896
  return !!value && typeof value === "object" && !Array.isArray(value);
26
897
  }
27
898
  function isPrimitiveEnumValue(value) {
28
899
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
29
900
  }
30
901
  function normalizeConstraint(value) {
31
- if (!isRecord(value) || typeof value.kind !== "string") return null;
902
+ if (!isRecord$1(value) || typeof value.kind !== "string") return null;
32
903
  if (value.kind === "enum") {
33
904
  if (!Array.isArray(value.values) || value.values.length === 0 || !value.values.every(isPrimitiveEnumValue)) return null;
34
905
  return {
@@ -58,7 +929,7 @@ function normalizeConstraint(value) {
58
929
  return null;
59
930
  }
60
931
  function normalizeGenerationPolicy(value) {
61
- if (!isRecord(value) || value.version !== 1) return null;
932
+ if (!isRecord$1(value) || value.version !== 1) return null;
62
933
  if (value.mode === "auto") return {
63
934
  version: 1,
64
935
  mode: "auto"
@@ -66,10 +937,10 @@ function normalizeGenerationPolicy(value) {
66
937
  if (value.mode !== "limited" || !Array.isArray(value.models) || value.models.length === 0) return null;
67
938
  const models = [];
68
939
  for (const item of value.models) {
69
- if (!isRecord(item) || typeof item.model !== "string" || !item.model.trim()) return null;
940
+ if (!isRecord$1(item) || typeof item.model !== "string" || !item.model.trim()) return null;
70
941
  const modelPolicy = { model: item.model.trim() };
71
942
  if (item.parameters !== void 0) {
72
- if (!isRecord(item.parameters)) return null;
943
+ if (!isRecord$1(item.parameters)) return null;
73
944
  const parameters = {};
74
945
  for (const [key, rawConstraint] of Object.entries(item.parameters)) {
75
946
  if (!key.trim()) return null;
@@ -244,6 +1115,172 @@ function filterGenerationDeclarationsByPolicy(declarations, policy) {
244
1115
  });
245
1116
  }
246
1117
  //#endregion
1118
+ //#region ../protocol/dist/public-identifiers.js
1119
+ const USERNAME_PATTERN = /^(?!-)(?!.*--)[a-z0-9-]{1,39}(?<!-)$/;
1120
+ const SPACE_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9_-]{0,78}[a-z0-9])?$/;
1121
+ /**
1122
+ * Platform-owned path segments that must not be newly assigned to public
1123
+ * identities. Existing stored values remain readable through parse helpers.
1124
+ */
1125
+ const RESERVED_PLATFORM_PATH_SEGMENTS = Object.freeze([
1126
+ "admin",
1127
+ "api",
1128
+ "assets",
1129
+ "auth",
1130
+ "callback",
1131
+ "changelog",
1132
+ "docs",
1133
+ "explore",
1134
+ "invite",
1135
+ "landing",
1136
+ "login",
1137
+ "logout",
1138
+ "new",
1139
+ "org",
1140
+ "pricing",
1141
+ "pwa",
1142
+ "referrals",
1143
+ "sessions",
1144
+ "settings",
1145
+ "spaces",
1146
+ "static",
1147
+ "teams",
1148
+ "trending",
1149
+ "u",
1150
+ "user",
1151
+ "users",
1152
+ "work-auth"
1153
+ ]);
1154
+ new Set(RESERVED_PLATFORM_PATH_SEGMENTS);
1155
+ [...RESERVED_PLATFORM_PATH_SEGMENTS];
1156
+ function parseUsername(value) {
1157
+ if (value === null || value === void 0) return null;
1158
+ const normalized = value.trim().toLowerCase();
1159
+ return USERNAME_PATTERN.test(normalized) ? normalized : null;
1160
+ }
1161
+ function parseSpaceSlug(value) {
1162
+ if (value === null || value === void 0) return null;
1163
+ const normalized = value.trim();
1164
+ return SPACE_SLUG_PATTERN.test(normalized) ? normalized : null;
1165
+ }
1166
+ //#endregion
1167
+ //#region ../protocol/dist/work-surface.js
1168
+ const WORK_SURFACE_PROTOCOL = "cohub.surface";
1169
+ const WORK_SURFACE_READY_TIMEOUT_MS = 1e4;
1170
+ const WORK_SURFACE_REQUEST_TIMEOUT_MS = 15e3;
1171
+ const WORK_COMPOSER_CHIP_KEY_MAX_LENGTH = 80;
1172
+ const WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH = 120;
1173
+ const WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES = 32 * 1024;
1174
+ const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
1175
+ const isSurfaceEnvelope = (value) => isRecord(value) && value.protocol === "cohub.surface" && value.version === 1;
1176
+ const parseWorkSurfaceReady = (value) => {
1177
+ if (!isSurfaceEnvelope(value) || value.type !== "ready") return null;
1178
+ const methods = Array.isArray(value.methods) ? value.methods.filter((method) => typeof method === "string" && Boolean(method)) : [];
1179
+ return {
1180
+ protocol: WORK_SURFACE_PROTOCOL,
1181
+ version: 1,
1182
+ type: "ready",
1183
+ methods
1184
+ };
1185
+ };
1186
+ const parseWorkSurfaceResponse = (value) => {
1187
+ if (!isSurfaceEnvelope(value) || value.type !== "response") return null;
1188
+ if (typeof value.requestId !== "string" || !value.requestId) return null;
1189
+ const error = isRecord(value.error) ? {
1190
+ code: typeof value.error.code === "string" && value.error.code ? value.error.code : "surface_error",
1191
+ message: typeof value.error.message === "string" ? value.error.message : "Work surface call failed"
1192
+ } : void 0;
1193
+ return {
1194
+ protocol: WORK_SURFACE_PROTOCOL,
1195
+ version: 1,
1196
+ type: "response",
1197
+ requestId: value.requestId,
1198
+ ok: value.ok === true,
1199
+ ...error ? { error } : {}
1200
+ };
1201
+ };
1202
+ const parseComposerChipKey = (value) => {
1203
+ if (typeof value !== "string") return null;
1204
+ const key = value.trim();
1205
+ if (!key || key.length > 80) return null;
1206
+ return key;
1207
+ };
1208
+ const parseWorkComposerChipSet = (value) => {
1209
+ if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.set" || !isRecord(value.chip)) return null;
1210
+ const key = parseComposerChipKey(value.chip.key);
1211
+ if (!key || typeof value.chip.label !== "string" || typeof value.chip.content !== "string") return null;
1212
+ const label = value.chip.label.trim();
1213
+ if (!label || label.length > 120) return null;
1214
+ if (!value.chip.content.trim()) return null;
1215
+ if (new TextEncoder().encode(value.chip.content).length > 32768) return null;
1216
+ return {
1217
+ protocol: WORK_SURFACE_PROTOCOL,
1218
+ version: 1,
1219
+ type: "composer.chip.set",
1220
+ chip: {
1221
+ key,
1222
+ label,
1223
+ content: value.chip.content
1224
+ }
1225
+ };
1226
+ };
1227
+ const parseWorkComposerChipClear = (value) => {
1228
+ if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.clear") return null;
1229
+ const key = parseComposerChipKey(value.key);
1230
+ return key ? {
1231
+ protocol: WORK_SURFACE_PROTOCOL,
1232
+ version: 1,
1233
+ type: "composer.chip.clear",
1234
+ key
1235
+ } : null;
1236
+ };
1237
+ const parseWorkSurfaceRequest = (value) => {
1238
+ if (!isSurfaceEnvelope(value) || value.type !== "request") return null;
1239
+ if (typeof value.requestId !== "string" || !value.requestId) return null;
1240
+ if (typeof value.method !== "string" || !value.method) return null;
1241
+ const commandId = parseUiCommandId(value.commandId);
1242
+ if (!commandId) return null;
1243
+ return {
1244
+ protocol: WORK_SURFACE_PROTOCOL,
1245
+ version: 1,
1246
+ type: "request",
1247
+ requestId: value.requestId,
1248
+ method: value.method,
1249
+ ...value.input === void 0 ? {} : { input: value.input },
1250
+ commandId
1251
+ };
1252
+ };
1253
+ const buildWorkSurfaceReady = (methods) => ({
1254
+ protocol: WORK_SURFACE_PROTOCOL,
1255
+ version: 1,
1256
+ type: "ready",
1257
+ methods: [...methods]
1258
+ });
1259
+ const buildWorkSurfaceRequest = (input) => ({
1260
+ protocol: WORK_SURFACE_PROTOCOL,
1261
+ version: 1,
1262
+ type: "request",
1263
+ ...input
1264
+ });
1265
+ const buildWorkSurfaceResponse = (input) => ({
1266
+ protocol: WORK_SURFACE_PROTOCOL,
1267
+ version: 1,
1268
+ type: "response",
1269
+ ...input
1270
+ });
1271
+ const buildWorkComposerChipSet = (chip) => ({
1272
+ protocol: WORK_SURFACE_PROTOCOL,
1273
+ version: 1,
1274
+ type: "composer.chip.set",
1275
+ chip
1276
+ });
1277
+ const buildWorkComposerChipClear = (key) => ({
1278
+ protocol: WORK_SURFACE_PROTOCOL,
1279
+ version: 1,
1280
+ type: "composer.chip.clear",
1281
+ key
1282
+ });
1283
+ //#endregion
247
1284
  //#region src/apis/billing.ts
248
1285
  var BillingApi = class {
249
1286
  transport;
@@ -316,193 +1353,6 @@ var BillingApi = class {
316
1353
  }
317
1354
  };
318
1355
  //#endregion
319
- //#region ../protocol/dist/realtime/schema.js
320
- const contentBlockMetaSchema = z.record(z.string(), z.unknown());
321
- const realtimeRoomSchema = z.string().regex(/^(space|user|board|room):[^:]+$/);
322
- const contentBlockSchema = z.discriminatedUnion("type", [
323
- z.object({
324
- type: z.literal("text"),
325
- text: z.string(),
326
- _meta: contentBlockMetaSchema.optional()
327
- }),
328
- z.object({
329
- type: z.literal("thinking"),
330
- thinking: z.string(),
331
- signature: z.string().optional(),
332
- _meta: contentBlockMetaSchema.optional()
333
- }),
334
- z.object({
335
- type: z.literal("image"),
336
- source: z.union([z.object({
337
- type: z.literal("url"),
338
- url: z.string().url()
339
- }), z.object({
340
- type: z.literal("base64"),
341
- media_type: z.string(),
342
- data: z.string()
343
- })]),
344
- _meta: contentBlockMetaSchema.optional()
345
- }),
346
- z.object({
347
- type: z.literal("shell_command"),
348
- command: z.string(),
349
- rawText: z.string(),
350
- _meta: contentBlockMetaSchema.optional()
351
- }),
352
- z.object({
353
- type: z.literal("tool_use"),
354
- id: z.string(),
355
- name: z.string(),
356
- input: z.record(z.string(), z.unknown()),
357
- _meta: contentBlockMetaSchema.optional()
358
- }),
359
- z.object({
360
- type: z.literal("tool_result"),
361
- tool_use_id: z.string(),
362
- content: z.union([z.string(), z.array(z.unknown())]),
363
- is_error: z.boolean().optional(),
364
- _meta: contentBlockMetaSchema.optional()
365
- }),
366
- z.object({
367
- type: z.literal("system_note"),
368
- note_type: z.enum([
369
- "session_created",
370
- "forked",
371
- "compacted",
372
- "info"
373
- ]),
374
- text: z.string(),
375
- _meta: contentBlockMetaSchema.optional()
376
- })
377
- ]);
378
- z.discriminatedUnion("type", [
379
- z.object({
380
- type: z.literal("auth"),
381
- requestId: z.string().optional(),
382
- payload: z.object({
383
- token: z.string().min(1),
384
- capabilities: z.array(z.string().min(1)).optional()
385
- })
386
- }),
387
- z.object({
388
- type: z.literal("subscribe"),
389
- requestId: z.string().optional(),
390
- payload: z.object({ rooms: z.array(realtimeRoomSchema).min(1) })
391
- }),
392
- z.object({
393
- type: z.literal("unsubscribe"),
394
- requestId: z.string().optional(),
395
- payload: z.object({ rooms: z.array(realtimeRoomSchema).min(1) })
396
- }),
397
- z.object({
398
- type: z.literal("session.message.create"),
399
- requestId: z.string().optional(),
400
- payload: z.object({
401
- spaceId: z.string().uuid(),
402
- sessionId: z.string().uuid(),
403
- clientMessageId: z.string().optional(),
404
- content: z.array(contentBlockSchema).min(1),
405
- model: z.string().optional(),
406
- provider: z.string().optional(),
407
- thinkingLevel: z.enum([
408
- "off",
409
- "minimal",
410
- "low",
411
- "medium",
412
- "high",
413
- "xhigh",
414
- "max"
415
- ]).optional()
416
- })
417
- }),
418
- z.object({
419
- type: z.literal("presence.update"),
420
- requestId: z.string().optional(),
421
- payload: z.object({
422
- spaceId: z.string().uuid(),
423
- meta: z.record(z.string(), z.unknown()).nullable().optional()
424
- })
425
- }),
426
- z.object({
427
- type: z.literal("board.awareness.update"),
428
- requestId: z.string().optional(),
429
- payload: BoardAwarenessClientPayloadSchema
430
- }),
431
- z.object({
432
- type: z.literal("realtime.room.join"),
433
- requestId: z.string().optional(),
434
- payload: z.object({
435
- roomId: z.string().uuid(),
436
- ticket: z.string().min(1)
437
- })
438
- }),
439
- z.object({
440
- type: z.literal("realtime.room.publish"),
441
- requestId: z.string().optional(),
442
- payload: z.object({
443
- roomId: z.string().uuid(),
444
- event: z.string().regex(REALTIME_ROOM_EVENT_NAME_PATTERN),
445
- data: z.unknown(),
446
- clientEventId: z.string().max(128).optional()
447
- })
448
- }),
449
- z.object({
450
- type: z.literal("realtime.room.leave"),
451
- requestId: z.string().optional(),
452
- payload: z.object({ roomId: z.string().uuid() })
453
- }),
454
- z.object({
455
- type: z.literal("realtime.room.presence.update"),
456
- requestId: z.string().optional(),
457
- payload: z.object({
458
- roomId: z.string().uuid(),
459
- presence: z.record(z.string(), z.unknown()).nullable()
460
- })
461
- }),
462
- z.object({
463
- type: z.literal("ping"),
464
- requestId: z.string().optional(),
465
- payload: z.record(z.string(), z.unknown()).optional()
466
- }),
467
- z.object({
468
- type: z.literal("ack"),
469
- requestId: z.string().optional(),
470
- payload: z.object({ eventId: z.string().optional() }).optional()
471
- })
472
- ]);
473
- z.object({
474
- id: z.string(),
475
- timestamp: z.number(),
476
- domain: z.enum(REALTIME_DOMAINS),
477
- type: z.string(),
478
- requestId: z.string().nullable().optional(),
479
- spaceId: z.string().nullable().optional(),
480
- sessionId: z.string().nullable().optional(),
481
- rooms: z.array(realtimeRoomSchema).optional(),
482
- payload: z.record(z.string(), z.unknown())
483
- });
484
- z.discriminatedUnion("t", [z.object({
485
- t: z.literal("d"),
486
- sid: z.string().min(1),
487
- s: z.number().int().nonnegative(),
488
- b: z.number().int().nonnegative(),
489
- v: z.unknown()
490
- }), z.object({
491
- t: z.literal("p"),
492
- sid: z.string().min(1),
493
- s: z.number().int().nonnegative(),
494
- b: z.number().int().nonnegative(),
495
- o: z.enum([
496
- "append",
497
- "replace",
498
- "add",
499
- "merge",
500
- "remove"
501
- ]),
502
- p: z.string().min(1),
503
- v: z.unknown().optional()
504
- })]);
505
- //#endregion
506
1356
  //#region src/apis/work-realtime.ts
507
1357
  const randomId = () => globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;
508
1358
  const textEncoder = new TextEncoder();
@@ -2370,4 +3220,4 @@ function createBoardExtensionRegistry() {
2370
3220
  }
2371
3221
  const BOARD_CHANNELS = BOARD_ANIMATION_CHANNELS;
2372
3222
  //#endregion
2373
- export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_ANIMATION_CHANNEL_CAPABILITIES, BOARD_CHANNELS, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BOARD_NODE_CONTRACT, BillingApi, BoardAuthoringItemSchema, BoardClient, BoardCompositionInputSchema, BoardCompositionSchema, BoardEffectSchema, BoardExtensionRegistry, BoardItemPatchSchema, BoardPlaybackPolicySchema, BoardTransactionError, COHUB_ENVIRONMENTS, COHUB_SOURCE_HEADER, COHUB_SOURCE_HEADER_NAMES, CohubClient, CohubHttpClient, DEFAULT_BOARD_LIMITS, FEATURE_NOT_ENTITLED_ERROR_CODE, GenerationPolicyError, HttpError, ParentBridgeTransport, PopupBrokerTransport, REQUEST_SOURCE_VIA_MAX_LENGTH, ReferencesApi, ReferralsApi, SessionGenerationStreamClient, SessionPatchReducer, SpacePublicFilesApi, UI_COMMAND_DEFAULT_TIMEOUT_MS, UI_COMMAND_MAX_TIMEOUT_MS, UI_COMMAND_PAYLOAD_MAX_BYTES, UI_COMMAND_PENDING_TTL_SECONDS, UI_COMMAND_SETTLEMENT_GRACE_SECONDS, UI_COMMAND_TERMINAL_TTL_SECONDS, UI_COMMAND_VERSION, UiCommandsApi, UsersApi, VoiceApi, VoiceInputClient, WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES, WORK_COMPOSER_CHIP_KEY_MAX_LENGTH, WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH, WORK_SURFACE_READY_TIMEOUT_MS, WORK_SURFACE_REQUEST_TIMEOUT_MS, WebsocketClient, WorkCommerceApi, WorkRealtimeApi, WorkRefParseError, WorkRoom, WorkRuntimeApi, WorkSurfaceApi, WorksApi, assertGenerationRequestAllowedByPolicy, buildSpaceInvitePath, buildSpacePath, buildWorkSurfaceRequest, clearGrantedWorkScopes, compileComposition, composition, createBoardExtensionRegistry, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createSlugWorkIdResolver, createVoiceInputClient, createWebsocketClient, createWorkBridgeCore, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, extractBillingPayload, filterDiscoverableGenerationModels, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, formatWorkRef, getAllowedGenerationModelIds, hasGrantedWorkScopes, hasRequestSourceIdentity, isBillingAccessBlockedCode, isBillingAccessBlockedError, isFeatureNotEntitledError, isGenerationModelHidden, isHttpErrorCode, isRequestSourceClientId, isRequestSourceEmpty, isRequestSourceUuid, isTerminalUiCommandStatus, isUiSurfaceMethod, isUuid, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseBoardCompositionInput, parseBoardPlaybackPolicy, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseUiCommand, parseWorkRef, parseWorkSurfaceReady, parseWorkSurfaceResponse, proceduralClip, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveCohubEnvironment, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, sampleCompositionTracks, sampleEasing, sampleTrack, sanitizeAccessToken, setGrantedWorkScopes, track, validateBoardNodeInput };
3223
+ export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_ANIMATION_CHANNEL_CAPABILITIES, BOARD_CHANNELS, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BillingApi, BoardAuthoringItemSchema, BoardClient, BoardCompositionInputSchema, BoardCompositionSchema, BoardEffectInputSchema, BoardEffectSchema, BoardExtensionRegistry, BoardItemPatchSchema, BoardPlaybackPolicySchema, COHUB_ENVIRONMENTS, COHUB_SOURCE_HEADER, COHUB_SOURCE_HEADER_NAMES, CohubClient, CohubHttpClient, DEFAULT_BOARD_LIMITS, FEATURE_NOT_ENTITLED_ERROR_CODE, GenerationPolicyError, HttpError, ParentBridgeTransport, PopupBrokerTransport, REQUEST_SOURCE_VIA_MAX_LENGTH, ReferencesApi, ReferralsApi, SessionGenerationStreamClient, SessionPatchReducer, SpacePublicFilesApi, UI_COMMAND_DEFAULT_TIMEOUT_MS, UI_COMMAND_MAX_TIMEOUT_MS, UI_COMMAND_PAYLOAD_MAX_BYTES, UI_COMMAND_PENDING_TTL_SECONDS, UI_COMMAND_SETTLEMENT_GRACE_SECONDS, UI_COMMAND_TERMINAL_TTL_SECONDS, UI_COMMAND_VERSION, UiCommandsApi, UsersApi, VoiceApi, VoiceInputClient, WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES, WORK_COMPOSER_CHIP_KEY_MAX_LENGTH, WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH, WORK_SURFACE_READY_TIMEOUT_MS, WORK_SURFACE_REQUEST_TIMEOUT_MS, WebsocketClient, WorkCommerceApi, WorkRealtimeApi, WorkRefParseError, WorkRoom, WorkRuntimeApi, WorkSurfaceApi, WorksApi, assertGenerationRequestAllowedByPolicy, buildSpaceInvitePath, buildSpacePath, buildWorkSurfaceRequest, clearGrantedWorkScopes, compileComposition, composition, createBoardExtensionRegistry, createCohubClient, createHttpClient, createSessionGenerationStreamClient, createSessionPatchReducer, createSlugWorkIdResolver, createVoiceInputClient, createWebsocketClient, createWorkBridgeCore, createWorkRuntime, decodeGenerationPolicy, encodeGenerationPolicy, extractBillingPayload, filterDiscoverableGenerationModels, filterGenerationDeclarationsByPolicy, findGenerationModelPolicy, formatWorkRef, getAllowedGenerationModelIds, hasGrantedWorkScopes, hasRequestSourceIdentity, isBillingAccessBlockedCode, isBillingAccessBlockedError, isFeatureNotEntitledError, isGenerationModelHidden, isHttpErrorCode, isRequestSourceClientId, isRequestSourceEmpty, isRequestSourceUuid, isTerminalUiCommandStatus, isUiSurfaceMethod, isUuid, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseBoardCompositionInput, parseBoardEffectInput, parseBoardPlaybackPolicy, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseUiCommand, parseWorkRef, parseWorkSurfaceReady, parseWorkSurfaceResponse, proceduralClip, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveCohubEnvironment, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, sampleCompositionTracks, sampleEasing, sampleTrack, sanitizeAccessToken, setGrantedWorkScopes, track };