@neta-art/cohub 5.6.0 → 5.8.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/README.md +18 -5
- package/dist/board/codec.js +15 -0
- package/dist/board/core/palette.d.ts +3 -2
- package/dist/board/core/shape-types.d.ts +8 -2
- package/dist/board/core/shape-types.js +3 -7
- package/dist/board/core/tool-styles.d.ts +2 -1
- package/dist/board/image-key.js +3 -5
- package/dist/board/index.d.ts +10 -5
- package/dist/board/index.js +7 -3
- package/dist/board/media-playback.d.ts +22 -0
- package/dist/board/media-playback.js +67 -0
- package/dist/board/media.d.ts +7 -0
- package/dist/board/media.js +70 -0
- package/dist/board/nodes.d.ts +113 -0
- package/dist/board/nodes.js +154 -0
- package/dist/board/render/audio-waveform.d.ts +12 -0
- package/dist/board/render/audio-waveform.js +36 -0
- package/dist/board/render/index.d.ts +4 -1
- package/dist/board/render/index.js +4 -1
- package/dist/board/render/media-interaction.d.ts +19 -0
- package/dist/board/render/media-interaction.js +26 -0
- package/dist/board/render/renderers/audio-card-renderer.d.ts +5 -0
- package/dist/board/render/renderers/audio-card-renderer.js +120 -0
- package/dist/board/render/renderers/board-renderer-registry.js +4 -2
- package/dist/board/render/renderers/draw-card-renderer.js +1 -1
- package/dist/board/render/renderers/file-card-renderer.js +1 -1
- package/dist/board/render/renderers/frame-card-renderer.js +1 -1
- package/dist/board/render/renderers/geo-card-renderer.js +1 -1
- package/dist/board/render/renderers/image-card-renderer.js +1 -1
- package/dist/board/render/renderers/task-card-renderer.d.ts +2 -1
- package/dist/board/render/renderers/task-card-renderer.js +21 -53
- package/dist/board/render/renderers/text-card-renderer.js +1 -1
- package/dist/board/render/renderers/unknown-card-renderer.js +1 -1
- package/dist/board/render/renderers/video-card-renderer.js +1 -1
- package/dist/board/render/video-thumbnail.d.ts +16 -0
- package/dist/board/render/video-thumbnail.js +86 -0
- package/dist/board/task.d.ts +10 -5
- package/dist/board/task.js +159 -103
- package/dist/chunks/environment.d.ts +6 -6
- package/dist/chunks/environment.js +6 -6
- package/dist/chunks/http.d.ts +71 -5
- package/dist/chunks/http.js +1535 -167
- package/dist/chunks/transport.js +8 -1
- package/dist/chunks/websocket.d.ts +139 -3
- package/dist/http.d.ts +3 -3
- package/dist/index.d.ts +245 -4
- package/dist/index.js +438 -788
- package/dist/protocol/dist/board-document.d.ts +271 -53
- package/dist/protocol/dist/board-document.js +54 -22
- package/dist/protocol/dist/board-node.d.ts +18 -0
- package/dist/protocol/dist/board-node.js +239 -0
- package/dist/protocol/dist/board-url.d.ts +12 -0
- package/dist/protocol/dist/board-url.js +83 -0
- package/dist/protocol/dist/board.d.ts +5 -0
- package/dist/protocol/dist/index.d.ts +2 -1
- package/dist/protocol/dist/index.js +2 -1
- package/dist/protocol/dist/provenance.js +1 -0
- package/docs/work-runtime-guide.md +7 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,191 +1,438 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { $ as SearchApi, A as UI_COMMAND_PENDING_TTL_SECONDS, B as BoardAwarenessClientPayloadSchema, C as BoardInputError, D as UI_COMMAND_DEFAULT_TIMEOUT_MS, E as validateBoardNodes, F as isUiSurfaceMethod, G as validateBoardNodeInput, H as BOARD_GEO_KINDS, I as parseUiCommand, J as ensureRealtimeConnected, K as BoardPlaybackPolicySchema, L as parseUiCommandId, M as UI_COMMAND_TERMINAL_TTL_SECONDS, N as UI_COMMAND_VERSION, O as UI_COMMAND_MAX_TIMEOUT_MS, P as isTerminalUiCommandStatus, Q as ReferencesApi, R as parseSpaceSlug, S as createSessionPatchReducer, T as createBoardNode, U as BOARD_NATIVE_NODE_TYPES, V as BOARD_COLOR_IDS, W as BOARD_NODE_CONTRACT, X as DEFAULT_BOARD_RENDER_LIMITS, Y as BOARD_BUILTIN_CAPABILITIES, Z as SessionAccessApi, _ as buildSpacePath, a as ReferralsApi, at as CronJobsApi, b as parseAssistantMessageCommit, c as UiCommandsApi, d as BoardTransactionError, et as PublicAssetsApi, f as SpaceClient, g as buildSpaceInvitePath, h as PublicInviteApi, i as WorksApi, it as GenerationsApi, j as UI_COMMAND_SETTLEMENT_GRACE_SECONDS, k as UI_COMMAND_PAYLOAD_MAX_BYTES, l as TasksApi, m as SpacesApi, n as createHttpClient, nt as PromptsApi, o as UsersApi, ot as ChannelsApi, p as SpacePublicFilesApi, q as parseBoardPlaybackPolicy, r as WorkCommerceApi, rt as ModelsApi, s as UserApi, t as CohubHttpClient, tt as SkillsApi, u as BoardClient, v as SessionGenerationStreamClient, w as assertBoardNodes, x as SessionPatchReducer, y as createSessionGenerationStreamClient, z as parseUsername } from "./chunks/http.js";
|
|
2
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 REALTIME_DOMAINS } 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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
//#region ../protocol/dist/generation/catalog.js
|
|
8
|
+
function isGenerationModelHidden(model) {
|
|
9
|
+
return model.hidden === true;
|
|
10
|
+
}
|
|
11
|
+
function filterDiscoverableGenerationModels(models, options = {}) {
|
|
12
|
+
const includeModelIds = new Set(options.includeModelIds);
|
|
13
|
+
return models.filter((model) => !isGenerationModelHidden(model) || includeModelIds.has(model.model));
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region ../protocol/dist/generation/policy.js
|
|
17
|
+
const GENERATION_POLICY_ENV_KEY = "COHUB_GENERATION_POLICY_B64";
|
|
18
|
+
var GenerationPolicyError = class extends Error {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "GenerationPolicyError";
|
|
12
22
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
};
|
|
24
|
+
function isRecord$1(value) {
|
|
25
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
26
|
+
}
|
|
27
|
+
function isPrimitiveEnumValue(value) {
|
|
28
|
+
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
29
|
+
}
|
|
30
|
+
function normalizeConstraint(value) {
|
|
31
|
+
if (!isRecord$1(value) || typeof value.kind !== "string") return null;
|
|
32
|
+
if (value.kind === "enum") {
|
|
33
|
+
if (!Array.isArray(value.values) || value.values.length === 0 || !value.values.every(isPrimitiveEnumValue)) return null;
|
|
34
|
+
return {
|
|
35
|
+
kind: "enum",
|
|
36
|
+
values: value.values
|
|
37
|
+
};
|
|
16
38
|
}
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
if (
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
if (value.kind === "number" || value.kind === "integer") {
|
|
40
|
+
const result = { kind: value.kind };
|
|
41
|
+
if (typeof value.min === "number" && Number.isFinite(value.min)) result.min = value.min;
|
|
42
|
+
if (typeof value.max === "number" && Number.isFinite(value.max)) result.max = value.max;
|
|
43
|
+
if (result.min !== void 0 && result.max !== void 0 && result.min > result.max) return null;
|
|
44
|
+
if (Array.isArray(value.values) && value.values.every((item) => typeof item === "number" && Number.isFinite(item))) {
|
|
45
|
+
if (value.kind === "integer" && !value.values.every(Number.isInteger)) return null;
|
|
46
|
+
const min = result.min;
|
|
47
|
+
const max = result.max;
|
|
48
|
+
if (min !== void 0 && value.values.some((item) => item < min)) return null;
|
|
49
|
+
if (max !== void 0 && value.values.some((item) => item > max)) return null;
|
|
50
|
+
result.values = value.values;
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
24
53
|
}
|
|
25
|
-
|
|
26
|
-
|
|
54
|
+
if (value.kind === "boolean") return typeof value.value === "boolean" ? {
|
|
55
|
+
kind: "boolean",
|
|
56
|
+
value: value.value
|
|
57
|
+
} : { kind: "boolean" };
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
function normalizeGenerationPolicy(value) {
|
|
61
|
+
if (!isRecord$1(value) || value.version !== 1) return null;
|
|
62
|
+
if (value.mode === "auto") return {
|
|
63
|
+
version: 1,
|
|
64
|
+
mode: "auto"
|
|
65
|
+
};
|
|
66
|
+
if (value.mode !== "limited" || !Array.isArray(value.models) || value.models.length === 0) return null;
|
|
67
|
+
const models = [];
|
|
68
|
+
for (const item of value.models) {
|
|
69
|
+
if (!isRecord$1(item) || typeof item.model !== "string" || !item.model.trim()) return null;
|
|
70
|
+
const modelPolicy = { model: item.model.trim() };
|
|
71
|
+
if (item.parameters !== void 0) {
|
|
72
|
+
if (!isRecord$1(item.parameters)) return null;
|
|
73
|
+
const parameters = {};
|
|
74
|
+
for (const [key, rawConstraint] of Object.entries(item.parameters)) {
|
|
75
|
+
if (!key.trim()) return null;
|
|
76
|
+
const constraint = normalizeConstraint(rawConstraint);
|
|
77
|
+
if (!constraint) return null;
|
|
78
|
+
parameters[key] = constraint;
|
|
79
|
+
}
|
|
80
|
+
if (Object.keys(parameters).length > 0) modelPolicy.parameters = parameters;
|
|
81
|
+
}
|
|
82
|
+
models.push(modelPolicy);
|
|
27
83
|
}
|
|
28
|
-
|
|
29
|
-
|
|
84
|
+
return {
|
|
85
|
+
version: 1,
|
|
86
|
+
mode: "limited",
|
|
87
|
+
models
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function bytesToBase64(bytes) {
|
|
91
|
+
let binary = "";
|
|
92
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
93
|
+
return btoa(binary);
|
|
94
|
+
}
|
|
95
|
+
function base64ToBytes(value) {
|
|
96
|
+
const binary = atob(value);
|
|
97
|
+
const bytes = new Uint8Array(binary.length);
|
|
98
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
99
|
+
return bytes;
|
|
100
|
+
}
|
|
101
|
+
function toBase64Url(value) {
|
|
102
|
+
return bytesToBase64(new TextEncoder().encode(value)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
103
|
+
}
|
|
104
|
+
function fromBase64Url(value) {
|
|
105
|
+
const base64 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
106
|
+
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
107
|
+
return new TextDecoder().decode(base64ToBytes(padded));
|
|
108
|
+
}
|
|
109
|
+
function encodeGenerationPolicy(policy) {
|
|
110
|
+
return toBase64Url(JSON.stringify(policy));
|
|
111
|
+
}
|
|
112
|
+
function decodeGenerationPolicy(value) {
|
|
113
|
+
try {
|
|
114
|
+
return normalizeGenerationPolicy(JSON.parse(fromBase64Url(value)));
|
|
115
|
+
} catch {
|
|
116
|
+
return null;
|
|
30
117
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
118
|
+
}
|
|
119
|
+
function parseGenerationPolicyFromEnv(env) {
|
|
120
|
+
const value = env[GENERATION_POLICY_ENV_KEY]?.trim();
|
|
121
|
+
return value ? decodeGenerationPolicy(value) : null;
|
|
122
|
+
}
|
|
123
|
+
function getAllowedGenerationModelIds(policy) {
|
|
124
|
+
if (!policy || policy.mode === "auto") return null;
|
|
125
|
+
return [...new Set((policy.models ?? []).map((item) => item.model))];
|
|
126
|
+
}
|
|
127
|
+
function findGenerationModelPolicy(policy, model) {
|
|
128
|
+
if (!policy || policy.mode === "auto") return null;
|
|
129
|
+
return policy.models?.find((item) => item.model === model) ?? null;
|
|
130
|
+
}
|
|
131
|
+
function formatList(values) {
|
|
132
|
+
return values.map((value) => `- ${String(value)}`).join("\n");
|
|
133
|
+
}
|
|
134
|
+
function modelNotSupportedMessage(allowedModels) {
|
|
135
|
+
return [
|
|
136
|
+
"This turn supports the following generation models:",
|
|
137
|
+
"",
|
|
138
|
+
formatList(allowedModels),
|
|
139
|
+
"",
|
|
140
|
+
"Choose one of these models or update Generation settings in the Models panel."
|
|
141
|
+
].join("\n");
|
|
142
|
+
}
|
|
143
|
+
function valuesNotSupportedMessage(model, name, values, received) {
|
|
144
|
+
return [
|
|
145
|
+
`This turn supports selected values for ${model}.${name}:`,
|
|
146
|
+
"",
|
|
147
|
+
formatList(values),
|
|
148
|
+
"",
|
|
149
|
+
"Received:",
|
|
150
|
+
`- ${String(received)}`
|
|
151
|
+
].join("\n");
|
|
152
|
+
}
|
|
153
|
+
function rangeNotSupportedMessage(model, name, min, max, received) {
|
|
154
|
+
return [
|
|
155
|
+
`This turn supports ${model}.${name} in the range ${min !== void 0 && max !== void 0 ? `${min}–${max}` : min !== void 0 ? `at least ${min}` : `at most ${max}`}.`,
|
|
156
|
+
"",
|
|
157
|
+
"Received:",
|
|
158
|
+
`- ${String(received)}`
|
|
159
|
+
].join("\n");
|
|
160
|
+
}
|
|
161
|
+
function booleanNotSupportedMessage(model, name, expected, received) {
|
|
162
|
+
return [
|
|
163
|
+
`This turn supports ${model}.${name}=${String(expected)}.`,
|
|
164
|
+
"",
|
|
165
|
+
"Received:",
|
|
166
|
+
`- ${String(received)}`
|
|
167
|
+
].join("\n");
|
|
168
|
+
}
|
|
169
|
+
function sameEnumValue(a, b) {
|
|
170
|
+
return typeof a === typeof b && a === b;
|
|
171
|
+
}
|
|
172
|
+
function validateConstraint(input) {
|
|
173
|
+
const { model, name, value, constraint } = input;
|
|
174
|
+
if (constraint.kind === "enum") {
|
|
175
|
+
if (!constraint.values.some((item) => sameEnumValue(item, value))) throw new GenerationPolicyError(valuesNotSupportedMessage(model, name, constraint.values, value));
|
|
176
|
+
return;
|
|
37
177
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
});
|
|
178
|
+
if (constraint.kind === "number" || constraint.kind === "integer") {
|
|
179
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
180
|
+
if (constraint.kind === "integer" && !Number.isInteger(value)) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
181
|
+
if (constraint.values?.length && !constraint.values.includes(value)) throw new GenerationPolicyError(valuesNotSupportedMessage(model, name, constraint.values, value));
|
|
182
|
+
if (constraint.min !== void 0 && value < constraint.min) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
183
|
+
if (constraint.max !== void 0 && value > constraint.max) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
184
|
+
return;
|
|
46
185
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
186
|
+
if (constraint.kind === "boolean" && constraint.value !== void 0 && value !== constraint.value) throw new GenerationPolicyError(booleanNotSupportedMessage(model, name, constraint.value, value));
|
|
187
|
+
}
|
|
188
|
+
function assertGenerationRequestAllowedByPolicy(input) {
|
|
189
|
+
const allowedModels = getAllowedGenerationModelIds(input.policy);
|
|
190
|
+
if (!allowedModels) return;
|
|
191
|
+
const modelPolicy = findGenerationModelPolicy(input.policy, input.model);
|
|
192
|
+
if (!modelPolicy) throw new GenerationPolicyError(modelNotSupportedMessage(allowedModels));
|
|
193
|
+
const parameters = input.parameters ?? {};
|
|
194
|
+
for (const [name, value] of Object.entries(parameters)) {
|
|
195
|
+
const constraint = modelPolicy.parameters?.[name];
|
|
196
|
+
if (!constraint) continue;
|
|
197
|
+
validateConstraint({
|
|
198
|
+
model: input.model,
|
|
199
|
+
name,
|
|
200
|
+
value,
|
|
201
|
+
constraint
|
|
54
202
|
});
|
|
55
203
|
}
|
|
56
|
-
|
|
57
|
-
|
|
204
|
+
}
|
|
205
|
+
function cloneDeclaration(declaration) {
|
|
206
|
+
return {
|
|
207
|
+
...declaration,
|
|
208
|
+
content: {
|
|
209
|
+
...declaration.content,
|
|
210
|
+
input: [...declaration.content.input]
|
|
211
|
+
},
|
|
212
|
+
parameters: declaration.parameters ? Object.fromEntries(Object.entries(declaration.parameters).map(([key, value]) => [key, { ...value }])) : declaration.parameters,
|
|
213
|
+
examples: declaration.examples ? [...declaration.examples] : declaration.examples
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
function narrowParameterSpec(spec, constraint) {
|
|
217
|
+
const next = { ...spec };
|
|
218
|
+
if (constraint.kind === "enum") {
|
|
219
|
+
if ("enum" in next && Array.isArray(next.enum)) next.enum = next.enum.filter((value) => constraint.values.some((allowed) => sameEnumValue(allowed, value)));
|
|
220
|
+
return next;
|
|
58
221
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
222
|
+
if (constraint.kind === "number" || constraint.kind === "integer") {
|
|
223
|
+
if ("min" in next && typeof next.min === "number" && constraint.min !== void 0) next.min = Math.max(next.min, constraint.min);
|
|
224
|
+
else if ("min" in next && constraint.min !== void 0) next.min = constraint.min;
|
|
225
|
+
if ("max" in next && typeof next.max === "number" && constraint.max !== void 0) next.max = Math.min(next.max, constraint.max);
|
|
226
|
+
else if ("max" in next && constraint.max !== void 0) next.max = constraint.max;
|
|
227
|
+
if (constraint.values?.length && "enum" in next && Array.isArray(next.enum)) next.enum = next.enum.filter((value) => constraint.values?.some((allowed) => sameEnumValue(allowed, value)));
|
|
64
228
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
229
|
+
return next;
|
|
230
|
+
}
|
|
231
|
+
function filterGenerationDeclarationsByPolicy(declarations, policy) {
|
|
232
|
+
const allowedModels = getAllowedGenerationModelIds(policy);
|
|
233
|
+
if (!allowedModels) return declarations;
|
|
234
|
+
const allowedSet = new Set(allowedModels);
|
|
235
|
+
return declarations.filter((declaration) => allowedSet.has(declaration.model)).map((declaration) => {
|
|
236
|
+
const cloned = cloneDeclaration(declaration);
|
|
237
|
+
const modelPolicy = findGenerationModelPolicy(policy, declaration.model);
|
|
238
|
+
if (!modelPolicy?.parameters || !cloned.parameters) return cloned;
|
|
239
|
+
for (const [name, constraint] of Object.entries(modelPolicy.parameters)) {
|
|
240
|
+
const spec = cloned.parameters[name];
|
|
241
|
+
if (spec) cloned.parameters[name] = narrowParameterSpec(spec, constraint);
|
|
242
|
+
}
|
|
243
|
+
return cloned;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
72
246
|
//#endregion
|
|
73
|
-
//#region ../protocol/dist/
|
|
74
|
-
const
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
247
|
+
//#region ../protocol/dist/work-surface.js
|
|
248
|
+
const WORK_SURFACE_PROTOCOL = "cohub.surface";
|
|
249
|
+
const WORK_SURFACE_READY_TIMEOUT_MS = 1e4;
|
|
250
|
+
const WORK_SURFACE_REQUEST_TIMEOUT_MS = 15e3;
|
|
251
|
+
const WORK_COMPOSER_CHIP_KEY_MAX_LENGTH = 80;
|
|
252
|
+
const WORK_COMPOSER_CHIP_LABEL_MAX_LENGTH = 120;
|
|
253
|
+
const WORK_COMPOSER_CHIP_CONTENT_MAX_BYTES = 32 * 1024;
|
|
254
|
+
const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
255
|
+
const isSurfaceEnvelope = (value) => isRecord(value) && value.protocol === "cohub.surface" && value.version === 1;
|
|
256
|
+
const parseWorkSurfaceReady = (value) => {
|
|
257
|
+
if (!isSurfaceEnvelope(value) || value.type !== "ready") return null;
|
|
258
|
+
const methods = Array.isArray(value.methods) ? value.methods.filter((method) => typeof method === "string" && Boolean(method)) : [];
|
|
259
|
+
return {
|
|
260
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
261
|
+
version: 1,
|
|
262
|
+
type: "ready",
|
|
263
|
+
methods
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
|
+
const parseWorkSurfaceResponse = (value) => {
|
|
267
|
+
if (!isSurfaceEnvelope(value) || value.type !== "response") return null;
|
|
268
|
+
if (typeof value.requestId !== "string" || !value.requestId) return null;
|
|
269
|
+
const error = isRecord(value.error) ? {
|
|
270
|
+
code: typeof value.error.code === "string" && value.error.code ? value.error.code : "surface_error",
|
|
271
|
+
message: typeof value.error.message === "string" ? value.error.message : "Work surface call failed"
|
|
272
|
+
} : void 0;
|
|
273
|
+
return {
|
|
274
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
275
|
+
version: 1,
|
|
276
|
+
type: "response",
|
|
277
|
+
requestId: value.requestId,
|
|
278
|
+
ok: value.ok === true,
|
|
279
|
+
...error ? { error } : {}
|
|
280
|
+
};
|
|
281
|
+
};
|
|
282
|
+
const parseComposerChipKey = (value) => {
|
|
283
|
+
if (typeof value !== "string") return null;
|
|
284
|
+
const key = value.trim();
|
|
285
|
+
if (!key || key.length > 80) return null;
|
|
286
|
+
return key;
|
|
287
|
+
};
|
|
288
|
+
const parseWorkComposerChipSet = (value) => {
|
|
289
|
+
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.set" || !isRecord(value.chip)) return null;
|
|
290
|
+
const key = parseComposerChipKey(value.chip.key);
|
|
291
|
+
if (!key || typeof value.chip.label !== "string" || typeof value.chip.content !== "string") return null;
|
|
292
|
+
const label = value.chip.label.trim();
|
|
293
|
+
if (!label || label.length > 120) return null;
|
|
294
|
+
if (!value.chip.content.trim()) return null;
|
|
295
|
+
if (new TextEncoder().encode(value.chip.content).length > 32768) return null;
|
|
296
|
+
return {
|
|
297
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
298
|
+
version: 1,
|
|
299
|
+
type: "composer.chip.set",
|
|
300
|
+
chip: {
|
|
301
|
+
key,
|
|
302
|
+
label,
|
|
303
|
+
content: value.chip.content
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
};
|
|
307
|
+
const parseWorkComposerChipClear = (value) => {
|
|
308
|
+
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.clear") return null;
|
|
309
|
+
const key = parseComposerChipKey(value.key);
|
|
310
|
+
return key ? {
|
|
311
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
312
|
+
version: 1,
|
|
313
|
+
type: "composer.chip.clear",
|
|
314
|
+
key
|
|
315
|
+
} : null;
|
|
316
|
+
};
|
|
317
|
+
const parseWorkSurfaceRequest = (value) => {
|
|
318
|
+
if (!isSurfaceEnvelope(value) || value.type !== "request") return null;
|
|
319
|
+
if (typeof value.requestId !== "string" || !value.requestId) return null;
|
|
320
|
+
if (typeof value.method !== "string" || !value.method) return null;
|
|
321
|
+
const commandId = parseUiCommandId(value.commandId);
|
|
322
|
+
if (!commandId) return null;
|
|
323
|
+
return {
|
|
324
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
325
|
+
version: 1,
|
|
326
|
+
type: "request",
|
|
327
|
+
requestId: value.requestId,
|
|
328
|
+
method: value.method,
|
|
329
|
+
...value.input === void 0 ? {} : { input: value.input },
|
|
330
|
+
commandId
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
const buildWorkSurfaceReady = (methods) => ({
|
|
334
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
335
|
+
version: 1,
|
|
336
|
+
type: "ready",
|
|
337
|
+
methods: [...methods]
|
|
79
338
|
});
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
height: finiteSchema$1.positive(),
|
|
86
|
-
rotation: finiteSchema$1
|
|
339
|
+
const buildWorkSurfaceRequest = (input) => ({
|
|
340
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
341
|
+
version: 1,
|
|
342
|
+
type: "request",
|
|
343
|
+
...input
|
|
87
344
|
});
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
start: BoardAwarenessPointSchema,
|
|
94
|
-
end: BoardAwarenessPointSchema,
|
|
95
|
-
bend: finiteSchema$1
|
|
96
|
-
}).optional()
|
|
345
|
+
const buildWorkSurfaceResponse = (input) => ({
|
|
346
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
347
|
+
version: 1,
|
|
348
|
+
type: "response",
|
|
349
|
+
...input
|
|
97
350
|
});
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"pen",
|
|
104
|
-
"touch"
|
|
105
|
-
]) }).nullable(),
|
|
106
|
-
tool: z.string().min(1).max(40),
|
|
107
|
-
selection: z.object({
|
|
108
|
-
ids: z.array(idSchema$1).max(64),
|
|
109
|
-
count: z.number().int().nonnegative().max(5e4),
|
|
110
|
-
bounds: BoardAwarenessFrameSchema.nullable()
|
|
111
|
-
}),
|
|
112
|
-
editingId: idSchema$1.nullable()
|
|
351
|
+
const buildWorkComposerChipSet = (chip) => ({
|
|
352
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
353
|
+
version: 1,
|
|
354
|
+
type: "composer.chip.set",
|
|
355
|
+
chip
|
|
113
356
|
});
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
color: z.string().min(1).max(64),
|
|
120
|
-
size: finiteSchema$1.positive().max(256),
|
|
121
|
-
from: z.number().int().nonnegative().max(1e5),
|
|
122
|
-
points: z.array(BoardAwarenessDrawPointSchema).min(1).max(64)
|
|
123
|
-
}),
|
|
124
|
-
z.object({
|
|
125
|
-
kind: z.literal("arrow"),
|
|
126
|
-
id: idSchema$1,
|
|
127
|
-
nodeId: idSchema$1,
|
|
128
|
-
start: BoardAwarenessPointSchema,
|
|
129
|
-
current: BoardAwarenessPointSchema,
|
|
130
|
-
color: z.string().min(1).max(64),
|
|
131
|
-
size: finiteSchema$1.positive().max(256).default(BOARD_ARROW_STROKE_SIZE)
|
|
132
|
-
}),
|
|
133
|
-
z.object({
|
|
134
|
-
kind: z.literal("box"),
|
|
135
|
-
id: idSchema$1,
|
|
136
|
-
nodeId: idSchema$1,
|
|
137
|
-
shape: z.enum(["geo", "frame"]),
|
|
138
|
-
start: BoardAwarenessPointSchema,
|
|
139
|
-
current: BoardAwarenessPointSchema,
|
|
140
|
-
color: z.string().min(1).max(64),
|
|
141
|
-
geo: z.string().min(1).max(40)
|
|
142
|
-
}),
|
|
143
|
-
z.object({
|
|
144
|
-
kind: z.literal("connection"),
|
|
145
|
-
id: idSchema$1,
|
|
146
|
-
sourceNodeId: idSchema$1,
|
|
147
|
-
targetNodeId: idSchema$1.nullable(),
|
|
148
|
-
current: BoardAwarenessPointSchema,
|
|
149
|
-
color: z.string().min(1).max(64),
|
|
150
|
-
size: finiteSchema$1.positive().max(256).default(BOARD_CONNECTION_STROKE_SIZE)
|
|
151
|
-
}),
|
|
152
|
-
z.object({
|
|
153
|
-
kind: z.literal("transform"),
|
|
154
|
-
id: idSchema$1,
|
|
155
|
-
mode: z.enum([
|
|
156
|
-
"translate",
|
|
157
|
-
"resize",
|
|
158
|
-
"rotate",
|
|
159
|
-
"arrow",
|
|
160
|
-
"connection"
|
|
161
|
-
]),
|
|
162
|
-
nodes: z.array(BoardAwarenessNodePreviewSchema).max(64),
|
|
163
|
-
bounds: BoardAwarenessFrameSchema.nullable()
|
|
164
|
-
})
|
|
165
|
-
]);
|
|
166
|
-
const BoardAwarenessUpdateSchema = z.discriminatedUnion("type", [
|
|
167
|
-
BoardAwarenessStateUpdateSchema,
|
|
168
|
-
z.object({
|
|
169
|
-
type: z.literal("gesture"),
|
|
170
|
-
gesture: BoardAwarenessGestureSchema
|
|
171
|
-
}),
|
|
172
|
-
z.object({
|
|
173
|
-
type: z.literal("gesture.end"),
|
|
174
|
-
gestureId: idSchema$1,
|
|
175
|
-
resultingNodeIds: z.array(idSchema$1).max(64)
|
|
176
|
-
}),
|
|
177
|
-
z.object({
|
|
178
|
-
type: z.literal("gesture.cancel"),
|
|
179
|
-
gestureId: idSchema$1
|
|
180
|
-
})
|
|
181
|
-
]);
|
|
182
|
-
const BoardAwarenessClientPayloadSchema = z.object({
|
|
183
|
-
spaceId: z.string().uuid(),
|
|
184
|
-
boardId: z.string().uuid(),
|
|
185
|
-
seq: z.number().int().nonnegative(),
|
|
186
|
-
update: BoardAwarenessUpdateSchema
|
|
357
|
+
const buildWorkComposerChipClear = (key) => ({
|
|
358
|
+
protocol: WORK_SURFACE_PROTOCOL,
|
|
359
|
+
version: 1,
|
|
360
|
+
type: "composer.chip.clear",
|
|
361
|
+
key
|
|
187
362
|
});
|
|
188
363
|
//#endregion
|
|
364
|
+
//#region src/apis/billing.ts
|
|
365
|
+
var BillingApi = class {
|
|
366
|
+
transport;
|
|
367
|
+
constructor(transport) {
|
|
368
|
+
this.transport = transport;
|
|
369
|
+
}
|
|
370
|
+
async getCredits(input) {
|
|
371
|
+
const query = input?.tokenType ? `?tokenType=${encodeURIComponent(input.tokenType)}` : "";
|
|
372
|
+
return this.transport.request(`/api/billing/credits${query}`);
|
|
373
|
+
}
|
|
374
|
+
async getBalanceActivities(input) {
|
|
375
|
+
const params = new URLSearchParams();
|
|
376
|
+
if (input?.tokenType) params.set("tokenType", input.tokenType);
|
|
377
|
+
if (input?.page) params.set("page", String(input.page));
|
|
378
|
+
if (input?.limit) params.set("limit", String(input.limit));
|
|
379
|
+
const query = params.toString();
|
|
380
|
+
return this.transport.request(`/api/billing/balance-activities${query ? `?${query}` : ""}`);
|
|
381
|
+
}
|
|
382
|
+
async getCatalog() {
|
|
383
|
+
return this.transport.request("/api/billing/catalog");
|
|
384
|
+
}
|
|
385
|
+
async getFeatureEntitlement(featureKey) {
|
|
386
|
+
return this.transport.request(`/api/billing/features/${encodeURIComponent(featureKey)}`);
|
|
387
|
+
}
|
|
388
|
+
async getSubscriptions(input) {
|
|
389
|
+
const params = new URLSearchParams();
|
|
390
|
+
if (input?.page) params.set("page", String(input.page));
|
|
391
|
+
if (input?.limit) params.set("limit", String(input.limit));
|
|
392
|
+
const query = params.toString();
|
|
393
|
+
return this.transport.request(`/api/billing/subscriptions${query ? `?${query}` : ""}`);
|
|
394
|
+
}
|
|
395
|
+
async previewPromotionCode(input) {
|
|
396
|
+
return this.transport.request("/api/billing/promotion-code-preview", {
|
|
397
|
+
method: "POST",
|
|
398
|
+
body: JSON.stringify(input)
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
async createOrder(productKey, input) {
|
|
402
|
+
return this.transport.request("/api/billing/orders", {
|
|
403
|
+
method: "POST",
|
|
404
|
+
body: JSON.stringify({
|
|
405
|
+
...input ?? {},
|
|
406
|
+
productKey
|
|
407
|
+
})
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
async createSubscription(productKey, input) {
|
|
411
|
+
return this.transport.request("/api/billing/subscriptions", {
|
|
412
|
+
method: "POST",
|
|
413
|
+
body: JSON.stringify({
|
|
414
|
+
...input ?? {},
|
|
415
|
+
productKey
|
|
416
|
+
})
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
async cancelSubscriptionCheckout(subscriptionId) {
|
|
420
|
+
return this.transport.request(`/api/billing/subscriptions/${encodeURIComponent(subscriptionId)}/checkout`, { method: "DELETE" });
|
|
421
|
+
}
|
|
422
|
+
async cancelSubscriptionAutoRenew(subscriptionId) {
|
|
423
|
+
return this.transport.request(`/api/billing/subscriptions/${encodeURIComponent(subscriptionId)}`, {
|
|
424
|
+
method: "PATCH",
|
|
425
|
+
body: JSON.stringify({ cancelAtPeriodEnd: true })
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
async createRedemption(input) {
|
|
429
|
+
return this.transport.request("/api/billing/redemptions", {
|
|
430
|
+
method: "POST",
|
|
431
|
+
body: JSON.stringify(input)
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
//#endregion
|
|
189
436
|
//#region ../protocol/dist/realtime/schema.js
|
|
190
437
|
const contentBlockMetaSchema = z.record(z.string(), z.unknown());
|
|
191
438
|
const realtimeRoomSchema = z.string().regex(/^(space|user|board|room):[^:]+$/);
|
|
@@ -796,145 +1043,31 @@ var WorkRealtimeApi = class {
|
|
|
796
1043
|
}
|
|
797
1044
|
};
|
|
798
1045
|
//#endregion
|
|
799
|
-
//#region
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
} : void 0;
|
|
825
|
-
return {
|
|
826
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
827
|
-
version: 1,
|
|
828
|
-
type: "response",
|
|
829
|
-
requestId: value.requestId,
|
|
830
|
-
ok: value.ok === true,
|
|
831
|
-
...error ? { error } : {}
|
|
832
|
-
};
|
|
833
|
-
};
|
|
834
|
-
const parseComposerChipKey = (value) => {
|
|
835
|
-
if (typeof value !== "string") return null;
|
|
836
|
-
const key = value.trim();
|
|
837
|
-
if (!key || key.length > 80) return null;
|
|
838
|
-
return key;
|
|
839
|
-
};
|
|
840
|
-
const parseWorkComposerChipSet = (value) => {
|
|
841
|
-
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.set" || !isRecord$1(value.chip)) return null;
|
|
842
|
-
const key = parseComposerChipKey(value.chip.key);
|
|
843
|
-
if (!key || typeof value.chip.label !== "string" || typeof value.chip.content !== "string") return null;
|
|
844
|
-
const label = value.chip.label.trim();
|
|
845
|
-
if (!label || label.length > 120) return null;
|
|
846
|
-
if (!value.chip.content.trim()) return null;
|
|
847
|
-
if (new TextEncoder().encode(value.chip.content).length > 32768) return null;
|
|
848
|
-
return {
|
|
849
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
850
|
-
version: 1,
|
|
851
|
-
type: "composer.chip.set",
|
|
852
|
-
chip: {
|
|
853
|
-
key,
|
|
854
|
-
label,
|
|
855
|
-
content: value.chip.content
|
|
856
|
-
}
|
|
857
|
-
};
|
|
858
|
-
};
|
|
859
|
-
const parseWorkComposerChipClear = (value) => {
|
|
860
|
-
if (!isSurfaceEnvelope(value) || value.type !== "composer.chip.clear") return null;
|
|
861
|
-
const key = parseComposerChipKey(value.key);
|
|
862
|
-
return key ? {
|
|
863
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
864
|
-
version: 1,
|
|
865
|
-
type: "composer.chip.clear",
|
|
866
|
-
key
|
|
867
|
-
} : null;
|
|
868
|
-
};
|
|
869
|
-
const parseWorkSurfaceRequest = (value) => {
|
|
870
|
-
if (!isSurfaceEnvelope(value) || value.type !== "request") return null;
|
|
871
|
-
if (typeof value.requestId !== "string" || !value.requestId) return null;
|
|
872
|
-
if (typeof value.method !== "string" || !value.method) return null;
|
|
873
|
-
const commandId = parseUiCommandId(value.commandId);
|
|
874
|
-
if (!commandId) return null;
|
|
875
|
-
return {
|
|
876
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
877
|
-
version: 1,
|
|
878
|
-
type: "request",
|
|
879
|
-
requestId: value.requestId,
|
|
880
|
-
method: value.method,
|
|
881
|
-
...value.input === void 0 ? {} : { input: value.input },
|
|
882
|
-
commandId
|
|
883
|
-
};
|
|
884
|
-
};
|
|
885
|
-
const buildWorkSurfaceReady = (methods) => ({
|
|
886
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
887
|
-
version: 1,
|
|
888
|
-
type: "ready",
|
|
889
|
-
methods: [...methods]
|
|
890
|
-
});
|
|
891
|
-
const buildWorkSurfaceRequest = (input) => ({
|
|
892
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
893
|
-
version: 1,
|
|
894
|
-
type: "request",
|
|
895
|
-
...input
|
|
896
|
-
});
|
|
897
|
-
const buildWorkSurfaceResponse = (input) => ({
|
|
898
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
899
|
-
version: 1,
|
|
900
|
-
type: "response",
|
|
901
|
-
...input
|
|
902
|
-
});
|
|
903
|
-
const buildWorkComposerChipSet = (chip) => ({
|
|
904
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
905
|
-
version: 1,
|
|
906
|
-
type: "composer.chip.set",
|
|
907
|
-
chip
|
|
908
|
-
});
|
|
909
|
-
const buildWorkComposerChipClear = (key) => ({
|
|
910
|
-
protocol: WORK_SURFACE_PROTOCOL,
|
|
911
|
-
version: 1,
|
|
912
|
-
type: "composer.chip.clear",
|
|
913
|
-
key
|
|
914
|
-
});
|
|
915
|
-
//#endregion
|
|
916
|
-
//#region src/work-surface.ts
|
|
917
|
-
/**
|
|
918
|
-
* Explicit app origins, not a `*.cohub.run` suffix match: Works themselves are
|
|
919
|
-
* served from Cohub subdomains, so a suffix match would let one Work call into
|
|
920
|
-
* another and turn a subdomain takeover into surface access.
|
|
921
|
-
*/
|
|
922
|
-
const COHUB_APP_ORIGINS = [
|
|
923
|
-
"https://cohub.run",
|
|
924
|
-
"https://www.cohub.run",
|
|
925
|
-
"https://dev.cohub.run"
|
|
926
|
-
];
|
|
927
|
-
const isCohubHostOrigin = (origin) => COHUB_APP_ORIGINS.includes(origin);
|
|
928
|
-
const resolveEmbedderOrigin = () => {
|
|
929
|
-
if (typeof window === "undefined" || window.parent === window) return null;
|
|
930
|
-
const ancestor = window.location?.ancestorOrigins?.[0];
|
|
931
|
-
if (typeof ancestor === "string" && ancestor) return ancestor;
|
|
932
|
-
try {
|
|
933
|
-
const referrer = typeof document === "undefined" ? "" : document.referrer;
|
|
934
|
-
return referrer ? new URL(referrer).origin : null;
|
|
935
|
-
} catch {
|
|
936
|
-
return null;
|
|
937
|
-
}
|
|
1046
|
+
//#region src/work-surface.ts
|
|
1047
|
+
/**
|
|
1048
|
+
* Explicit app origins, not a Cohub suffix match: Works themselves are
|
|
1049
|
+
* served from Cohub subdomains, so a suffix match would let one Work call into
|
|
1050
|
+
* another and turn a subdomain takeover into surface access.
|
|
1051
|
+
*/
|
|
1052
|
+
const COHUB_APP_ORIGINS = [
|
|
1053
|
+
"https://cohub.live",
|
|
1054
|
+
"https://www.cohub.live",
|
|
1055
|
+
"https://dev.cohub.live",
|
|
1056
|
+
"https://cohub.run",
|
|
1057
|
+
"https://www.cohub.run",
|
|
1058
|
+
"https://dev.cohub.run"
|
|
1059
|
+
];
|
|
1060
|
+
const isCohubHostOrigin = (origin) => COHUB_APP_ORIGINS.includes(origin);
|
|
1061
|
+
const resolveEmbedderOrigin = () => {
|
|
1062
|
+
if (typeof window === "undefined" || window.parent === window) return null;
|
|
1063
|
+
const ancestor = window.location?.ancestorOrigins?.[0];
|
|
1064
|
+
if (typeof ancestor === "string" && ancestor) return ancestor;
|
|
1065
|
+
try {
|
|
1066
|
+
const referrer = typeof document === "undefined" ? "" : document.referrer;
|
|
1067
|
+
return referrer ? new URL(referrer).origin : null;
|
|
1068
|
+
} catch {
|
|
1069
|
+
return null;
|
|
1070
|
+
}
|
|
938
1071
|
};
|
|
939
1072
|
var WorkSurfaceApi = class {
|
|
940
1073
|
handlers = /* @__PURE__ */ new Map();
|
|
@@ -1607,55 +1740,6 @@ var CohubClient = class {
|
|
|
1607
1740
|
};
|
|
1608
1741
|
const createCohubClient = (options) => new CohubClient(options);
|
|
1609
1742
|
//#endregion
|
|
1610
|
-
//#region ../protocol/dist/public-identifiers.js
|
|
1611
|
-
const USERNAME_PATTERN = /^(?!-)(?!.*--)[a-z0-9-]{1,39}(?<!-)$/;
|
|
1612
|
-
const SPACE_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9_-]{0,78}[a-z0-9])?$/;
|
|
1613
|
-
/**
|
|
1614
|
-
* Platform-owned path segments that must not be newly assigned to public
|
|
1615
|
-
* identities. Existing stored values remain readable through parse helpers.
|
|
1616
|
-
*/
|
|
1617
|
-
const RESERVED_PLATFORM_PATH_SEGMENTS = Object.freeze([
|
|
1618
|
-
"admin",
|
|
1619
|
-
"api",
|
|
1620
|
-
"assets",
|
|
1621
|
-
"auth",
|
|
1622
|
-
"callback",
|
|
1623
|
-
"changelog",
|
|
1624
|
-
"docs",
|
|
1625
|
-
"explore",
|
|
1626
|
-
"invite",
|
|
1627
|
-
"landing",
|
|
1628
|
-
"login",
|
|
1629
|
-
"logout",
|
|
1630
|
-
"new",
|
|
1631
|
-
"org",
|
|
1632
|
-
"pricing",
|
|
1633
|
-
"pwa",
|
|
1634
|
-
"referrals",
|
|
1635
|
-
"sessions",
|
|
1636
|
-
"settings",
|
|
1637
|
-
"spaces",
|
|
1638
|
-
"static",
|
|
1639
|
-
"teams",
|
|
1640
|
-
"trending",
|
|
1641
|
-
"u",
|
|
1642
|
-
"user",
|
|
1643
|
-
"users",
|
|
1644
|
-
"work-auth"
|
|
1645
|
-
]);
|
|
1646
|
-
new Set(RESERVED_PLATFORM_PATH_SEGMENTS);
|
|
1647
|
-
[...RESERVED_PLATFORM_PATH_SEGMENTS];
|
|
1648
|
-
function parseUsername(value) {
|
|
1649
|
-
if (value === null || value === void 0) return null;
|
|
1650
|
-
const normalized = value.trim().toLowerCase();
|
|
1651
|
-
return USERNAME_PATTERN.test(normalized) ? normalized : null;
|
|
1652
|
-
}
|
|
1653
|
-
function parseSpaceSlug(value) {
|
|
1654
|
-
if (value === null || value === void 0) return null;
|
|
1655
|
-
const normalized = value.trim();
|
|
1656
|
-
return SPACE_SLUG_PATTERN.test(normalized) ? normalized : null;
|
|
1657
|
-
}
|
|
1658
|
-
//#endregion
|
|
1659
1743
|
//#region src/work-ref.ts
|
|
1660
1744
|
/**
|
|
1661
1745
|
* Accepts every way a Work is named across Cohub — id, management URL, public
|
|
@@ -2166,440 +2250,6 @@ function createWorkBridgeCore(config) {
|
|
|
2166
2250
|
};
|
|
2167
2251
|
}
|
|
2168
2252
|
//#endregion
|
|
2169
|
-
//#region ../protocol/dist/generation/catalog.js
|
|
2170
|
-
function isGenerationModelHidden(model) {
|
|
2171
|
-
return model.hidden === true;
|
|
2172
|
-
}
|
|
2173
|
-
function filterDiscoverableGenerationModels(models, options = {}) {
|
|
2174
|
-
const includeModelIds = new Set(options.includeModelIds);
|
|
2175
|
-
return models.filter((model) => !isGenerationModelHidden(model) || includeModelIds.has(model.model));
|
|
2176
|
-
}
|
|
2177
|
-
//#endregion
|
|
2178
|
-
//#region ../protocol/dist/generation/policy.js
|
|
2179
|
-
const GENERATION_POLICY_ENV_KEY = "COHUB_GENERATION_POLICY_B64";
|
|
2180
|
-
var GenerationPolicyError = class extends Error {
|
|
2181
|
-
constructor(message) {
|
|
2182
|
-
super(message);
|
|
2183
|
-
this.name = "GenerationPolicyError";
|
|
2184
|
-
}
|
|
2185
|
-
};
|
|
2186
|
-
function isRecord(value) {
|
|
2187
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2188
|
-
}
|
|
2189
|
-
function isPrimitiveEnumValue(value) {
|
|
2190
|
-
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
2191
|
-
}
|
|
2192
|
-
function normalizeConstraint(value) {
|
|
2193
|
-
if (!isRecord(value) || typeof value.kind !== "string") return null;
|
|
2194
|
-
if (value.kind === "enum") {
|
|
2195
|
-
if (!Array.isArray(value.values) || value.values.length === 0 || !value.values.every(isPrimitiveEnumValue)) return null;
|
|
2196
|
-
return {
|
|
2197
|
-
kind: "enum",
|
|
2198
|
-
values: value.values
|
|
2199
|
-
};
|
|
2200
|
-
}
|
|
2201
|
-
if (value.kind === "number" || value.kind === "integer") {
|
|
2202
|
-
const result = { kind: value.kind };
|
|
2203
|
-
if (typeof value.min === "number" && Number.isFinite(value.min)) result.min = value.min;
|
|
2204
|
-
if (typeof value.max === "number" && Number.isFinite(value.max)) result.max = value.max;
|
|
2205
|
-
if (result.min !== void 0 && result.max !== void 0 && result.min > result.max) return null;
|
|
2206
|
-
if (Array.isArray(value.values) && value.values.every((item) => typeof item === "number" && Number.isFinite(item))) {
|
|
2207
|
-
if (value.kind === "integer" && !value.values.every(Number.isInteger)) return null;
|
|
2208
|
-
const min = result.min;
|
|
2209
|
-
const max = result.max;
|
|
2210
|
-
if (min !== void 0 && value.values.some((item) => item < min)) return null;
|
|
2211
|
-
if (max !== void 0 && value.values.some((item) => item > max)) return null;
|
|
2212
|
-
result.values = value.values;
|
|
2213
|
-
}
|
|
2214
|
-
return result;
|
|
2215
|
-
}
|
|
2216
|
-
if (value.kind === "boolean") return typeof value.value === "boolean" ? {
|
|
2217
|
-
kind: "boolean",
|
|
2218
|
-
value: value.value
|
|
2219
|
-
} : { kind: "boolean" };
|
|
2220
|
-
return null;
|
|
2221
|
-
}
|
|
2222
|
-
function normalizeGenerationPolicy(value) {
|
|
2223
|
-
if (!isRecord(value) || value.version !== 1) return null;
|
|
2224
|
-
if (value.mode === "auto") return {
|
|
2225
|
-
version: 1,
|
|
2226
|
-
mode: "auto"
|
|
2227
|
-
};
|
|
2228
|
-
if (value.mode !== "limited" || !Array.isArray(value.models) || value.models.length === 0) return null;
|
|
2229
|
-
const models = [];
|
|
2230
|
-
for (const item of value.models) {
|
|
2231
|
-
if (!isRecord(item) || typeof item.model !== "string" || !item.model.trim()) return null;
|
|
2232
|
-
const modelPolicy = { model: item.model.trim() };
|
|
2233
|
-
if (item.parameters !== void 0) {
|
|
2234
|
-
if (!isRecord(item.parameters)) return null;
|
|
2235
|
-
const parameters = {};
|
|
2236
|
-
for (const [key, rawConstraint] of Object.entries(item.parameters)) {
|
|
2237
|
-
if (!key.trim()) return null;
|
|
2238
|
-
const constraint = normalizeConstraint(rawConstraint);
|
|
2239
|
-
if (!constraint) return null;
|
|
2240
|
-
parameters[key] = constraint;
|
|
2241
|
-
}
|
|
2242
|
-
if (Object.keys(parameters).length > 0) modelPolicy.parameters = parameters;
|
|
2243
|
-
}
|
|
2244
|
-
models.push(modelPolicy);
|
|
2245
|
-
}
|
|
2246
|
-
return {
|
|
2247
|
-
version: 1,
|
|
2248
|
-
mode: "limited",
|
|
2249
|
-
models
|
|
2250
|
-
};
|
|
2251
|
-
}
|
|
2252
|
-
function bytesToBase64(bytes) {
|
|
2253
|
-
let binary = "";
|
|
2254
|
-
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
2255
|
-
return btoa(binary);
|
|
2256
|
-
}
|
|
2257
|
-
function base64ToBytes(value) {
|
|
2258
|
-
const binary = atob(value);
|
|
2259
|
-
const bytes = new Uint8Array(binary.length);
|
|
2260
|
-
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
2261
|
-
return bytes;
|
|
2262
|
-
}
|
|
2263
|
-
function toBase64Url(value) {
|
|
2264
|
-
return bytesToBase64(new TextEncoder().encode(value)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");
|
|
2265
|
-
}
|
|
2266
|
-
function fromBase64Url(value) {
|
|
2267
|
-
const base64 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
2268
|
-
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
2269
|
-
return new TextDecoder().decode(base64ToBytes(padded));
|
|
2270
|
-
}
|
|
2271
|
-
function encodeGenerationPolicy(policy) {
|
|
2272
|
-
return toBase64Url(JSON.stringify(policy));
|
|
2273
|
-
}
|
|
2274
|
-
function decodeGenerationPolicy(value) {
|
|
2275
|
-
try {
|
|
2276
|
-
return normalizeGenerationPolicy(JSON.parse(fromBase64Url(value)));
|
|
2277
|
-
} catch {
|
|
2278
|
-
return null;
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
function parseGenerationPolicyFromEnv(env) {
|
|
2282
|
-
const value = env[GENERATION_POLICY_ENV_KEY]?.trim();
|
|
2283
|
-
return value ? decodeGenerationPolicy(value) : null;
|
|
2284
|
-
}
|
|
2285
|
-
function getAllowedGenerationModelIds(policy) {
|
|
2286
|
-
if (!policy || policy.mode === "auto") return null;
|
|
2287
|
-
return [...new Set((policy.models ?? []).map((item) => item.model))];
|
|
2288
|
-
}
|
|
2289
|
-
function findGenerationModelPolicy(policy, model) {
|
|
2290
|
-
if (!policy || policy.mode === "auto") return null;
|
|
2291
|
-
return policy.models?.find((item) => item.model === model) ?? null;
|
|
2292
|
-
}
|
|
2293
|
-
function formatList(values) {
|
|
2294
|
-
return values.map((value) => `- ${String(value)}`).join("\n");
|
|
2295
|
-
}
|
|
2296
|
-
function modelNotSupportedMessage(allowedModels) {
|
|
2297
|
-
return [
|
|
2298
|
-
"This turn supports the following generation models:",
|
|
2299
|
-
"",
|
|
2300
|
-
formatList(allowedModels),
|
|
2301
|
-
"",
|
|
2302
|
-
"Choose one of these models or update Generation settings in the Models panel."
|
|
2303
|
-
].join("\n");
|
|
2304
|
-
}
|
|
2305
|
-
function valuesNotSupportedMessage(model, name, values, received) {
|
|
2306
|
-
return [
|
|
2307
|
-
`This turn supports selected values for ${model}.${name}:`,
|
|
2308
|
-
"",
|
|
2309
|
-
formatList(values),
|
|
2310
|
-
"",
|
|
2311
|
-
"Received:",
|
|
2312
|
-
`- ${String(received)}`
|
|
2313
|
-
].join("\n");
|
|
2314
|
-
}
|
|
2315
|
-
function rangeNotSupportedMessage(model, name, min, max, received) {
|
|
2316
|
-
return [
|
|
2317
|
-
`This turn supports ${model}.${name} in the range ${min !== void 0 && max !== void 0 ? `${min}–${max}` : min !== void 0 ? `at least ${min}` : `at most ${max}`}.`,
|
|
2318
|
-
"",
|
|
2319
|
-
"Received:",
|
|
2320
|
-
`- ${String(received)}`
|
|
2321
|
-
].join("\n");
|
|
2322
|
-
}
|
|
2323
|
-
function booleanNotSupportedMessage(model, name, expected, received) {
|
|
2324
|
-
return [
|
|
2325
|
-
`This turn supports ${model}.${name}=${String(expected)}.`,
|
|
2326
|
-
"",
|
|
2327
|
-
"Received:",
|
|
2328
|
-
`- ${String(received)}`
|
|
2329
|
-
].join("\n");
|
|
2330
|
-
}
|
|
2331
|
-
function sameEnumValue(a, b) {
|
|
2332
|
-
return typeof a === typeof b && a === b;
|
|
2333
|
-
}
|
|
2334
|
-
function validateConstraint(input) {
|
|
2335
|
-
const { model, name, value, constraint } = input;
|
|
2336
|
-
if (constraint.kind === "enum") {
|
|
2337
|
-
if (!constraint.values.some((item) => sameEnumValue(item, value))) throw new GenerationPolicyError(valuesNotSupportedMessage(model, name, constraint.values, value));
|
|
2338
|
-
return;
|
|
2339
|
-
}
|
|
2340
|
-
if (constraint.kind === "number" || constraint.kind === "integer") {
|
|
2341
|
-
if (typeof value !== "number" || !Number.isFinite(value)) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
2342
|
-
if (constraint.kind === "integer" && !Number.isInteger(value)) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
2343
|
-
if (constraint.values?.length && !constraint.values.includes(value)) throw new GenerationPolicyError(valuesNotSupportedMessage(model, name, constraint.values, value));
|
|
2344
|
-
if (constraint.min !== void 0 && value < constraint.min) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
2345
|
-
if (constraint.max !== void 0 && value > constraint.max) throw new GenerationPolicyError(rangeNotSupportedMessage(model, name, constraint.min, constraint.max, value));
|
|
2346
|
-
return;
|
|
2347
|
-
}
|
|
2348
|
-
if (constraint.kind === "boolean" && constraint.value !== void 0 && value !== constraint.value) throw new GenerationPolicyError(booleanNotSupportedMessage(model, name, constraint.value, value));
|
|
2349
|
-
}
|
|
2350
|
-
function assertGenerationRequestAllowedByPolicy(input) {
|
|
2351
|
-
const allowedModels = getAllowedGenerationModelIds(input.policy);
|
|
2352
|
-
if (!allowedModels) return;
|
|
2353
|
-
const modelPolicy = findGenerationModelPolicy(input.policy, input.model);
|
|
2354
|
-
if (!modelPolicy) throw new GenerationPolicyError(modelNotSupportedMessage(allowedModels));
|
|
2355
|
-
const parameters = input.parameters ?? {};
|
|
2356
|
-
for (const [name, value] of Object.entries(parameters)) {
|
|
2357
|
-
const constraint = modelPolicy.parameters?.[name];
|
|
2358
|
-
if (!constraint) continue;
|
|
2359
|
-
validateConstraint({
|
|
2360
|
-
model: input.model,
|
|
2361
|
-
name,
|
|
2362
|
-
value,
|
|
2363
|
-
constraint
|
|
2364
|
-
});
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
function cloneDeclaration(declaration) {
|
|
2368
|
-
return {
|
|
2369
|
-
...declaration,
|
|
2370
|
-
content: {
|
|
2371
|
-
...declaration.content,
|
|
2372
|
-
input: [...declaration.content.input]
|
|
2373
|
-
},
|
|
2374
|
-
parameters: declaration.parameters ? Object.fromEntries(Object.entries(declaration.parameters).map(([key, value]) => [key, { ...value }])) : declaration.parameters,
|
|
2375
|
-
examples: declaration.examples ? [...declaration.examples] : declaration.examples
|
|
2376
|
-
};
|
|
2377
|
-
}
|
|
2378
|
-
function narrowParameterSpec(spec, constraint) {
|
|
2379
|
-
const next = { ...spec };
|
|
2380
|
-
if (constraint.kind === "enum") {
|
|
2381
|
-
if ("enum" in next && Array.isArray(next.enum)) next.enum = next.enum.filter((value) => constraint.values.some((allowed) => sameEnumValue(allowed, value)));
|
|
2382
|
-
return next;
|
|
2383
|
-
}
|
|
2384
|
-
if (constraint.kind === "number" || constraint.kind === "integer") {
|
|
2385
|
-
if ("min" in next && typeof next.min === "number" && constraint.min !== void 0) next.min = Math.max(next.min, constraint.min);
|
|
2386
|
-
else if ("min" in next && constraint.min !== void 0) next.min = constraint.min;
|
|
2387
|
-
if ("max" in next && typeof next.max === "number" && constraint.max !== void 0) next.max = Math.min(next.max, constraint.max);
|
|
2388
|
-
else if ("max" in next && constraint.max !== void 0) next.max = constraint.max;
|
|
2389
|
-
if (constraint.values?.length && "enum" in next && Array.isArray(next.enum)) next.enum = next.enum.filter((value) => constraint.values?.some((allowed) => sameEnumValue(allowed, value)));
|
|
2390
|
-
}
|
|
2391
|
-
return next;
|
|
2392
|
-
}
|
|
2393
|
-
function filterGenerationDeclarationsByPolicy(declarations, policy) {
|
|
2394
|
-
const allowedModels = getAllowedGenerationModelIds(policy);
|
|
2395
|
-
if (!allowedModels) return declarations;
|
|
2396
|
-
const allowedSet = new Set(allowedModels);
|
|
2397
|
-
return declarations.filter((declaration) => allowedSet.has(declaration.model)).map((declaration) => {
|
|
2398
|
-
const cloned = cloneDeclaration(declaration);
|
|
2399
|
-
const modelPolicy = findGenerationModelPolicy(policy, declaration.model);
|
|
2400
|
-
if (!modelPolicy?.parameters || !cloned.parameters) return cloned;
|
|
2401
|
-
for (const [name, constraint] of Object.entries(modelPolicy.parameters)) {
|
|
2402
|
-
const spec = cloned.parameters[name];
|
|
2403
|
-
if (spec) cloned.parameters[name] = narrowParameterSpec(spec, constraint);
|
|
2404
|
-
}
|
|
2405
|
-
return cloned;
|
|
2406
|
-
});
|
|
2407
|
-
}
|
|
2408
|
-
//#endregion
|
|
2409
|
-
//#region ../protocol/dist/board.js
|
|
2410
|
-
const BOARD_MANIFEST_KIND = "cohub.board.manifest";
|
|
2411
|
-
const idSchema = z.string().min(1).max(160);
|
|
2412
|
-
const extensionIdSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/).max(160);
|
|
2413
|
-
const jsonObjectSchema = z.record(z.string(), z.unknown());
|
|
2414
|
-
const finiteSchema = z.number().finite();
|
|
2415
|
-
z.object({
|
|
2416
|
-
kind: z.literal(BOARD_MANIFEST_KIND),
|
|
2417
|
-
version: z.literal(1),
|
|
2418
|
-
boardId: z.string().uuid(),
|
|
2419
|
-
title: z.string().min(1).max(255)
|
|
2420
|
-
});
|
|
2421
|
-
const BoardTargetSchema = z.discriminatedUnion("type", [
|
|
2422
|
-
z.object({
|
|
2423
|
-
type: z.literal("node"),
|
|
2424
|
-
nodeId: idSchema
|
|
2425
|
-
}),
|
|
2426
|
-
z.object({
|
|
2427
|
-
type: z.literal("effect"),
|
|
2428
|
-
effectId: idSchema
|
|
2429
|
-
}),
|
|
2430
|
-
z.object({ type: z.literal("board") }),
|
|
2431
|
-
z.object({ type: z.literal("camera") })
|
|
2432
|
-
]);
|
|
2433
|
-
const BoardAssetRefSchema = z.object({
|
|
2434
|
-
type: z.enum(["space-file", "extension"]),
|
|
2435
|
-
ref: z.string().min(1).max(4096),
|
|
2436
|
-
digest: z.string().min(16).max(160).optional()
|
|
2437
|
-
});
|
|
2438
|
-
const BoardKeyframeSchema = z.object({
|
|
2439
|
-
at: finiteSchema.nonnegative(),
|
|
2440
|
-
value: z.unknown(),
|
|
2441
|
-
easing: z.string().min(1).max(80).optional()
|
|
2442
|
-
});
|
|
2443
|
-
const BoardClipSchema = z.object({
|
|
2444
|
-
id: idSchema,
|
|
2445
|
-
sequenceId: idSchema,
|
|
2446
|
-
kind: extensionIdSchema,
|
|
2447
|
-
kindVersion: z.number().int().positive(),
|
|
2448
|
-
target: BoardTargetSchema,
|
|
2449
|
-
start: finiteSchema.nonnegative(),
|
|
2450
|
-
duration: finiteSchema.positive(),
|
|
2451
|
-
layer: z.enum([
|
|
2452
|
-
"behind",
|
|
2453
|
-
"content",
|
|
2454
|
-
"front",
|
|
2455
|
-
"screen"
|
|
2456
|
-
]).default("content"),
|
|
2457
|
-
fill: z.enum([
|
|
2458
|
-
"none",
|
|
2459
|
-
"backwards",
|
|
2460
|
-
"forwards",
|
|
2461
|
-
"both"
|
|
2462
|
-
]).default("none"),
|
|
2463
|
-
easing: z.string().min(1).max(80).default("linear"),
|
|
2464
|
-
params: jsonObjectSchema.default({}),
|
|
2465
|
-
keyframes: z.array(BoardKeyframeSchema).default([]),
|
|
2466
|
-
assetRefs: z.array(BoardAssetRefSchema).default([]),
|
|
2467
|
-
seed: z.string().min(1).max(160),
|
|
2468
|
-
metadata: jsonObjectSchema.default({})
|
|
2469
|
-
});
|
|
2470
|
-
const BoardEffectSchema = z.object({
|
|
2471
|
-
id: idSchema,
|
|
2472
|
-
boardId: z.string().uuid(),
|
|
2473
|
-
target: z.discriminatedUnion("type", [z.object({
|
|
2474
|
-
type: z.literal("node"),
|
|
2475
|
-
nodeId: idSchema
|
|
2476
|
-
}), z.object({ type: z.literal("board") })]),
|
|
2477
|
-
kind: extensionIdSchema,
|
|
2478
|
-
kindVersion: z.number().int().positive(),
|
|
2479
|
-
enabled: z.boolean().default(true),
|
|
2480
|
-
lifecycle: z.enum([
|
|
2481
|
-
"persistent",
|
|
2482
|
-
"when-visible",
|
|
2483
|
-
"manual"
|
|
2484
|
-
]),
|
|
2485
|
-
timeOrigin: z.enum([
|
|
2486
|
-
"board",
|
|
2487
|
-
"visible",
|
|
2488
|
-
"activation"
|
|
2489
|
-
]),
|
|
2490
|
-
layer: z.enum([
|
|
2491
|
-
"behind",
|
|
2492
|
-
"front",
|
|
2493
|
-
"screen"
|
|
2494
|
-
]).default("front"),
|
|
2495
|
-
seed: z.string().min(1).max(160),
|
|
2496
|
-
params: jsonObjectSchema.default({}),
|
|
2497
|
-
assetRefs: z.array(BoardAssetRefSchema).default([]),
|
|
2498
|
-
metadata: jsonObjectSchema.default({}),
|
|
2499
|
-
revision: z.number().int().nonnegative()
|
|
2500
|
-
});
|
|
2501
|
-
const BoardSequenceSchema = z.object({
|
|
2502
|
-
id: idSchema,
|
|
2503
|
-
boardId: z.string().uuid(),
|
|
2504
|
-
name: z.string().min(1).max(255),
|
|
2505
|
-
duration: finiteSchema.nonnegative(),
|
|
2506
|
-
seed: z.string().min(1).max(160),
|
|
2507
|
-
restPose: jsonObjectSchema.default({}),
|
|
2508
|
-
metadata: jsonObjectSchema.default({}),
|
|
2509
|
-
revision: z.number().int().nonnegative()
|
|
2510
|
-
});
|
|
2511
|
-
const BoardNodeInputSchema = z.object({
|
|
2512
|
-
nodeId: idSchema,
|
|
2513
|
-
type: z.string().min(1).max(40),
|
|
2514
|
-
parentId: idSchema.nullable(),
|
|
2515
|
-
orderKey: z.string().max(4096).nullable(),
|
|
2516
|
-
x: finiteSchema,
|
|
2517
|
-
y: finiteSchema,
|
|
2518
|
-
width: finiteSchema.positive(),
|
|
2519
|
-
height: finiteSchema.positive(),
|
|
2520
|
-
rotation: finiteSchema,
|
|
2521
|
-
refKind: z.string().max(40).nullable(),
|
|
2522
|
-
refPath: z.string().max(4096).nullable(),
|
|
2523
|
-
refUrl: z.string().max(4096).nullable(),
|
|
2524
|
-
view: jsonObjectSchema,
|
|
2525
|
-
style: jsonObjectSchema,
|
|
2526
|
-
data: jsonObjectSchema
|
|
2527
|
-
});
|
|
2528
|
-
z.object({
|
|
2529
|
-
path: z.string().min(1),
|
|
2530
|
-
/** Reused by clients when board creation is interrupted and retried. */
|
|
2531
|
-
mutationId: z.string().max(128).optional(),
|
|
2532
|
-
title: z.string().min(1).max(255).optional(),
|
|
2533
|
-
metadata: jsonObjectSchema.optional(),
|
|
2534
|
-
nodes: z.array(BoardNodeInputSchema).max(5e4).optional(),
|
|
2535
|
-
connections: z.array(BoardConnectionSchema).max(5e4).optional(),
|
|
2536
|
-
effects: z.array(BoardEffectSchema.omit({
|
|
2537
|
-
boardId: true,
|
|
2538
|
-
revision: true
|
|
2539
|
-
})).optional(),
|
|
2540
|
-
sequences: z.array(z.object({
|
|
2541
|
-
sequence: BoardSequenceSchema.omit({
|
|
2542
|
-
boardId: true,
|
|
2543
|
-
revision: true
|
|
2544
|
-
}),
|
|
2545
|
-
clips: z.array(BoardClipSchema.omit({ sequenceId: true }))
|
|
2546
|
-
})).optional()
|
|
2547
|
-
});
|
|
2548
|
-
z.object({
|
|
2549
|
-
include: z.array(z.enum([
|
|
2550
|
-
"nodes",
|
|
2551
|
-
"connections",
|
|
2552
|
-
"effects",
|
|
2553
|
-
"sequences",
|
|
2554
|
-
"clips",
|
|
2555
|
-
"playback"
|
|
2556
|
-
])).optional(),
|
|
2557
|
-
viewport: z.object({
|
|
2558
|
-
x: finiteSchema,
|
|
2559
|
-
y: finiteSchema,
|
|
2560
|
-
width: finiteSchema.positive(),
|
|
2561
|
-
height: finiteSchema.positive()
|
|
2562
|
-
}).optional()
|
|
2563
|
-
});
|
|
2564
|
-
/** Persisted on `boards.metadata.playback`: how a Board plays when opened. */
|
|
2565
|
-
const BoardPlaybackPolicySchema = z.object({
|
|
2566
|
-
sequenceId: idSchema,
|
|
2567
|
-
/** Delay before the first local playback after opening the Board, in milliseconds. */
|
|
2568
|
-
delayMs: finiteSchema.nonnegative().default(0),
|
|
2569
|
-
loop: z.boolean().default(false)
|
|
2570
|
-
});
|
|
2571
|
-
function parseBoardPlaybackPolicy(metadata) {
|
|
2572
|
-
const parsed = BoardPlaybackPolicySchema.safeParse(metadata.playback);
|
|
2573
|
-
return parsed.success ? parsed.data : null;
|
|
2574
|
-
}
|
|
2575
|
-
z.discriminatedUnion("type", [
|
|
2576
|
-
z.object({
|
|
2577
|
-
commandId: idSchema,
|
|
2578
|
-
type: z.literal("play"),
|
|
2579
|
-
sequenceId: idSchema,
|
|
2580
|
-
position: finiteSchema.nonnegative().optional(),
|
|
2581
|
-
timeScale: finiteSchema.positive().max(4).optional(),
|
|
2582
|
-
shared: z.boolean().optional(),
|
|
2583
|
-
seed: idSchema.optional()
|
|
2584
|
-
}),
|
|
2585
|
-
z.object({
|
|
2586
|
-
commandId: idSchema,
|
|
2587
|
-
type: z.literal("pause"),
|
|
2588
|
-
playbackId: z.string().uuid()
|
|
2589
|
-
}),
|
|
2590
|
-
z.object({
|
|
2591
|
-
commandId: idSchema,
|
|
2592
|
-
type: z.literal("seek"),
|
|
2593
|
-
playbackId: z.string().uuid(),
|
|
2594
|
-
position: finiteSchema.nonnegative()
|
|
2595
|
-
}),
|
|
2596
|
-
z.object({
|
|
2597
|
-
commandId: idSchema,
|
|
2598
|
-
type: z.literal("stop"),
|
|
2599
|
-
playbackId: z.string().uuid()
|
|
2600
|
-
})
|
|
2601
|
-
]);
|
|
2602
|
-
//#endregion
|
|
2603
2253
|
//#region src/board/animation.ts
|
|
2604
2254
|
const ZERO_COST = {
|
|
2605
2255
|
particles: 0,
|
|
@@ -2951,4 +2601,4 @@ function createBoardExtensionRegistry(input = {}) {
|
|
|
2951
2601
|
return registry;
|
|
2952
2602
|
}
|
|
2953
2603
|
//#endregion
|
|
2954
|
-
export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BillingApi, BoardClient, BoardExtensionRegistry, 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, 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, clip, compileSequence, 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, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseBoardPlaybackPolicy, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseUiCommand, parseWorkRef, parseWorkSurfaceReady, parseWorkSurfaceResponse, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveCohubEnvironment, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, sanitizeAccessToken, setGrantedWorkScopes, timeline };
|
|
2604
|
+
export { BILLING_ACCESS_BLOCKED_ERROR_CODE, BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BOARD_NODE_CONTRACT, BillingApi, BoardClient, BoardExtensionRegistry, BoardInputError, 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, assertBoardNodes, assertGenerationRequestAllowedByPolicy, buildSpaceInvitePath, buildSpacePath, buildWorkSurfaceRequest, clearGrantedWorkScopes, clip, compileSequence, createBoardExtensionRegistry, createBoardNode, 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, isWorkId, joinApiUrl, matchesUnauthorizedErrorToken, mergeRequestSourceIntoMeta, normalizeBaseUrl, normalizeGenerationPolicy, normalizeRequestSource, normalizeVoiceInputWebsocketUrl, normalizeWebsocketUrl, parseAssistantMessageCommit, parseBoardPlaybackPolicy, parseGenerationPolicyFromEnv, parseRequestSourceFromHeaders, parseUiCommand, parseWorkRef, parseWorkSurfaceReady, parseWorkSurfaceResponse, readRequestSourceFromEnv, requestSourceToHeaders, resolveApiBaseUrl, resolveCohubEnvironment, resolveRequestSourceChannel, resolveVoiceInputWebsocketUrl, resolveWebsocketUrl, resolveWorkTransport, sanitizeAccessToken, setGrantedWorkScopes, timeline, validateBoardNodeInput, validateBoardNodes };
|