@neta-art/cohub 8.17.0 → 8.19.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 +17 -9
- package/dist/chunks/environment.d.ts +525 -5
- package/dist/chunks/environment.js +1 -0
- package/dist/chunks/http.d.ts +51 -2
- package/dist/chunks/http.js +975 -943
- package/dist/chunks/websocket.d.ts +1 -1
- package/dist/http.d.ts +2 -2
- package/dist/index.d.ts +35 -4
- package/dist/index.js +834 -30
- package/dist/protocol/dist/app-authorization.d.ts +1 -0
- package/dist/protocol/dist/index.d.ts +4 -0
- package/dist/protocol/dist/model/session.d.ts +1 -0
- package/dist/protocol/dist/model/turn.d.ts +1 -0
- package/dist/protocol/dist/realtime/types.d.ts +2 -0
- package/dist/protocol/dist/runtime/archive.d.ts +1 -0
- package/dist/protocol/dist/runtime/context.d.ts +1 -0
- package/dist/protocol/dist/runtime/index.d.ts +3 -0
- package/dist/types.d.ts +1 -0
- package/docs/app-runtime-guide.md +145 -92
- package/package.json +1 -1
package/dist/chunks/http.js
CHANGED
|
@@ -1,503 +1,77 @@
|
|
|
1
1
|
import { D as getRealtimeSpaceRoom, E as getRealtimeBoardRoom, n as HttpTransport, t as HttpError, y as isUuid } from "./transport.js";
|
|
2
2
|
import { l as resolveExecutionToken, o as resolveApiBaseUrl } from "./environment.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
//#region
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
create(data) {
|
|
17
|
-
return this.transport.request("/api/channels", {
|
|
18
|
-
method: "POST",
|
|
19
|
-
headers: { "Content-Type": "application/json" },
|
|
20
|
-
body: JSON.stringify(data)
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
|
-
startWeChatLogin(data) {
|
|
24
|
-
return this.transport.request("/api/channels/wechat/login/start", {
|
|
25
|
-
method: "POST",
|
|
26
|
-
headers: { "Content-Type": "application/json" },
|
|
27
|
-
body: JSON.stringify(data)
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
waitWeChatLogin(data) {
|
|
31
|
-
return this.transport.request("/api/channels/wechat/login/wait", {
|
|
32
|
-
method: "POST",
|
|
33
|
-
headers: { "Content-Type": "application/json" },
|
|
34
|
-
body: JSON.stringify(data)
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
delete(id) {
|
|
38
|
-
return this.transport.request(`/api/channels/${id}`, { method: "DELETE" });
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
//#endregion
|
|
42
|
-
//#region src/apis/cron-jobs.ts
|
|
43
|
-
const toQuery = (params) => {
|
|
44
|
-
const query = new URLSearchParams();
|
|
45
|
-
for (const [key, value] of Object.entries(params)) if (value !== void 0 && value !== null && value !== "") query.set(key, String(value));
|
|
46
|
-
const text = query.toString();
|
|
47
|
-
return text ? `?${text}` : "";
|
|
4
|
+
//#region ../protocol/dist/board-constants.js
|
|
5
|
+
const DEFAULT_BOARD_RENDER_LIMITS = {
|
|
6
|
+
particles: 2e4,
|
|
7
|
+
vertices: 5e5,
|
|
8
|
+
dynamicVertices: 15e4,
|
|
9
|
+
drawCalls: 400,
|
|
10
|
+
filterPasses: 24,
|
|
11
|
+
renderTexturePixels: 16777216,
|
|
12
|
+
textureBytes: 536870912,
|
|
13
|
+
bufferBytes: 268435456,
|
|
14
|
+
simulationSteps: 1e5
|
|
48
15
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
16
|
+
const BOARD_BUILTIN_CLIP_KINDS = [
|
|
17
|
+
"motion.path",
|
|
18
|
+
"draw.reveal",
|
|
19
|
+
"text.reveal",
|
|
20
|
+
"effects.particles",
|
|
21
|
+
"effects.trail",
|
|
22
|
+
"effects.impact",
|
|
23
|
+
"effects.flash",
|
|
24
|
+
"camera.focus",
|
|
25
|
+
"camera.shake"
|
|
26
|
+
];
|
|
27
|
+
const BOARD_BUILTIN_EFFECT_KINDS = [
|
|
28
|
+
"effects.pulse",
|
|
29
|
+
"effects.float",
|
|
30
|
+
"effects.deal"
|
|
31
|
+
];
|
|
32
|
+
const BOARD_ARROW_STROKE_SIZE = 2.5;
|
|
33
|
+
const BOARD_CONNECTION_STROKE_SIZE = 2.5;
|
|
34
|
+
function clipSchema(id) {
|
|
35
|
+
switch (id) {
|
|
36
|
+
case "motion.path": return { params: { points: {
|
|
37
|
+
coordinateSpace: "world-offset",
|
|
38
|
+
unit: "board"
|
|
39
|
+
} } };
|
|
40
|
+
case "effects.particles": return { params: { bounds: {
|
|
41
|
+
coordinateSpace: "world",
|
|
42
|
+
unit: "board"
|
|
43
|
+
} } };
|
|
44
|
+
case "camera.focus": return { params: {
|
|
45
|
+
focus: {
|
|
46
|
+
coordinateSpace: "world",
|
|
47
|
+
unit: "board"
|
|
48
|
+
},
|
|
49
|
+
padding: {
|
|
50
|
+
coordinateSpace: "screen",
|
|
51
|
+
unit: "css-px"
|
|
52
|
+
},
|
|
53
|
+
minZoom: { unit: "ratio" },
|
|
54
|
+
maxZoom: { unit: "ratio" }
|
|
55
|
+
} };
|
|
56
|
+
case "camera.shake": return { params: { amount: {
|
|
57
|
+
coordinateSpace: "screen-offset",
|
|
58
|
+
unit: "css-px"
|
|
59
|
+
} } };
|
|
60
|
+
default: return;
|
|
80
61
|
}
|
|
81
|
-
};
|
|
82
|
-
//#endregion
|
|
83
|
-
//#region src/apis/generations.ts
|
|
84
|
-
const DEFAULT_INTERVAL_MS = 1500;
|
|
85
|
-
const DEFAULT_TIMEOUT_MS = 18e5;
|
|
86
|
-
function sleep$1(ms, signal) {
|
|
87
|
-
if (signal?.aborted) return Promise.reject(signal.reason ?? /* @__PURE__ */ new Error("Generation wait aborted"));
|
|
88
|
-
return new Promise((resolve, reject) => {
|
|
89
|
-
const cleanup = () => signal?.removeEventListener("abort", onAbort);
|
|
90
|
-
const timer = setTimeout(() => {
|
|
91
|
-
cleanup();
|
|
92
|
-
resolve();
|
|
93
|
-
}, ms);
|
|
94
|
-
const onAbort = () => {
|
|
95
|
-
clearTimeout(timer);
|
|
96
|
-
cleanup();
|
|
97
|
-
reject(signal?.reason ?? /* @__PURE__ */ new Error("Generation wait aborted"));
|
|
98
|
-
};
|
|
99
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
100
|
-
});
|
|
101
62
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (typeof billing.usageType !== "string") return false;
|
|
115
|
-
if (billing.status !== "recorded" && billing.status !== "overage" && billing.status !== "skipped") return false;
|
|
116
|
-
if (billing.reason !== void 0 && billing.reason !== null && typeof billing.reason !== "string") return false;
|
|
117
|
-
}
|
|
118
|
-
return true;
|
|
119
|
-
}
|
|
120
|
-
var GenerationsApi = class {
|
|
121
|
-
transport;
|
|
122
|
-
constructor(transport) {
|
|
123
|
-
this.transport = transport;
|
|
124
|
-
}
|
|
125
|
-
async create(request) {
|
|
126
|
-
return this.transport.request("/api/generations", {
|
|
127
|
-
method: "POST",
|
|
128
|
-
headers: { "Content-Type": "application/json" },
|
|
129
|
-
body: JSON.stringify(request)
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
async wait(taskRunId, options = {}) {
|
|
133
|
-
const intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
134
|
-
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
135
|
-
const startedAt = Date.now();
|
|
136
|
-
while (true) {
|
|
137
|
-
if (options.signal?.aborted) throw options.signal.reason ?? /* @__PURE__ */ new Error("Generation wait aborted");
|
|
138
|
-
const detail = await this.transport.request(`/api/tasks/${taskRunId}`);
|
|
139
|
-
options.onPoll?.(detail);
|
|
140
|
-
if (detail.run.taskType !== "generation") throw new Error(`Task is not a generation task: ${detail.run.taskType}`);
|
|
141
|
-
if (detail.run.status === "completed") {
|
|
142
|
-
if (!isGenerationTaskResult(detail.run.result)) throw new Error("Generation task completed without a valid result");
|
|
143
|
-
return detail.run.result;
|
|
144
|
-
}
|
|
145
|
-
if (detail.run.status === "failed") {
|
|
146
|
-
const message = detail.run.errorMessage || "Generation task failed";
|
|
147
|
-
throw new Error(`${message}\ntask ID: ${taskRunId}`);
|
|
148
|
-
}
|
|
149
|
-
const remainingMs = timeoutMs - (Date.now() - startedAt);
|
|
150
|
-
if (remainingMs <= 0) throw new Error(`Generation task timed out after ${timeoutMs}ms`);
|
|
151
|
-
await sleep$1(Math.min(intervalMs, remainingMs), options.signal);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async createAndWait(request, options) {
|
|
155
|
-
const created = await this.create(request);
|
|
156
|
-
return this.wait(created.taskRunId, options);
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
//#endregion
|
|
160
|
-
//#region src/apis/models.ts
|
|
161
|
-
const MULTIMODAL_MODEL_TYPE = "multimodal";
|
|
162
|
-
var ModelsApi = class {
|
|
163
|
-
transport;
|
|
164
|
-
constructor(transport) {
|
|
165
|
-
this.transport = transport;
|
|
166
|
-
}
|
|
167
|
-
async list() {
|
|
168
|
-
return this.transport.request("/api/models");
|
|
169
|
-
}
|
|
170
|
-
async listMultimodal() {
|
|
171
|
-
return this.transport.request(`/api/models?modelType=${MULTIMODAL_MODEL_TYPE}`);
|
|
172
|
-
}
|
|
173
|
-
async status() {
|
|
174
|
-
return this.transport.request("/api/models/status");
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
//#endregion
|
|
178
|
-
//#region src/apis/prompts.ts
|
|
179
|
-
var PromptsApi = class {
|
|
180
|
-
transport;
|
|
181
|
-
constructor(transport) {
|
|
182
|
-
this.transport = transport;
|
|
183
|
-
}
|
|
184
|
-
async list(options, customFetch) {
|
|
185
|
-
const params = new URLSearchParams();
|
|
186
|
-
if (options?.spaceId) params.set("spaceId", options.spaceId);
|
|
187
|
-
const query = params.toString();
|
|
188
|
-
const path = query ? `/api/prompts?${query}` : "/api/prompts";
|
|
189
|
-
return this.transport.request(path, { fetch: customFetch });
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
//#endregion
|
|
193
|
-
//#region src/apis/skills.ts
|
|
194
|
-
var SkillsApi = class {
|
|
195
|
-
transport;
|
|
196
|
-
constructor(transport) {
|
|
197
|
-
this.transport = transport;
|
|
198
|
-
}
|
|
199
|
-
async list(options, customFetch) {
|
|
200
|
-
const params = new URLSearchParams();
|
|
201
|
-
if (options?.spaceId) params.set("spaceId", options.spaceId);
|
|
202
|
-
const query = params.toString();
|
|
203
|
-
const path = query ? `/api/skills?${query}` : "/api/skills";
|
|
204
|
-
return this.transport.request(path, { fetch: customFetch });
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
//#endregion
|
|
208
|
-
//#region src/apis/public-assets.ts
|
|
209
|
-
function createAbortError() {
|
|
210
|
-
if (typeof DOMException === "function") return new DOMException("The operation was aborted.", "AbortError");
|
|
211
|
-
const error = /* @__PURE__ */ new Error("The operation was aborted.");
|
|
212
|
-
error.name = "AbortError";
|
|
213
|
-
return error;
|
|
214
|
-
}
|
|
215
|
-
function uploadWithProgress(input) {
|
|
216
|
-
return new Promise((resolve, reject) => {
|
|
217
|
-
if (input.signal?.aborted) {
|
|
218
|
-
reject(createAbortError());
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const xhr = new XMLHttpRequest();
|
|
222
|
-
let settled = false;
|
|
223
|
-
let lastRatio = 0;
|
|
224
|
-
const handleSignalAbort = () => xhr.abort();
|
|
225
|
-
const finish = (callback) => {
|
|
226
|
-
if (settled) return;
|
|
227
|
-
settled = true;
|
|
228
|
-
input.signal?.removeEventListener("abort", handleSignalAbort);
|
|
229
|
-
callback();
|
|
230
|
-
};
|
|
231
|
-
const emitProgress = (loaded, total) => {
|
|
232
|
-
const ratio = Math.max(lastRatio, Math.min(1, total > 0 ? loaded / total : 0));
|
|
233
|
-
lastRatio = ratio;
|
|
234
|
-
try {
|
|
235
|
-
input.onProgress({
|
|
236
|
-
loadedBytes: Math.round(input.fileBytes * ratio),
|
|
237
|
-
totalBytes: input.fileBytes,
|
|
238
|
-
ratio
|
|
239
|
-
});
|
|
240
|
-
} catch {}
|
|
241
|
-
};
|
|
242
|
-
try {
|
|
243
|
-
xhr.open(input.method, input.url);
|
|
244
|
-
for (const [key, value] of Object.entries(input.headers ?? {})) {
|
|
245
|
-
if (/[\r\n\0]/.test(value)) continue;
|
|
246
|
-
xhr.setRequestHeader(key, value);
|
|
247
|
-
}
|
|
248
|
-
xhr.upload.onprogress = (event) => {
|
|
249
|
-
if (event.lengthComputable) emitProgress(event.loaded, event.total);
|
|
250
|
-
};
|
|
251
|
-
xhr.onload = () => {
|
|
252
|
-
if (xhr.status >= 200 && xhr.status < 300) {
|
|
253
|
-
emitProgress(1, 1);
|
|
254
|
-
finish(resolve);
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
const detail = xhr.responseText?.trim();
|
|
258
|
-
finish(() => reject(/* @__PURE__ */ new Error(`Public asset upload failed: HTTP ${xhr.status}${detail ? ` — ${detail}` : ""}`)));
|
|
259
|
-
};
|
|
260
|
-
xhr.onerror = () => finish(() => reject(/* @__PURE__ */ new Error("Public asset upload failed")));
|
|
261
|
-
xhr.onabort = () => finish(() => reject(createAbortError()));
|
|
262
|
-
input.signal?.addEventListener("abort", handleSignalAbort, { once: true });
|
|
263
|
-
xhr.send(input.body);
|
|
264
|
-
} catch (error) {
|
|
265
|
-
finish(() => reject(error));
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
var PublicAssetsApi = class {
|
|
270
|
-
transport;
|
|
271
|
-
constructor(transport) {
|
|
272
|
-
this.transport = transport;
|
|
273
|
-
}
|
|
274
|
-
createUpload(input, options = {}) {
|
|
275
|
-
return this.transport.request("/api/public-assets/uploads", {
|
|
276
|
-
method: "POST",
|
|
277
|
-
headers: { "Content-Type": "application/json" },
|
|
278
|
-
body: JSON.stringify(input),
|
|
279
|
-
signal: options.signal
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
async upload(input) {
|
|
283
|
-
if (input.signal?.aborted) throw createAbortError();
|
|
284
|
-
const plan = await this.createUpload({
|
|
285
|
-
purpose: input.purpose,
|
|
286
|
-
uploadProtocol: "presigned_put_v1",
|
|
287
|
-
spaceId: input.spaceId,
|
|
288
|
-
sessionId: input.sessionId,
|
|
289
|
-
file: {
|
|
290
|
-
size: input.file.size,
|
|
291
|
-
mimeType: input.mimeType,
|
|
292
|
-
filename: input.filename
|
|
293
|
-
}
|
|
294
|
-
}, { signal: input.signal });
|
|
295
|
-
if (input.signal?.aborted) throw createAbortError();
|
|
296
|
-
let response;
|
|
297
|
-
if (input.onProgress && typeof XMLHttpRequest === "function") {
|
|
298
|
-
await uploadWithProgress({
|
|
299
|
-
method: "PUT",
|
|
300
|
-
url: plan.asset.uploadUrl,
|
|
301
|
-
headers: plan.asset.uploadHeaders,
|
|
302
|
-
body: input.file,
|
|
303
|
-
fileBytes: input.file.size,
|
|
304
|
-
onProgress: input.onProgress,
|
|
305
|
-
signal: input.signal
|
|
306
|
-
});
|
|
307
|
-
return plan.asset;
|
|
308
|
-
}
|
|
309
|
-
response = await fetch(plan.asset.uploadUrl, {
|
|
310
|
-
method: "PUT",
|
|
311
|
-
headers: plan.asset.uploadHeaders,
|
|
312
|
-
body: input.file,
|
|
313
|
-
signal: input.signal
|
|
314
|
-
});
|
|
315
|
-
if (!response.ok) {
|
|
316
|
-
const detail = await response.text().catch(() => "");
|
|
317
|
-
throw new Error(`Public asset upload failed: HTTP ${response.status}${detail ? ` — ${detail}` : ""}`);
|
|
318
|
-
}
|
|
319
|
-
return plan.asset;
|
|
320
|
-
}
|
|
321
|
-
/** Durable public upload for any chat attachment (image or file). No space required. */
|
|
322
|
-
uploadAppSource(input) {
|
|
323
|
-
return this.upload({
|
|
324
|
-
purpose: "app_source",
|
|
325
|
-
spaceId: input.spaceId,
|
|
326
|
-
sessionId: input.sessionId,
|
|
327
|
-
file: input.file,
|
|
328
|
-
mimeType: input.mimeType,
|
|
329
|
-
filename: input.filename,
|
|
330
|
-
onProgress: input.onProgress,
|
|
331
|
-
signal: input.signal
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
uploadChatAttachment(input) {
|
|
335
|
-
return this.upload({
|
|
336
|
-
purpose: "chat_attachment",
|
|
337
|
-
spaceId: input.spaceId,
|
|
338
|
-
sessionId: input.sessionId,
|
|
339
|
-
file: input.file,
|
|
340
|
-
mimeType: input.mimeType,
|
|
341
|
-
filename: input.filename,
|
|
342
|
-
onProgress: input.onProgress,
|
|
343
|
-
signal: input.signal
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
/** Preprocessed chat image (webp/jpeg). Same durable path as uploadChatAttachment. */
|
|
347
|
-
uploadChatImageAttachment(input) {
|
|
348
|
-
return this.uploadChatAttachment(input);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
//#endregion
|
|
352
|
-
//#region src/apis/search.ts
|
|
353
|
-
var SearchApi = class {
|
|
354
|
-
transport;
|
|
355
|
-
constructor(transport) {
|
|
356
|
-
this.transport = transport;
|
|
357
|
-
}
|
|
358
|
-
query(input, customFetch) {
|
|
359
|
-
const params = new URLSearchParams({ q: input.q });
|
|
360
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
361
|
-
for (const type of input.types ?? []) params.append("type", type);
|
|
362
|
-
if (input.spaceId) params.set("spaceId", input.spaceId);
|
|
363
|
-
if (input.labelRef) params.set("labelRef", input.labelRef);
|
|
364
|
-
if (input.groupTurns === false) params.set("groupTurns", "false");
|
|
365
|
-
return this.transport.request(`/api/search?${params.toString()}`, { fetch: customFetch });
|
|
366
|
-
}
|
|
367
|
-
/** Default (empty-query) command palette data: viewer-relative space signals. */
|
|
368
|
-
overview(input, customFetch) {
|
|
369
|
-
const params = new URLSearchParams();
|
|
370
|
-
if (input?.spaceLimit !== void 0) params.set("spaceLimit", String(input.spaceLimit));
|
|
371
|
-
if (input?.sessionLimit !== void 0) params.set("sessionLimit", String(input.sessionLimit));
|
|
372
|
-
for (const spaceId of input?.recentSpaceIds ?? []) params.append("recentSpaceId", spaceId);
|
|
373
|
-
const query = params.toString();
|
|
374
|
-
return this.transport.request(`/api/palette/overview${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
375
|
-
}
|
|
376
|
-
};
|
|
377
|
-
//#endregion
|
|
378
|
-
//#region src/apis/references.ts
|
|
379
|
-
const toSelector = (ref) => typeof ref === "string" ? ref : `${ref.type}:${ref.id}`;
|
|
380
|
-
/**
|
|
381
|
-
* Neutral access to the resource reference index. `query` lists references
|
|
382
|
-
* touching a resource; `aggregate` returns grouped counts for a space. Callers
|
|
383
|
-
* assemble collaboration graphs, lineage views, rankings, or trends from the
|
|
384
|
-
* returned data.
|
|
385
|
-
*/
|
|
386
|
-
var ReferencesApi = class {
|
|
387
|
-
transport;
|
|
388
|
-
constructor(transport) {
|
|
389
|
-
this.transport = transport;
|
|
390
|
-
}
|
|
391
|
-
query(input, customFetch) {
|
|
392
|
-
const params = new URLSearchParams({ source: toSelector(input.source) });
|
|
393
|
-
if (input.direction) params.set("direction", input.direction);
|
|
394
|
-
if (input.kinds && input.kinds.length > 0) params.set("kinds", input.kinds.join(","));
|
|
395
|
-
if (input.days !== void 0) params.set("days", String(input.days));
|
|
396
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
397
|
-
return this.transport.request(`/api/references?${params.toString()}`, { fetch: customFetch });
|
|
398
|
-
}
|
|
399
|
-
aggregate(input, customFetch) {
|
|
400
|
-
const params = new URLSearchParams({ space: input.spaceId });
|
|
401
|
-
if (input.groupBy) params.set("groupBy", input.groupBy);
|
|
402
|
-
if (input.kinds && input.kinds.length > 0) params.set("kinds", input.kinds.join(","));
|
|
403
|
-
if (input.days !== void 0) params.set("days", String(input.days));
|
|
404
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
405
|
-
return this.transport.request(`/api/references/aggregate?${params.toString()}`, { fetch: customFetch });
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
//#endregion
|
|
409
|
-
//#region src/apis/session-access.ts
|
|
410
|
-
var SessionAccessApi = class {
|
|
411
|
-
transport;
|
|
412
|
-
constructor(transport) {
|
|
413
|
-
this.transport = transport;
|
|
414
|
-
}
|
|
415
|
-
get(sessionId) {
|
|
416
|
-
return this.transport.request(`/api/sessions/${sessionId}/access`);
|
|
417
|
-
}
|
|
418
|
-
set(sessionId, body) {
|
|
419
|
-
return this.transport.request(`/api/sessions/${sessionId}/access`, {
|
|
420
|
-
method: "PATCH",
|
|
421
|
-
headers: { "Content-Type": "application/json" },
|
|
422
|
-
body: JSON.stringify(body)
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
remove(sessionId) {
|
|
426
|
-
return this.transport.request(`/api/sessions/${sessionId}/access`, { method: "DELETE" });
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
//#endregion
|
|
430
|
-
//#region ../protocol/dist/board-constants.js
|
|
431
|
-
const DEFAULT_BOARD_RENDER_LIMITS = {
|
|
432
|
-
particles: 2e4,
|
|
433
|
-
vertices: 5e5,
|
|
434
|
-
dynamicVertices: 15e4,
|
|
435
|
-
drawCalls: 400,
|
|
436
|
-
filterPasses: 24,
|
|
437
|
-
renderTexturePixels: 16777216,
|
|
438
|
-
textureBytes: 536870912,
|
|
439
|
-
bufferBytes: 268435456,
|
|
440
|
-
simulationSteps: 1e5
|
|
441
|
-
};
|
|
442
|
-
const BOARD_BUILTIN_CLIP_KINDS = [
|
|
443
|
-
"motion.path",
|
|
444
|
-
"draw.reveal",
|
|
445
|
-
"text.reveal",
|
|
446
|
-
"effects.particles",
|
|
447
|
-
"effects.trail",
|
|
448
|
-
"effects.impact",
|
|
449
|
-
"effects.flash",
|
|
450
|
-
"camera.focus",
|
|
451
|
-
"camera.shake"
|
|
452
|
-
];
|
|
453
|
-
const BOARD_BUILTIN_EFFECT_KINDS = [
|
|
454
|
-
"effects.pulse",
|
|
455
|
-
"effects.float",
|
|
456
|
-
"effects.deal"
|
|
457
|
-
];
|
|
458
|
-
const BOARD_ARROW_STROKE_SIZE = 2.5;
|
|
459
|
-
const BOARD_CONNECTION_STROKE_SIZE = 2.5;
|
|
460
|
-
function clipSchema(id) {
|
|
461
|
-
switch (id) {
|
|
462
|
-
case "motion.path": return { params: { points: {
|
|
463
|
-
coordinateSpace: "world-offset",
|
|
464
|
-
unit: "board"
|
|
465
|
-
} } };
|
|
466
|
-
case "effects.particles": return { params: { bounds: {
|
|
467
|
-
coordinateSpace: "world",
|
|
468
|
-
unit: "board"
|
|
469
|
-
} } };
|
|
470
|
-
case "camera.focus": return { params: {
|
|
471
|
-
focus: {
|
|
472
|
-
coordinateSpace: "world",
|
|
473
|
-
unit: "board"
|
|
474
|
-
},
|
|
475
|
-
padding: {
|
|
476
|
-
coordinateSpace: "screen",
|
|
477
|
-
unit: "css-px"
|
|
478
|
-
},
|
|
479
|
-
minZoom: { unit: "ratio" },
|
|
480
|
-
maxZoom: { unit: "ratio" }
|
|
481
|
-
} };
|
|
482
|
-
case "camera.shake": return { params: { amount: {
|
|
483
|
-
coordinateSpace: "screen-offset",
|
|
484
|
-
unit: "css-px"
|
|
485
|
-
} } };
|
|
486
|
-
default: return;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
function effectSchema(id) {
|
|
490
|
-
switch (id) {
|
|
491
|
-
case "effects.deal": return { params: {
|
|
492
|
-
lift: { unit: "board" },
|
|
493
|
-
swing: { unit: "board" },
|
|
494
|
-
curve: { unit: "board" },
|
|
495
|
-
tilt: { unit: "degree" },
|
|
496
|
-
scale: { unit: "ratio" },
|
|
497
|
-
duration: { unit: "ms" },
|
|
498
|
-
landing: { unit: "ms" }
|
|
499
|
-
} };
|
|
500
|
-
default: return;
|
|
63
|
+
function effectSchema(id) {
|
|
64
|
+
switch (id) {
|
|
65
|
+
case "effects.deal": return { params: {
|
|
66
|
+
lift: { unit: "board" },
|
|
67
|
+
swing: { unit: "board" },
|
|
68
|
+
curve: { unit: "board" },
|
|
69
|
+
tilt: { unit: "degree" },
|
|
70
|
+
scale: { unit: "ratio" },
|
|
71
|
+
duration: { unit: "ms" },
|
|
72
|
+
landing: { unit: "ms" }
|
|
73
|
+
} };
|
|
74
|
+
default: return;
|
|
501
75
|
}
|
|
502
76
|
}
|
|
503
77
|
const BOARD_BUILTIN_CAPABILITIES = [...BOARD_BUILTIN_CLIP_KINDS.map((id) => {
|
|
@@ -1052,479 +626,905 @@ const BoardAuthoringPositionSchema = z.object({
|
|
|
1052
626
|
x: finiteSchema,
|
|
1053
627
|
y: finiteSchema
|
|
1054
628
|
}).strict();
|
|
1055
|
-
const BoardAuthoringSizeSchema = z.object({
|
|
1056
|
-
width: finiteSchema.positive(),
|
|
1057
|
-
height: finiteSchema.positive()
|
|
629
|
+
const BoardAuthoringSizeSchema = z.object({
|
|
630
|
+
width: finiteSchema.positive(),
|
|
631
|
+
height: finiteSchema.positive()
|
|
632
|
+
}).strict();
|
|
633
|
+
const BoardAuthoringPositionPatchSchema = z.object({
|
|
634
|
+
x: finiteSchema.optional(),
|
|
635
|
+
y: finiteSchema.optional()
|
|
636
|
+
}).strict();
|
|
637
|
+
const pointSchema = z.object({
|
|
638
|
+
x: finiteSchema,
|
|
639
|
+
y: finiteSchema,
|
|
640
|
+
p: finiteSchema.min(0).max(1).default(.5)
|
|
641
|
+
}).strict();
|
|
642
|
+
const worldPointSchema = z.object({
|
|
643
|
+
x: finiteSchema,
|
|
644
|
+
y: finiteSchema
|
|
645
|
+
}).strict();
|
|
646
|
+
const cropSchema = z.object({
|
|
647
|
+
x: finiteSchema.min(0).max(1),
|
|
648
|
+
y: finiteSchema.min(0).max(1),
|
|
649
|
+
w: finiteSchema.min(0).max(1),
|
|
650
|
+
h: finiteSchema.min(0).max(1)
|
|
651
|
+
}).strict();
|
|
652
|
+
const BoardItemStyleSchema = z.object({
|
|
653
|
+
color: z.enum(BOARD_AUTHORING_COLOR_IDS).optional(),
|
|
654
|
+
strokeWidth: finiteSchema.min(1).max(64).optional(),
|
|
655
|
+
fillOpacity: finiteSchema.min(0).max(1).optional()
|
|
656
|
+
}).strict();
|
|
657
|
+
const sourceSnapshotSchema = z.record(z.string(), z.unknown());
|
|
658
|
+
function isSafeBoardSourcePath(value) {
|
|
659
|
+
return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !value.startsWith("\\") && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
660
|
+
}
|
|
661
|
+
const BoardItemSourceSchema = z.object({
|
|
662
|
+
kind: z.literal("space-file"),
|
|
663
|
+
path: z.string().refine(isSafeBoardSourcePath, "source path must be a safe relative Board file path"),
|
|
664
|
+
snapshot: sourceSnapshotSchema.optional()
|
|
665
|
+
}).strict();
|
|
666
|
+
const sizedBaseFields = {
|
|
667
|
+
id: idSchema,
|
|
668
|
+
position: BoardAuthoringPositionSchema.default({
|
|
669
|
+
x: 0,
|
|
670
|
+
y: 0
|
|
671
|
+
}),
|
|
672
|
+
rotation: finiteSchema.default(0),
|
|
673
|
+
parentId: idSchema.nullable().optional(),
|
|
674
|
+
locked: z.boolean().optional(),
|
|
675
|
+
metadata: jsonObjectSchema.optional(),
|
|
676
|
+
size: BoardAuthoringSizeSchema.optional()
|
|
677
|
+
};
|
|
678
|
+
const styledBaseFields = {
|
|
679
|
+
...sizedBaseFields,
|
|
680
|
+
style: BoardItemStyleSchema.optional()
|
|
681
|
+
};
|
|
682
|
+
const { position: _positionField, size: _sizeField, ...strokeBaseFields } = sizedBaseFields;
|
|
683
|
+
const strokeStyledBaseFields = {
|
|
684
|
+
...strokeBaseFields,
|
|
685
|
+
rotation: z.literal(0).default(0),
|
|
686
|
+
style: BoardItemStyleSchema.optional()
|
|
687
|
+
};
|
|
688
|
+
const BoardTextAuthoringItemSchema = z.object({
|
|
689
|
+
...styledBaseFields,
|
|
690
|
+
type: z.literal("text"),
|
|
691
|
+
props: z.object({
|
|
692
|
+
text: z.string().default(""),
|
|
693
|
+
fontSize: finiteSchema.min(2).max(512).default(24)
|
|
694
|
+
}).strict()
|
|
695
|
+
}).strict();
|
|
696
|
+
const BoardGeoAuthoringItemSchema = z.object({
|
|
697
|
+
...styledBaseFields,
|
|
698
|
+
type: z.literal("geo"),
|
|
699
|
+
props: z.object({
|
|
700
|
+
shape: z.enum(BOARD_AUTHORING_GEO_KINDS).default("rectangle"),
|
|
701
|
+
text: z.string().default("")
|
|
702
|
+
}).strict()
|
|
1058
703
|
}).strict();
|
|
1059
|
-
const
|
|
1060
|
-
|
|
1061
|
-
|
|
704
|
+
const BoardDrawAuthoringItemSchema = z.object({
|
|
705
|
+
...strokeStyledBaseFields,
|
|
706
|
+
type: z.literal("draw"),
|
|
707
|
+
props: z.object({ points: z.array(pointSchema).min(1) }).strict()
|
|
1062
708
|
}).strict();
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
709
|
+
const BoardArrowAuthoringItemSchema = z.object({
|
|
710
|
+
...strokeStyledBaseFields,
|
|
711
|
+
type: z.literal("arrow"),
|
|
712
|
+
props: z.object({
|
|
713
|
+
start: worldPointSchema,
|
|
714
|
+
end: worldPointSchema,
|
|
715
|
+
bend: finiteSchema.min(-.85).max(.85).default(0),
|
|
716
|
+
arrowStart: z.boolean().default(false),
|
|
717
|
+
arrowEnd: z.boolean().default(true),
|
|
718
|
+
label: z.string().default("")
|
|
719
|
+
}).strict()
|
|
1067
720
|
}).strict();
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
|
|
721
|
+
const BoardFrameAuthoringItemSchema = z.object({
|
|
722
|
+
...styledBaseFields,
|
|
723
|
+
type: z.literal("frame"),
|
|
724
|
+
props: z.object({ label: z.string().default("Frame") }).strict()
|
|
1071
725
|
}).strict();
|
|
1072
|
-
const
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
726
|
+
const fileBackedFields = {
|
|
727
|
+
...sizedBaseFields,
|
|
728
|
+
style: z.object({}).strict().optional(),
|
|
729
|
+
source: BoardItemSourceSchema
|
|
730
|
+
};
|
|
731
|
+
const builtinItemSchemas = [
|
|
732
|
+
BoardTextAuthoringItemSchema,
|
|
733
|
+
BoardGeoAuthoringItemSchema,
|
|
734
|
+
BoardDrawAuthoringItemSchema,
|
|
735
|
+
BoardArrowAuthoringItemSchema,
|
|
736
|
+
BoardFrameAuthoringItemSchema,
|
|
737
|
+
z.object({
|
|
738
|
+
...fileBackedFields,
|
|
739
|
+
type: z.literal("image"),
|
|
740
|
+
props: z.object({ crop: cropSchema.optional() }).strict()
|
|
741
|
+
}).strict(),
|
|
742
|
+
z.object({
|
|
743
|
+
...fileBackedFields,
|
|
744
|
+
type: z.literal("video"),
|
|
745
|
+
props: z.object({}).strict()
|
|
746
|
+
}).strict(),
|
|
747
|
+
z.object({
|
|
748
|
+
...fileBackedFields,
|
|
749
|
+
type: z.literal("audio"),
|
|
750
|
+
props: z.object({}).strict()
|
|
751
|
+
}).strict(),
|
|
752
|
+
z.object({
|
|
753
|
+
...fileBackedFields,
|
|
754
|
+
type: z.literal("file"),
|
|
755
|
+
props: z.object({}).strict()
|
|
756
|
+
}).strict(),
|
|
757
|
+
z.object({
|
|
758
|
+
...sizedBaseFields,
|
|
759
|
+
type: z.literal("task"),
|
|
760
|
+
props: z.object({
|
|
761
|
+
taskRunId: z.string().min(1),
|
|
762
|
+
snapshot: z.record(z.string(), z.unknown())
|
|
763
|
+
}).strict(),
|
|
764
|
+
style: z.object({}).strict().optional()
|
|
765
|
+
}).strict()
|
|
766
|
+
];
|
|
767
|
+
const BoardBuiltinAuthoringItemSchema = z.discriminatedUnion("type", builtinItemSchemas);
|
|
768
|
+
const BoardExtensionAuthoringItemSchema = z.object({
|
|
769
|
+
...sizedBaseFields,
|
|
770
|
+
type: extensionTypeSchema,
|
|
771
|
+
kindVersion: z.number().int().positive(),
|
|
772
|
+
props: jsonObjectSchema,
|
|
773
|
+
style: jsonObjectSchema.optional(),
|
|
774
|
+
source: z.object({
|
|
775
|
+
kind: z.string().min(1).max(80),
|
|
776
|
+
ref: z.string().min(1).max(4096),
|
|
777
|
+
snapshot: jsonObjectSchema.optional()
|
|
778
|
+
}).strict().optional()
|
|
1077
779
|
}).strict();
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
780
|
+
const BoardAuthoringItemSchema = z.union([BoardBuiltinAuthoringItemSchema, BoardExtensionAuthoringItemSchema]);
|
|
781
|
+
/** JSON Merge Patch semantics, constrained to the stable Item envelope. */
|
|
782
|
+
const BoardItemPatchSchema = z.object({
|
|
783
|
+
position: BoardAuthoringPositionPatchSchema.optional(),
|
|
784
|
+
size: BoardAuthoringSizeSchema.nullable().optional(),
|
|
785
|
+
rotation: finiteSchema.optional(),
|
|
786
|
+
parentId: idSchema.nullable().optional(),
|
|
787
|
+
locked: z.boolean().nullable().optional(),
|
|
788
|
+
props: jsonObjectSchema.optional(),
|
|
789
|
+
style: jsonObjectSchema.nullable().optional(),
|
|
790
|
+
source: jsonObjectSchema.nullable().optional(),
|
|
791
|
+
metadata: jsonObjectSchema.nullable().optional()
|
|
792
|
+
}).strict().refine((patch) => Object.keys(patch).length > 0, "item patch is empty");
|
|
793
|
+
const BoardConnectionInputSchema = BoardConnectionSchema;
|
|
794
|
+
const stripServerFields = (value) => {
|
|
795
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
796
|
+
const { boardId: _boardId, revision: _revision, ...input } = value;
|
|
797
|
+
return input;
|
|
798
|
+
};
|
|
799
|
+
const BoardEffectCommandInputSchema = z.preprocess(stripServerFields, BoardEffectInputSchema);
|
|
800
|
+
const BoardCompositionCommandInputSchema = z.preprocess(stripServerFields, BoardCompositionInputSchema);
|
|
801
|
+
const BoardSemanticCommandSchema = z.discriminatedUnion("type", [
|
|
802
|
+
z.object({
|
|
803
|
+
type: z.literal("board.patch"),
|
|
804
|
+
patch: z.object({
|
|
805
|
+
title: z.string().min(1).max(255).optional(),
|
|
806
|
+
metadata: jsonObjectSchema.nullable().optional(),
|
|
807
|
+
metadataPatch: jsonObjectSchema.optional()
|
|
808
|
+
}).strict().refine((patch) => Object.keys(patch).length > 0, "board patch is empty")
|
|
809
|
+
}).strict(),
|
|
810
|
+
z.object({
|
|
811
|
+
type: z.literal("item.create"),
|
|
812
|
+
item: BoardAuthoringItemSchema
|
|
813
|
+
}).strict(),
|
|
814
|
+
z.object({
|
|
815
|
+
type: z.literal("item.patch"),
|
|
816
|
+
itemId: idSchema,
|
|
817
|
+
patch: BoardItemPatchSchema
|
|
818
|
+
}).strict(),
|
|
819
|
+
z.object({
|
|
820
|
+
type: z.literal("item.replace"),
|
|
821
|
+
itemId: idSchema,
|
|
822
|
+
item: BoardAuthoringItemSchema
|
|
823
|
+
}).strict(),
|
|
824
|
+
z.object({
|
|
825
|
+
type: z.literal("item.delete"),
|
|
826
|
+
itemId: idSchema,
|
|
827
|
+
cascade: z.boolean().default(false)
|
|
828
|
+
}).strict(),
|
|
829
|
+
z.object({
|
|
830
|
+
type: z.literal("item.reorder"),
|
|
831
|
+
itemId: idSchema,
|
|
832
|
+
index: z.number().int().nonnegative()
|
|
833
|
+
}).strict(),
|
|
834
|
+
z.object({
|
|
835
|
+
type: z.literal("connection.create"),
|
|
836
|
+
connection: BoardConnectionInputSchema
|
|
837
|
+
}).strict(),
|
|
838
|
+
z.object({
|
|
839
|
+
type: z.literal("connection.patch"),
|
|
840
|
+
connectionId: idSchema,
|
|
841
|
+
patch: BoardConnectionPatchSchema
|
|
842
|
+
}).strict(),
|
|
843
|
+
z.object({
|
|
844
|
+
type: z.literal("connection.delete"),
|
|
845
|
+
connectionId: idSchema
|
|
846
|
+
}).strict(),
|
|
847
|
+
z.object({
|
|
848
|
+
type: z.literal("effect.apply"),
|
|
849
|
+
effect: BoardEffectCommandInputSchema
|
|
850
|
+
}).strict(),
|
|
851
|
+
z.object({
|
|
852
|
+
type: z.literal("effect.delete"),
|
|
853
|
+
effectId: idSchema
|
|
854
|
+
}).strict(),
|
|
855
|
+
z.object({
|
|
856
|
+
type: z.literal("composition.apply"),
|
|
857
|
+
composition: BoardCompositionCommandInputSchema
|
|
858
|
+
}).strict(),
|
|
859
|
+
z.object({
|
|
860
|
+
type: z.literal("composition.delete"),
|
|
861
|
+
compositionId: idSchema
|
|
862
|
+
}).strict()
|
|
863
|
+
]);
|
|
864
|
+
const BoardSemanticMutationSchema = z.object({
|
|
865
|
+
mutationId: idSchema,
|
|
866
|
+
baseVersion: z.number().int().nonnegative(),
|
|
867
|
+
clientId: idSchema.optional(),
|
|
868
|
+
undoGroupId: idSchema.optional(),
|
|
869
|
+
/** Validate (including server-side reference checks) without writing. */
|
|
870
|
+
dryRun: z.boolean().default(false),
|
|
871
|
+
commands: z.array(BoardSemanticCommandSchema).min(1).max(5e4)
|
|
1082
872
|
}).strict();
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
873
|
+
z.object({
|
|
874
|
+
include: z.array(z.enum([
|
|
875
|
+
"items",
|
|
876
|
+
"connections",
|
|
877
|
+
"effects",
|
|
878
|
+
"compositions",
|
|
879
|
+
"playback"
|
|
880
|
+
])).optional(),
|
|
881
|
+
itemIds: z.array(idSchema).max(5e4).optional(),
|
|
882
|
+
connectionIds: z.array(idSchema).max(5e4).optional(),
|
|
883
|
+
effectIds: z.array(idSchema).max(5e4).optional(),
|
|
884
|
+
compositionIds: z.array(idSchema).max(5e4).optional(),
|
|
885
|
+
viewport: z.object({
|
|
886
|
+
x: finiteSchema,
|
|
887
|
+
y: finiteSchema,
|
|
888
|
+
width: finiteSchema.positive(),
|
|
889
|
+
height: finiteSchema.positive()
|
|
890
|
+
}).optional()
|
|
891
|
+
}).strict();
|
|
892
|
+
//#endregion
|
|
893
|
+
//#region ../protocol/dist/space-hooks.js
|
|
894
|
+
const SPACE_HOOK_WEBHOOK_SECRET_HEADER = "x-cohub-webhook-secret";
|
|
895
|
+
//#endregion
|
|
896
|
+
//#region ../protocol/dist/navigation.js
|
|
897
|
+
const NAVIGATION_LAUNCH_MAX_LENGTH = 2048;
|
|
898
|
+
const NAVIGATION_ERROR_MESSAGE_MAX_LENGTH = 2e3;
|
|
899
|
+
//#endregion
|
|
900
|
+
//#region ../protocol/dist/desktop-command.js
|
|
901
|
+
/**
|
|
902
|
+
* Lets an agent drive the Cohub desktop that originated the app. Routing comes
|
|
903
|
+
* from request provenance, never a caller-supplied target, so a command only
|
|
904
|
+
* reaches the actor's own instances.
|
|
905
|
+
*
|
|
906
|
+
* The canonical command is `desktop.open`. The legacy `preview.show` shape is
|
|
907
|
+
* accepted on input and normalized, so older clients keep working, but commands
|
|
908
|
+
* are always stored and dispatched in the canonical form.
|
|
909
|
+
*/
|
|
910
|
+
const DESKTOP_COMMAND_VERSION = 1;
|
|
911
|
+
/** Persisted and broadcast, so every field is capped; MAX_BYTES bounds the whole. */
|
|
912
|
+
const DESKTOP_COMMAND_PAYLOAD_MAX_BYTES = 32768;
|
|
913
|
+
const DESKTOP_COMMAND_MAX_BYTES = 40960;
|
|
914
|
+
const DESKTOP_COMMAND_LAUNCH_MAX_LENGTH = NAVIGATION_LAUNCH_MAX_LENGTH;
|
|
915
|
+
const DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS = 6e5;
|
|
916
|
+
const DESKTOP_COMMAND_MAX_TIMEOUT_MS = 432e5;
|
|
917
|
+
const DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS = 600;
|
|
918
|
+
/** Keeps pending commands reportable for the full wait window plus settlement grace. */
|
|
919
|
+
const DESKTOP_COMMAND_PENDING_TTL_SECONDS = 43800;
|
|
920
|
+
const DESKTOP_COMMAND_TERMINAL_TTL_SECONDS = 1800;
|
|
921
|
+
const DESKTOP_COMMAND_TERMINAL_STATUSES = [
|
|
922
|
+
"applied",
|
|
923
|
+
"no_active_client",
|
|
924
|
+
"desktop_host_unavailable",
|
|
925
|
+
"rejected",
|
|
926
|
+
"unsupported",
|
|
927
|
+
"timeout"
|
|
928
|
+
];
|
|
929
|
+
const isTerminalDesktopCommandStatus = (status) => DESKTOP_COMMAND_TERMINAL_STATUSES.includes(status);
|
|
930
|
+
/**
|
|
931
|
+
* The surface a desktop open should use: an explicit request wins, then
|
|
932
|
+
* whatever the App declared at publish time. `window` is the implicit
|
|
933
|
+
* default and yields `undefined` so the command stays compact.
|
|
934
|
+
*/
|
|
935
|
+
function resolveOpenSurface(requested, declared) {
|
|
936
|
+
return (requested ?? declared) === "overlay" ? "overlay" : void 0;
|
|
1086
937
|
}
|
|
1087
|
-
const
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
const
|
|
1093
|
-
|
|
1094
|
-
position: BoardAuthoringPositionSchema.default({
|
|
1095
|
-
x: 0,
|
|
1096
|
-
y: 0
|
|
1097
|
-
}),
|
|
1098
|
-
rotation: finiteSchema.default(0),
|
|
1099
|
-
parentId: idSchema.nullable().optional(),
|
|
1100
|
-
locked: z.boolean().optional(),
|
|
1101
|
-
metadata: jsonObjectSchema.optional(),
|
|
1102
|
-
size: BoardAuthoringSizeSchema.optional()
|
|
938
|
+
const METHOD_RE = new RegExp(`^[A-Za-z][A-Za-z0-9_.:-]{0,63}$`);
|
|
939
|
+
const isDesktopCallMethod = (value) => typeof value === "string" && METHOD_RE.test(value);
|
|
940
|
+
const DESKTOP_COMMAND_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
|
|
941
|
+
const parseDesktopCommandId = (value) => {
|
|
942
|
+
if (typeof value !== "string") return null;
|
|
943
|
+
const trimmed = value.trim();
|
|
944
|
+
return DESKTOP_COMMAND_ID_RE.test(trimmed) ? trimmed : null;
|
|
1103
945
|
};
|
|
1104
|
-
const
|
|
1105
|
-
|
|
1106
|
-
|
|
946
|
+
const isRecord$1 = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
947
|
+
const asTrimmed = (value) => {
|
|
948
|
+
if (typeof value !== "string") return null;
|
|
949
|
+
const trimmed = value.trim();
|
|
950
|
+
return trimmed ? trimmed : null;
|
|
1107
951
|
};
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
952
|
+
const parseLaunch = (value) => {
|
|
953
|
+
if (!isRecord$1(value)) return void 0;
|
|
954
|
+
const search = asTrimmed(value.search);
|
|
955
|
+
const hash = asTrimmed(value.hash);
|
|
956
|
+
if (!search && !hash) return void 0;
|
|
957
|
+
return {
|
|
958
|
+
...search ? { search: search.startsWith("?") ? search : `?${search}` } : {},
|
|
959
|
+
...hash ? { hash: hash.startsWith("#") ? hash : `#${hash}` } : {}
|
|
960
|
+
};
|
|
1113
961
|
};
|
|
1114
|
-
const
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
962
|
+
const measureDesktopCommandPayload = (value) => {
|
|
963
|
+
if (value === void 0) return 0;
|
|
964
|
+
try {
|
|
965
|
+
return new TextEncoder().encode(JSON.stringify(value) ?? "").length;
|
|
966
|
+
} catch {
|
|
967
|
+
return null;
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
/**
|
|
971
|
+
* Parse a desktop command from untrusted input.
|
|
972
|
+
*
|
|
973
|
+
* Accepts both the canonical `desktop.open` shape (`target` / `call`) and the
|
|
974
|
+
* legacy `preview.show` shape (`preview` / `request`); the result is always
|
|
975
|
+
* canonical so every later stage handles a single form.
|
|
976
|
+
*/
|
|
977
|
+
const parseDesktopCommand = (input) => {
|
|
978
|
+
if (!isRecord$1(input)) return {
|
|
979
|
+
command: null,
|
|
980
|
+
error: "command must be an object"
|
|
981
|
+
};
|
|
982
|
+
const legacy = input.type === "preview.show";
|
|
983
|
+
if (input.type !== "desktop.open" && !legacy) return {
|
|
984
|
+
command: null,
|
|
985
|
+
error: "command.type must be one of: desktop.open"
|
|
986
|
+
};
|
|
987
|
+
const target = isRecord$1(input.target) ? input.target : isRecord$1(input.preview) ? input.preview : null;
|
|
988
|
+
if (!target) return {
|
|
989
|
+
command: null,
|
|
990
|
+
error: "command.target is required"
|
|
991
|
+
};
|
|
992
|
+
const kind = target.kind === "app" || legacy && target.kind === "work" ? "app" : target.kind === "file" ? "file" : null;
|
|
993
|
+
if (!kind) return {
|
|
994
|
+
command: null,
|
|
995
|
+
error: "command.target.kind must be one of: app, file"
|
|
996
|
+
};
|
|
997
|
+
if (kind === "file") {
|
|
998
|
+
const path = asTrimmed(target.path);
|
|
999
|
+
if (!path) return {
|
|
1000
|
+
command: null,
|
|
1001
|
+
error: "command.target.path is required"
|
|
1002
|
+
};
|
|
1003
|
+
if (path.length > 2048 || path.startsWith("/") || path.includes("\0") || path.includes("\\") || path.split("/").some((segment) => segment === "..")) return {
|
|
1004
|
+
command: null,
|
|
1005
|
+
error: "command.target.path must be a relative Space file path"
|
|
1006
|
+
};
|
|
1007
|
+
if (input.call !== void 0 && input.call !== null) return {
|
|
1008
|
+
command: null,
|
|
1009
|
+
error: "command.call is only supported for app targets"
|
|
1010
|
+
};
|
|
1011
|
+
if (legacy && input.request !== void 0 && input.request !== null) return {
|
|
1012
|
+
command: null,
|
|
1013
|
+
error: "command.call is only supported for app targets"
|
|
1014
|
+
};
|
|
1015
|
+
return {
|
|
1016
|
+
command: {
|
|
1017
|
+
type: "desktop.open",
|
|
1018
|
+
target: {
|
|
1019
|
+
kind: "file",
|
|
1020
|
+
path
|
|
1021
|
+
}
|
|
1022
|
+
},
|
|
1023
|
+
error: null
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
const appId = asTrimmed(target.appId ?? target.workId);
|
|
1027
|
+
if (!appId) return {
|
|
1028
|
+
command: null,
|
|
1029
|
+
error: "command.target.appId is required"
|
|
1030
|
+
};
|
|
1031
|
+
if (!isUuid(appId)) return {
|
|
1032
|
+
command: null,
|
|
1033
|
+
error: "command.target.appId must be an App id"
|
|
1034
|
+
};
|
|
1035
|
+
const label = asTrimmed(target.label);
|
|
1036
|
+
if (label && label.length > 200) return {
|
|
1037
|
+
command: null,
|
|
1038
|
+
error: `command.target.label exceeds 200 characters`
|
|
1039
|
+
};
|
|
1040
|
+
const launch = parseLaunch(target.launch);
|
|
1041
|
+
if (launch) {
|
|
1042
|
+
for (const [field, value] of [["search", launch.search], ["hash", launch.hash]]) if (value && value.length > DESKTOP_COMMAND_LAUNCH_MAX_LENGTH) return {
|
|
1043
|
+
command: null,
|
|
1044
|
+
error: `command.target.launch.${field} exceeds ${DESKTOP_COMMAND_LAUNCH_MAX_LENGTH} characters`
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
const callSource = input.call !== void 0 ? input.call : input.request;
|
|
1048
|
+
let call;
|
|
1049
|
+
if (callSource !== void 0 && callSource !== null) {
|
|
1050
|
+
if (!isRecord$1(callSource)) return {
|
|
1051
|
+
command: null,
|
|
1052
|
+
error: "command.call must be an object"
|
|
1053
|
+
};
|
|
1054
|
+
const method = asTrimmed(callSource.method);
|
|
1055
|
+
if (!method) return {
|
|
1056
|
+
command: null,
|
|
1057
|
+
error: "command.call.method is required"
|
|
1058
|
+
};
|
|
1059
|
+
if (!isDesktopCallMethod(method)) return {
|
|
1060
|
+
command: null,
|
|
1061
|
+
error: "command.call.method has an unsupported format"
|
|
1062
|
+
};
|
|
1063
|
+
const size = measureDesktopCommandPayload(callSource.input);
|
|
1064
|
+
if (size === null) return {
|
|
1065
|
+
command: null,
|
|
1066
|
+
error: "command.call.input must be JSON-serializable"
|
|
1067
|
+
};
|
|
1068
|
+
if (size > 32768) return {
|
|
1069
|
+
command: null,
|
|
1070
|
+
error: `command.call.input exceeds ${DESKTOP_COMMAND_PAYLOAD_MAX_BYTES} bytes`
|
|
1071
|
+
};
|
|
1072
|
+
call = {
|
|
1073
|
+
method,
|
|
1074
|
+
...callSource.input === void 0 ? {} : { input: callSource.input }
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
const surface = target.surface === "overlay" ? "overlay" : void 0;
|
|
1078
|
+
const command = {
|
|
1079
|
+
type: "desktop.open",
|
|
1080
|
+
target: {
|
|
1081
|
+
kind: "app",
|
|
1082
|
+
appId,
|
|
1083
|
+
...label ? { label } : {},
|
|
1084
|
+
...launch ? { launch } : {},
|
|
1085
|
+
...surface ? { surface } : {}
|
|
1086
|
+
},
|
|
1087
|
+
...call ? { call } : {}
|
|
1088
|
+
};
|
|
1089
|
+
const totalSize = measureDesktopCommandPayload(command);
|
|
1090
|
+
if (totalSize === null) return {
|
|
1091
|
+
command: null,
|
|
1092
|
+
error: "command must be JSON-serializable"
|
|
1093
|
+
};
|
|
1094
|
+
if (totalSize > 40960) return {
|
|
1095
|
+
command: null,
|
|
1096
|
+
error: `command exceeds ${DESKTOP_COMMAND_MAX_BYTES} bytes`
|
|
1097
|
+
};
|
|
1098
|
+
return {
|
|
1099
|
+
command,
|
|
1100
|
+
error: null
|
|
1101
|
+
};
|
|
1102
|
+
};
|
|
1103
|
+
//#endregion
|
|
1104
|
+
//#region src/apis/channels.ts
|
|
1105
|
+
var ChannelsApi = class {
|
|
1106
|
+
transport;
|
|
1107
|
+
constructor(transport) {
|
|
1108
|
+
this.transport = transport;
|
|
1109
|
+
}
|
|
1110
|
+
list(customFetch) {
|
|
1111
|
+
return this.transport.request("/api/channels", {
|
|
1112
|
+
method: "GET",
|
|
1113
|
+
fetch: customFetch
|
|
1114
|
+
});
|
|
1115
|
+
}
|
|
1116
|
+
create(data) {
|
|
1117
|
+
return this.transport.request("/api/channels", {
|
|
1118
|
+
method: "POST",
|
|
1119
|
+
headers: { "Content-Type": "application/json" },
|
|
1120
|
+
body: JSON.stringify(data)
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1123
|
+
startWeChatLogin(data) {
|
|
1124
|
+
return this.transport.request("/api/channels/wechat/login/start", {
|
|
1125
|
+
method: "POST",
|
|
1126
|
+
headers: { "Content-Type": "application/json" },
|
|
1127
|
+
body: JSON.stringify(data)
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
waitWeChatLogin(data) {
|
|
1131
|
+
return this.transport.request("/api/channels/wechat/login/wait", {
|
|
1132
|
+
method: "POST",
|
|
1133
|
+
headers: { "Content-Type": "application/json" },
|
|
1134
|
+
body: JSON.stringify(data)
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
delete(id) {
|
|
1138
|
+
return this.transport.request(`/api/channels/${id}`, { method: "DELETE" });
|
|
1139
|
+
}
|
|
1156
1140
|
};
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
kindVersion: z.number().int().positive(),
|
|
1198
|
-
props: jsonObjectSchema,
|
|
1199
|
-
style: jsonObjectSchema.optional(),
|
|
1200
|
-
source: z.object({
|
|
1201
|
-
kind: z.string().min(1).max(80),
|
|
1202
|
-
ref: z.string().min(1).max(4096),
|
|
1203
|
-
snapshot: jsonObjectSchema.optional()
|
|
1204
|
-
}).strict().optional()
|
|
1205
|
-
}).strict();
|
|
1206
|
-
const BoardAuthoringItemSchema = z.union([BoardBuiltinAuthoringItemSchema, BoardExtensionAuthoringItemSchema]);
|
|
1207
|
-
/** JSON Merge Patch semantics, constrained to the stable Item envelope. */
|
|
1208
|
-
const BoardItemPatchSchema = z.object({
|
|
1209
|
-
position: BoardAuthoringPositionPatchSchema.optional(),
|
|
1210
|
-
size: BoardAuthoringSizeSchema.nullable().optional(),
|
|
1211
|
-
rotation: finiteSchema.optional(),
|
|
1212
|
-
parentId: idSchema.nullable().optional(),
|
|
1213
|
-
locked: z.boolean().nullable().optional(),
|
|
1214
|
-
props: jsonObjectSchema.optional(),
|
|
1215
|
-
style: jsonObjectSchema.nullable().optional(),
|
|
1216
|
-
source: jsonObjectSchema.nullable().optional(),
|
|
1217
|
-
metadata: jsonObjectSchema.nullable().optional()
|
|
1218
|
-
}).strict().refine((patch) => Object.keys(patch).length > 0, "item patch is empty");
|
|
1219
|
-
const BoardConnectionInputSchema = BoardConnectionSchema;
|
|
1220
|
-
const stripServerFields = (value) => {
|
|
1221
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
1222
|
-
const { boardId: _boardId, revision: _revision, ...input } = value;
|
|
1223
|
-
return input;
|
|
1141
|
+
//#endregion
|
|
1142
|
+
//#region src/apis/cron-jobs.ts
|
|
1143
|
+
const toQuery = (params) => {
|
|
1144
|
+
const query = new URLSearchParams();
|
|
1145
|
+
for (const [key, value] of Object.entries(params)) if (value !== void 0 && value !== null && value !== "") query.set(key, String(value));
|
|
1146
|
+
const text = query.toString();
|
|
1147
|
+
return text ? `?${text}` : "";
|
|
1148
|
+
};
|
|
1149
|
+
var CronJobsApi = class {
|
|
1150
|
+
transport;
|
|
1151
|
+
constructor(transport) {
|
|
1152
|
+
this.transport = transport;
|
|
1153
|
+
}
|
|
1154
|
+
list(spaceId) {
|
|
1155
|
+
const query = toQuery({ spaceId });
|
|
1156
|
+
return this.transport.request(`/api/cron-jobs${query}`);
|
|
1157
|
+
}
|
|
1158
|
+
get(id) {
|
|
1159
|
+
return this.transport.request(`/api/cron-jobs/${id}`);
|
|
1160
|
+
}
|
|
1161
|
+
update(id, patch) {
|
|
1162
|
+
return this.transport.request(`/api/cron-jobs/${id}`, {
|
|
1163
|
+
method: "PATCH",
|
|
1164
|
+
headers: { "Content-Type": "application/json" },
|
|
1165
|
+
body: JSON.stringify(patch)
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
delete(id) {
|
|
1169
|
+
return this.transport.request(`/api/cron-jobs/${id}`, { method: "DELETE" });
|
|
1170
|
+
}
|
|
1171
|
+
toggle(id, enabled) {
|
|
1172
|
+
return this.update(id, { enabled });
|
|
1173
|
+
}
|
|
1174
|
+
runs(cronJobId, options = {}) {
|
|
1175
|
+
const query = toQuery({
|
|
1176
|
+
limit: options.limit,
|
|
1177
|
+
cursor: options.cursor
|
|
1178
|
+
});
|
|
1179
|
+
return this.transport.request(`/api/cron-jobs/${cronJobId}/runs${query}`);
|
|
1180
|
+
}
|
|
1224
1181
|
};
|
|
1225
|
-
const BoardEffectCommandInputSchema = z.preprocess(stripServerFields, BoardEffectInputSchema);
|
|
1226
|
-
const BoardCompositionCommandInputSchema = z.preprocess(stripServerFields, BoardCompositionInputSchema);
|
|
1227
|
-
const BoardSemanticCommandSchema = z.discriminatedUnion("type", [
|
|
1228
|
-
z.object({
|
|
1229
|
-
type: z.literal("board.patch"),
|
|
1230
|
-
patch: z.object({
|
|
1231
|
-
title: z.string().min(1).max(255).optional(),
|
|
1232
|
-
metadata: jsonObjectSchema.nullable().optional(),
|
|
1233
|
-
metadataPatch: jsonObjectSchema.optional()
|
|
1234
|
-
}).strict().refine((patch) => Object.keys(patch).length > 0, "board patch is empty")
|
|
1235
|
-
}).strict(),
|
|
1236
|
-
z.object({
|
|
1237
|
-
type: z.literal("item.create"),
|
|
1238
|
-
item: BoardAuthoringItemSchema
|
|
1239
|
-
}).strict(),
|
|
1240
|
-
z.object({
|
|
1241
|
-
type: z.literal("item.patch"),
|
|
1242
|
-
itemId: idSchema,
|
|
1243
|
-
patch: BoardItemPatchSchema
|
|
1244
|
-
}).strict(),
|
|
1245
|
-
z.object({
|
|
1246
|
-
type: z.literal("item.replace"),
|
|
1247
|
-
itemId: idSchema,
|
|
1248
|
-
item: BoardAuthoringItemSchema
|
|
1249
|
-
}).strict(),
|
|
1250
|
-
z.object({
|
|
1251
|
-
type: z.literal("item.delete"),
|
|
1252
|
-
itemId: idSchema,
|
|
1253
|
-
cascade: z.boolean().default(false)
|
|
1254
|
-
}).strict(),
|
|
1255
|
-
z.object({
|
|
1256
|
-
type: z.literal("item.reorder"),
|
|
1257
|
-
itemId: idSchema,
|
|
1258
|
-
index: z.number().int().nonnegative()
|
|
1259
|
-
}).strict(),
|
|
1260
|
-
z.object({
|
|
1261
|
-
type: z.literal("connection.create"),
|
|
1262
|
-
connection: BoardConnectionInputSchema
|
|
1263
|
-
}).strict(),
|
|
1264
|
-
z.object({
|
|
1265
|
-
type: z.literal("connection.patch"),
|
|
1266
|
-
connectionId: idSchema,
|
|
1267
|
-
patch: BoardConnectionPatchSchema
|
|
1268
|
-
}).strict(),
|
|
1269
|
-
z.object({
|
|
1270
|
-
type: z.literal("connection.delete"),
|
|
1271
|
-
connectionId: idSchema
|
|
1272
|
-
}).strict(),
|
|
1273
|
-
z.object({
|
|
1274
|
-
type: z.literal("effect.apply"),
|
|
1275
|
-
effect: BoardEffectCommandInputSchema
|
|
1276
|
-
}).strict(),
|
|
1277
|
-
z.object({
|
|
1278
|
-
type: z.literal("effect.delete"),
|
|
1279
|
-
effectId: idSchema
|
|
1280
|
-
}).strict(),
|
|
1281
|
-
z.object({
|
|
1282
|
-
type: z.literal("composition.apply"),
|
|
1283
|
-
composition: BoardCompositionCommandInputSchema
|
|
1284
|
-
}).strict(),
|
|
1285
|
-
z.object({
|
|
1286
|
-
type: z.literal("composition.delete"),
|
|
1287
|
-
compositionId: idSchema
|
|
1288
|
-
}).strict()
|
|
1289
|
-
]);
|
|
1290
|
-
const BoardSemanticMutationSchema = z.object({
|
|
1291
|
-
mutationId: idSchema,
|
|
1292
|
-
baseVersion: z.number().int().nonnegative(),
|
|
1293
|
-
clientId: idSchema.optional(),
|
|
1294
|
-
undoGroupId: idSchema.optional(),
|
|
1295
|
-
/** Validate (including server-side reference checks) without writing. */
|
|
1296
|
-
dryRun: z.boolean().default(false),
|
|
1297
|
-
commands: z.array(BoardSemanticCommandSchema).min(1).max(5e4)
|
|
1298
|
-
}).strict();
|
|
1299
|
-
z.object({
|
|
1300
|
-
include: z.array(z.enum([
|
|
1301
|
-
"items",
|
|
1302
|
-
"connections",
|
|
1303
|
-
"effects",
|
|
1304
|
-
"compositions",
|
|
1305
|
-
"playback"
|
|
1306
|
-
])).optional(),
|
|
1307
|
-
itemIds: z.array(idSchema).max(5e4).optional(),
|
|
1308
|
-
connectionIds: z.array(idSchema).max(5e4).optional(),
|
|
1309
|
-
effectIds: z.array(idSchema).max(5e4).optional(),
|
|
1310
|
-
compositionIds: z.array(idSchema).max(5e4).optional(),
|
|
1311
|
-
viewport: z.object({
|
|
1312
|
-
x: finiteSchema,
|
|
1313
|
-
y: finiteSchema,
|
|
1314
|
-
width: finiteSchema.positive(),
|
|
1315
|
-
height: finiteSchema.positive()
|
|
1316
|
-
}).optional()
|
|
1317
|
-
}).strict();
|
|
1318
1182
|
//#endregion
|
|
1319
|
-
//#region
|
|
1320
|
-
const
|
|
1183
|
+
//#region src/apis/generations.ts
|
|
1184
|
+
const DEFAULT_INTERVAL_MS = 1500;
|
|
1185
|
+
const DEFAULT_TIMEOUT_MS = 18e5;
|
|
1186
|
+
function sleep$1(ms, signal) {
|
|
1187
|
+
if (signal?.aborted) return Promise.reject(signal.reason ?? /* @__PURE__ */ new Error("Generation wait aborted"));
|
|
1188
|
+
return new Promise((resolve, reject) => {
|
|
1189
|
+
const cleanup = () => signal?.removeEventListener("abort", onAbort);
|
|
1190
|
+
const timer = setTimeout(() => {
|
|
1191
|
+
cleanup();
|
|
1192
|
+
resolve();
|
|
1193
|
+
}, ms);
|
|
1194
|
+
const onAbort = () => {
|
|
1195
|
+
clearTimeout(timer);
|
|
1196
|
+
cleanup();
|
|
1197
|
+
reject(signal?.reason ?? /* @__PURE__ */ new Error("Generation wait aborted"));
|
|
1198
|
+
};
|
|
1199
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1200
|
+
});
|
|
1201
|
+
}
|
|
1202
|
+
function isGenerationTaskResult(value) {
|
|
1203
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
1204
|
+
const record = value;
|
|
1205
|
+
if (typeof record.model !== "string" || !Array.isArray(record.output)) return false;
|
|
1206
|
+
if (record.requestId !== void 0 && typeof record.requestId !== "string") return false;
|
|
1207
|
+
if (record.cost !== void 0 && (typeof record.cost !== "number" || !Number.isFinite(record.cost))) return false;
|
|
1208
|
+
if (record.billing !== void 0 && record.billing !== null) {
|
|
1209
|
+
if (!record.billing || typeof record.billing !== "object" || Array.isArray(record.billing)) return false;
|
|
1210
|
+
const billing = record.billing;
|
|
1211
|
+
if (billing.officialCostUsd !== void 0 && (typeof billing.officialCostUsd !== "number" || !Number.isFinite(billing.officialCostUsd))) return false;
|
|
1212
|
+
if (typeof billing.amountUsd !== "number" || !Number.isFinite(billing.amountUsd)) return false;
|
|
1213
|
+
if (billing.discountMultiplier !== void 0 && (typeof billing.discountMultiplier !== "number" || !Number.isFinite(billing.discountMultiplier) || billing.discountMultiplier < 0 || billing.discountMultiplier > 1)) return false;
|
|
1214
|
+
if (typeof billing.usageType !== "string") return false;
|
|
1215
|
+
if (billing.status !== "recorded" && billing.status !== "overage" && billing.status !== "skipped") return false;
|
|
1216
|
+
if (billing.reason !== void 0 && billing.reason !== null && typeof billing.reason !== "string") return false;
|
|
1217
|
+
}
|
|
1218
|
+
return true;
|
|
1219
|
+
}
|
|
1220
|
+
var GenerationsApi = class {
|
|
1221
|
+
transport;
|
|
1222
|
+
constructor(transport) {
|
|
1223
|
+
this.transport = transport;
|
|
1224
|
+
}
|
|
1225
|
+
async create(request) {
|
|
1226
|
+
return this.transport.request("/api/generations", {
|
|
1227
|
+
method: "POST",
|
|
1228
|
+
headers: { "Content-Type": "application/json" },
|
|
1229
|
+
body: JSON.stringify(request)
|
|
1230
|
+
});
|
|
1231
|
+
}
|
|
1232
|
+
async wait(taskRunId, options = {}) {
|
|
1233
|
+
const intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;
|
|
1234
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1235
|
+
const startedAt = Date.now();
|
|
1236
|
+
while (true) {
|
|
1237
|
+
if (options.signal?.aborted) throw options.signal.reason ?? /* @__PURE__ */ new Error("Generation wait aborted");
|
|
1238
|
+
const detail = await this.transport.request(`/api/tasks/${taskRunId}`);
|
|
1239
|
+
options.onPoll?.(detail);
|
|
1240
|
+
if (detail.run.taskType !== "generation") throw new Error(`Task is not a generation task: ${detail.run.taskType}`);
|
|
1241
|
+
if (detail.run.status === "completed") {
|
|
1242
|
+
if (!isGenerationTaskResult(detail.run.result)) throw new Error("Generation task completed without a valid result");
|
|
1243
|
+
return detail.run.result;
|
|
1244
|
+
}
|
|
1245
|
+
if (detail.run.status === "failed") {
|
|
1246
|
+
const message = detail.run.errorMessage || "Generation task failed";
|
|
1247
|
+
throw new Error(`${message}\ntask ID: ${taskRunId}`);
|
|
1248
|
+
}
|
|
1249
|
+
const remainingMs = timeoutMs - (Date.now() - startedAt);
|
|
1250
|
+
if (remainingMs <= 0) throw new Error(`Generation task timed out after ${timeoutMs}ms`);
|
|
1251
|
+
await sleep$1(Math.min(intervalMs, remainingMs), options.signal);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
async createAndWait(request, options) {
|
|
1255
|
+
const created = await this.create(request);
|
|
1256
|
+
return this.wait(created.taskRunId, options);
|
|
1257
|
+
}
|
|
1258
|
+
};
|
|
1321
1259
|
//#endregion
|
|
1322
|
-
//#region
|
|
1323
|
-
const
|
|
1324
|
-
|
|
1260
|
+
//#region src/apis/models.ts
|
|
1261
|
+
const MULTIMODAL_MODEL_TYPE = "multimodal";
|
|
1262
|
+
var ModelsApi = class {
|
|
1263
|
+
transport;
|
|
1264
|
+
constructor(transport) {
|
|
1265
|
+
this.transport = transport;
|
|
1266
|
+
}
|
|
1267
|
+
async list() {
|
|
1268
|
+
return this.transport.request("/api/models");
|
|
1269
|
+
}
|
|
1270
|
+
async listMultimodal() {
|
|
1271
|
+
return this.transport.request(`/api/models?modelType=${MULTIMODAL_MODEL_TYPE}`);
|
|
1272
|
+
}
|
|
1273
|
+
async status() {
|
|
1274
|
+
return this.transport.request("/api/models/status");
|
|
1275
|
+
}
|
|
1276
|
+
};
|
|
1325
1277
|
//#endregion
|
|
1326
|
-
//#region
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
const
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
const DESKTOP_COMMAND_MAX_BYTES = 40960;
|
|
1340
|
-
const DESKTOP_COMMAND_LAUNCH_MAX_LENGTH = NAVIGATION_LAUNCH_MAX_LENGTH;
|
|
1341
|
-
const DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS = 6e5;
|
|
1342
|
-
const DESKTOP_COMMAND_MAX_TIMEOUT_MS = 432e5;
|
|
1343
|
-
const DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS = 600;
|
|
1344
|
-
/** Keeps pending commands reportable for the full wait window plus settlement grace. */
|
|
1345
|
-
const DESKTOP_COMMAND_PENDING_TTL_SECONDS = 43800;
|
|
1346
|
-
const DESKTOP_COMMAND_TERMINAL_TTL_SECONDS = 1800;
|
|
1347
|
-
const DESKTOP_COMMAND_TERMINAL_STATUSES = [
|
|
1348
|
-
"applied",
|
|
1349
|
-
"no_active_client",
|
|
1350
|
-
"desktop_host_unavailable",
|
|
1351
|
-
"rejected",
|
|
1352
|
-
"unsupported",
|
|
1353
|
-
"timeout"
|
|
1354
|
-
];
|
|
1355
|
-
const isTerminalDesktopCommandStatus = (status) => DESKTOP_COMMAND_TERMINAL_STATUSES.includes(status);
|
|
1356
|
-
/**
|
|
1357
|
-
* The surface a desktop open should use: an explicit request wins, then
|
|
1358
|
-
* whatever the App declared at publish time. `window` is the implicit
|
|
1359
|
-
* default and yields `undefined` so the command stays compact.
|
|
1360
|
-
*/
|
|
1361
|
-
function resolveOpenSurface(requested, declared) {
|
|
1362
|
-
return (requested ?? declared) === "overlay" ? "overlay" : void 0;
|
|
1363
|
-
}
|
|
1364
|
-
const METHOD_RE = new RegExp(`^[A-Za-z][A-Za-z0-9_.:-]{0,63}$`);
|
|
1365
|
-
const isDesktopCallMethod = (value) => typeof value === "string" && METHOD_RE.test(value);
|
|
1366
|
-
const DESKTOP_COMMAND_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
|
|
1367
|
-
const parseDesktopCommandId = (value) => {
|
|
1368
|
-
if (typeof value !== "string") return null;
|
|
1369
|
-
const trimmed = value.trim();
|
|
1370
|
-
return DESKTOP_COMMAND_ID_RE.test(trimmed) ? trimmed : null;
|
|
1278
|
+
//#region src/apis/prompts.ts
|
|
1279
|
+
var PromptsApi = class {
|
|
1280
|
+
transport;
|
|
1281
|
+
constructor(transport) {
|
|
1282
|
+
this.transport = transport;
|
|
1283
|
+
}
|
|
1284
|
+
async list(options, customFetch) {
|
|
1285
|
+
const params = new URLSearchParams();
|
|
1286
|
+
if (options?.spaceId) params.set("spaceId", options.spaceId);
|
|
1287
|
+
const query = params.toString();
|
|
1288
|
+
const path = query ? `/api/prompts?${query}` : "/api/prompts";
|
|
1289
|
+
return this.transport.request(path, { fetch: customFetch });
|
|
1290
|
+
}
|
|
1371
1291
|
};
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1292
|
+
//#endregion
|
|
1293
|
+
//#region src/apis/skills.ts
|
|
1294
|
+
var SkillsApi = class {
|
|
1295
|
+
transport;
|
|
1296
|
+
constructor(transport) {
|
|
1297
|
+
this.transport = transport;
|
|
1298
|
+
}
|
|
1299
|
+
async list(options, customFetch) {
|
|
1300
|
+
const params = new URLSearchParams();
|
|
1301
|
+
if (options?.spaceId) params.set("spaceId", options.spaceId);
|
|
1302
|
+
const query = params.toString();
|
|
1303
|
+
const path = query ? `/api/skills?${query}` : "/api/skills";
|
|
1304
|
+
return this.transport.request(path, { fetch: customFetch });
|
|
1305
|
+
}
|
|
1377
1306
|
};
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1307
|
+
//#endregion
|
|
1308
|
+
//#region src/apis/public-assets.ts
|
|
1309
|
+
function createAbortError() {
|
|
1310
|
+
if (typeof DOMException === "function") return new DOMException("The operation was aborted.", "AbortError");
|
|
1311
|
+
const error = /* @__PURE__ */ new Error("The operation was aborted.");
|
|
1312
|
+
error.name = "AbortError";
|
|
1313
|
+
return error;
|
|
1314
|
+
}
|
|
1315
|
+
function uploadWithProgress(input) {
|
|
1316
|
+
return new Promise((resolve, reject) => {
|
|
1317
|
+
if (input.signal?.aborted) {
|
|
1318
|
+
reject(createAbortError());
|
|
1319
|
+
return;
|
|
1320
|
+
}
|
|
1321
|
+
const xhr = new XMLHttpRequest();
|
|
1322
|
+
let settled = false;
|
|
1323
|
+
let lastRatio = 0;
|
|
1324
|
+
const handleSignalAbort = () => xhr.abort();
|
|
1325
|
+
const finish = (callback) => {
|
|
1326
|
+
if (settled) return;
|
|
1327
|
+
settled = true;
|
|
1328
|
+
input.signal?.removeEventListener("abort", handleSignalAbort);
|
|
1329
|
+
callback();
|
|
1330
|
+
};
|
|
1331
|
+
const emitProgress = (loaded, total) => {
|
|
1332
|
+
const ratio = Math.max(lastRatio, Math.min(1, total > 0 ? loaded / total : 0));
|
|
1333
|
+
lastRatio = ratio;
|
|
1334
|
+
try {
|
|
1335
|
+
input.onProgress({
|
|
1336
|
+
loadedBytes: Math.round(input.fileBytes * ratio),
|
|
1337
|
+
totalBytes: input.fileBytes,
|
|
1338
|
+
ratio
|
|
1339
|
+
});
|
|
1340
|
+
} catch {}
|
|
1341
|
+
};
|
|
1342
|
+
try {
|
|
1343
|
+
xhr.open(input.method, input.url);
|
|
1344
|
+
for (const [key, value] of Object.entries(input.headers ?? {})) {
|
|
1345
|
+
if (/[\r\n\0]/.test(value)) continue;
|
|
1346
|
+
xhr.setRequestHeader(key, value);
|
|
1347
|
+
}
|
|
1348
|
+
xhr.upload.onprogress = (event) => {
|
|
1349
|
+
if (event.lengthComputable) emitProgress(event.loaded, event.total);
|
|
1350
|
+
};
|
|
1351
|
+
xhr.onload = () => {
|
|
1352
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
1353
|
+
emitProgress(1, 1);
|
|
1354
|
+
finish(resolve);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
const detail = xhr.responseText?.trim();
|
|
1358
|
+
finish(() => reject(/* @__PURE__ */ new Error(`Public asset upload failed: HTTP ${xhr.status}${detail ? ` — ${detail}` : ""}`)));
|
|
1359
|
+
};
|
|
1360
|
+
xhr.onerror = () => finish(() => reject(/* @__PURE__ */ new Error("Public asset upload failed")));
|
|
1361
|
+
xhr.onabort = () => finish(() => reject(createAbortError()));
|
|
1362
|
+
input.signal?.addEventListener("abort", handleSignalAbort, { once: true });
|
|
1363
|
+
xhr.send(input.body);
|
|
1364
|
+
} catch (error) {
|
|
1365
|
+
finish(() => reject(error));
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1369
|
+
var PublicAssetsApi = class {
|
|
1370
|
+
transport;
|
|
1371
|
+
constructor(transport) {
|
|
1372
|
+
this.transport = transport;
|
|
1373
|
+
}
|
|
1374
|
+
createUpload(input, options = {}) {
|
|
1375
|
+
return this.transport.request("/api/public-assets/uploads", {
|
|
1376
|
+
method: "POST",
|
|
1377
|
+
headers: { "Content-Type": "application/json" },
|
|
1378
|
+
body: JSON.stringify(input),
|
|
1379
|
+
signal: options.signal
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
async upload(input) {
|
|
1383
|
+
if (input.signal?.aborted) throw createAbortError();
|
|
1384
|
+
const plan = await this.createUpload({
|
|
1385
|
+
purpose: input.purpose,
|
|
1386
|
+
uploadProtocol: "presigned_put_v1",
|
|
1387
|
+
spaceId: input.spaceId,
|
|
1388
|
+
sessionId: input.sessionId,
|
|
1389
|
+
file: {
|
|
1390
|
+
size: input.file.size,
|
|
1391
|
+
mimeType: input.mimeType,
|
|
1392
|
+
filename: input.filename
|
|
1393
|
+
}
|
|
1394
|
+
}, { signal: input.signal });
|
|
1395
|
+
if (input.signal?.aborted) throw createAbortError();
|
|
1396
|
+
let response;
|
|
1397
|
+
if (input.onProgress && typeof XMLHttpRequest === "function") {
|
|
1398
|
+
await uploadWithProgress({
|
|
1399
|
+
method: "PUT",
|
|
1400
|
+
url: plan.asset.uploadUrl,
|
|
1401
|
+
headers: plan.asset.uploadHeaders,
|
|
1402
|
+
body: input.file,
|
|
1403
|
+
fileBytes: input.file.size,
|
|
1404
|
+
onProgress: input.onProgress,
|
|
1405
|
+
signal: input.signal
|
|
1406
|
+
});
|
|
1407
|
+
return plan.asset;
|
|
1408
|
+
}
|
|
1409
|
+
response = await fetch(plan.asset.uploadUrl, {
|
|
1410
|
+
method: "PUT",
|
|
1411
|
+
headers: plan.asset.uploadHeaders,
|
|
1412
|
+
body: input.file,
|
|
1413
|
+
signal: input.signal
|
|
1414
|
+
});
|
|
1415
|
+
if (!response.ok) {
|
|
1416
|
+
const detail = await response.text().catch(() => "");
|
|
1417
|
+
throw new Error(`Public asset upload failed: HTTP ${response.status}${detail ? ` — ${detail}` : ""}`);
|
|
1418
|
+
}
|
|
1419
|
+
return plan.asset;
|
|
1420
|
+
}
|
|
1421
|
+
/** Durable public upload for any chat attachment (image or file). No space required. */
|
|
1422
|
+
uploadAppSource(input) {
|
|
1423
|
+
return this.upload({
|
|
1424
|
+
purpose: "app_source",
|
|
1425
|
+
spaceId: input.spaceId,
|
|
1426
|
+
sessionId: input.sessionId,
|
|
1427
|
+
file: input.file,
|
|
1428
|
+
mimeType: input.mimeType,
|
|
1429
|
+
filename: input.filename,
|
|
1430
|
+
onProgress: input.onProgress,
|
|
1431
|
+
signal: input.signal
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
uploadChatAttachment(input) {
|
|
1435
|
+
return this.upload({
|
|
1436
|
+
purpose: "chat_attachment",
|
|
1437
|
+
spaceId: input.spaceId,
|
|
1438
|
+
sessionId: input.sessionId,
|
|
1439
|
+
file: input.file,
|
|
1440
|
+
mimeType: input.mimeType,
|
|
1441
|
+
filename: input.filename,
|
|
1442
|
+
onProgress: input.onProgress,
|
|
1443
|
+
signal: input.signal
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
/** Preprocessed chat image (webp/jpeg). Same durable path as uploadChatAttachment. */
|
|
1447
|
+
uploadChatImageAttachment(input) {
|
|
1448
|
+
return this.uploadChatAttachment(input);
|
|
1449
|
+
}
|
|
1387
1450
|
};
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1451
|
+
//#endregion
|
|
1452
|
+
//#region src/apis/search.ts
|
|
1453
|
+
var SearchApi = class {
|
|
1454
|
+
transport;
|
|
1455
|
+
constructor(transport) {
|
|
1456
|
+
this.transport = transport;
|
|
1457
|
+
}
|
|
1458
|
+
query(input, customFetch) {
|
|
1459
|
+
const params = new URLSearchParams({ q: input.q });
|
|
1460
|
+
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
1461
|
+
for (const type of input.types ?? []) params.append("type", type);
|
|
1462
|
+
if (input.spaceId) params.set("spaceId", input.spaceId);
|
|
1463
|
+
if (input.labelRef) params.set("labelRef", input.labelRef);
|
|
1464
|
+
if (input.groupTurns === false) params.set("groupTurns", "false");
|
|
1465
|
+
return this.transport.request(`/api/search?${params.toString()}`, { fetch: customFetch });
|
|
1466
|
+
}
|
|
1467
|
+
/** Default (empty-query) command palette data: viewer-relative space signals. */
|
|
1468
|
+
overview(input, customFetch) {
|
|
1469
|
+
const params = new URLSearchParams();
|
|
1470
|
+
if (input?.spaceLimit !== void 0) params.set("spaceLimit", String(input.spaceLimit));
|
|
1471
|
+
if (input?.sessionLimit !== void 0) params.set("sessionLimit", String(input.sessionLimit));
|
|
1472
|
+
for (const spaceId of input?.recentSpaceIds ?? []) params.append("recentSpaceId", spaceId);
|
|
1473
|
+
const query = params.toString();
|
|
1474
|
+
return this.transport.request(`/api/palette/overview${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
1394
1475
|
}
|
|
1395
1476
|
};
|
|
1477
|
+
//#endregion
|
|
1478
|
+
//#region src/apis/references.ts
|
|
1479
|
+
const toSelector = (ref) => typeof ref === "string" ? ref : `${ref.type}:${ref.id}`;
|
|
1396
1480
|
/**
|
|
1397
|
-
*
|
|
1398
|
-
*
|
|
1399
|
-
*
|
|
1400
|
-
*
|
|
1401
|
-
* canonical so every later stage handles a single form.
|
|
1481
|
+
* Neutral access to the resource reference index. `query` lists references
|
|
1482
|
+
* touching a resource; `aggregate` returns grouped counts for a space. Callers
|
|
1483
|
+
* assemble collaboration graphs, lineage views, rankings, or trends from the
|
|
1484
|
+
* returned data.
|
|
1402
1485
|
*/
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
};
|
|
1408
|
-
const legacy = input.type === "preview.show";
|
|
1409
|
-
if (input.type !== "desktop.open" && !legacy) return {
|
|
1410
|
-
command: null,
|
|
1411
|
-
error: "command.type must be one of: desktop.open"
|
|
1412
|
-
};
|
|
1413
|
-
const target = isRecord$1(input.target) ? input.target : isRecord$1(input.preview) ? input.preview : null;
|
|
1414
|
-
if (!target) return {
|
|
1415
|
-
command: null,
|
|
1416
|
-
error: "command.target is required"
|
|
1417
|
-
};
|
|
1418
|
-
const kind = target.kind === "app" || legacy && target.kind === "work" ? "app" : target.kind === "file" ? "file" : null;
|
|
1419
|
-
if (!kind) return {
|
|
1420
|
-
command: null,
|
|
1421
|
-
error: "command.target.kind must be one of: app, file"
|
|
1422
|
-
};
|
|
1423
|
-
if (kind === "file") {
|
|
1424
|
-
const path = asTrimmed(target.path);
|
|
1425
|
-
if (!path) return {
|
|
1426
|
-
command: null,
|
|
1427
|
-
error: "command.target.path is required"
|
|
1428
|
-
};
|
|
1429
|
-
if (path.length > 2048 || path.startsWith("/") || path.includes("\0") || path.includes("\\") || path.split("/").some((segment) => segment === "..")) return {
|
|
1430
|
-
command: null,
|
|
1431
|
-
error: "command.target.path must be a relative Space file path"
|
|
1432
|
-
};
|
|
1433
|
-
if (input.call !== void 0 && input.call !== null) return {
|
|
1434
|
-
command: null,
|
|
1435
|
-
error: "command.call is only supported for app targets"
|
|
1436
|
-
};
|
|
1437
|
-
if (legacy && input.request !== void 0 && input.request !== null) return {
|
|
1438
|
-
command: null,
|
|
1439
|
-
error: "command.call is only supported for app targets"
|
|
1440
|
-
};
|
|
1441
|
-
return {
|
|
1442
|
-
command: {
|
|
1443
|
-
type: "desktop.open",
|
|
1444
|
-
target: {
|
|
1445
|
-
kind: "file",
|
|
1446
|
-
path
|
|
1447
|
-
}
|
|
1448
|
-
},
|
|
1449
|
-
error: null
|
|
1450
|
-
};
|
|
1486
|
+
var ReferencesApi = class {
|
|
1487
|
+
transport;
|
|
1488
|
+
constructor(transport) {
|
|
1489
|
+
this.transport = transport;
|
|
1451
1490
|
}
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
error: "command.target.appId must be an App id"
|
|
1460
|
-
};
|
|
1461
|
-
const label = asTrimmed(target.label);
|
|
1462
|
-
if (label && label.length > 200) return {
|
|
1463
|
-
command: null,
|
|
1464
|
-
error: `command.target.label exceeds 200 characters`
|
|
1465
|
-
};
|
|
1466
|
-
const launch = parseLaunch(target.launch);
|
|
1467
|
-
if (launch) {
|
|
1468
|
-
for (const [field, value] of [["search", launch.search], ["hash", launch.hash]]) if (value && value.length > DESKTOP_COMMAND_LAUNCH_MAX_LENGTH) return {
|
|
1469
|
-
command: null,
|
|
1470
|
-
error: `command.target.launch.${field} exceeds ${DESKTOP_COMMAND_LAUNCH_MAX_LENGTH} characters`
|
|
1471
|
-
};
|
|
1491
|
+
query(input, customFetch) {
|
|
1492
|
+
const params = new URLSearchParams({ source: toSelector(input.source) });
|
|
1493
|
+
if (input.direction) params.set("direction", input.direction);
|
|
1494
|
+
if (input.kinds && input.kinds.length > 0) params.set("kinds", input.kinds.join(","));
|
|
1495
|
+
if (input.days !== void 0) params.set("days", String(input.days));
|
|
1496
|
+
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
1497
|
+
return this.transport.request(`/api/references?${params.toString()}`, { fetch: customFetch });
|
|
1472
1498
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
if (
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
};
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
};
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
};
|
|
1499
|
+
aggregate(input, customFetch) {
|
|
1500
|
+
const params = new URLSearchParams({ space: input.spaceId });
|
|
1501
|
+
if (input.groupBy) params.set("groupBy", input.groupBy);
|
|
1502
|
+
if (input.kinds && input.kinds.length > 0) params.set("kinds", input.kinds.join(","));
|
|
1503
|
+
if (input.days !== void 0) params.set("days", String(input.days));
|
|
1504
|
+
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
1505
|
+
return this.transport.request(`/api/references/aggregate?${params.toString()}`, { fetch: customFetch });
|
|
1506
|
+
}
|
|
1507
|
+
};
|
|
1508
|
+
//#endregion
|
|
1509
|
+
//#region src/apis/session-access.ts
|
|
1510
|
+
var SessionAccessApi = class {
|
|
1511
|
+
transport;
|
|
1512
|
+
constructor(transport) {
|
|
1513
|
+
this.transport = transport;
|
|
1514
|
+
}
|
|
1515
|
+
get(sessionId) {
|
|
1516
|
+
return this.transport.request(`/api/sessions/${sessionId}/access`);
|
|
1517
|
+
}
|
|
1518
|
+
set(sessionId, body) {
|
|
1519
|
+
return this.transport.request(`/api/sessions/${sessionId}/access`, {
|
|
1520
|
+
method: "PATCH",
|
|
1521
|
+
headers: { "Content-Type": "application/json" },
|
|
1522
|
+
body: JSON.stringify(body)
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1525
|
+
remove(sessionId) {
|
|
1526
|
+
return this.transport.request(`/api/sessions/${sessionId}/access`, { method: "DELETE" });
|
|
1502
1527
|
}
|
|
1503
|
-
const surface = target.surface === "overlay" ? "overlay" : void 0;
|
|
1504
|
-
const command = {
|
|
1505
|
-
type: "desktop.open",
|
|
1506
|
-
target: {
|
|
1507
|
-
kind: "app",
|
|
1508
|
-
appId,
|
|
1509
|
-
...label ? { label } : {},
|
|
1510
|
-
...launch ? { launch } : {},
|
|
1511
|
-
...surface ? { surface } : {}
|
|
1512
|
-
},
|
|
1513
|
-
...call ? { call } : {}
|
|
1514
|
-
};
|
|
1515
|
-
const totalSize = measureDesktopCommandPayload(command);
|
|
1516
|
-
if (totalSize === null) return {
|
|
1517
|
-
command: null,
|
|
1518
|
-
error: "command must be JSON-serializable"
|
|
1519
|
-
};
|
|
1520
|
-
if (totalSize > 40960) return {
|
|
1521
|
-
command: null,
|
|
1522
|
-
error: `command exceeds ${DESKTOP_COMMAND_MAX_BYTES} bytes`
|
|
1523
|
-
};
|
|
1524
|
-
return {
|
|
1525
|
-
command,
|
|
1526
|
-
error: null
|
|
1527
|
-
};
|
|
1528
1528
|
};
|
|
1529
1529
|
//#endregion
|
|
1530
1530
|
//#region src/realtime.ts
|
|
@@ -3972,6 +3972,38 @@ var SpaceClient = class {
|
|
|
3972
3972
|
get(customFetch) {
|
|
3973
3973
|
return this.transport.request(`/api/spaces/${this.id}`, { fetch: customFetch });
|
|
3974
3974
|
}
|
|
3975
|
+
prepareRuntimeArchive(index, options = {}) {
|
|
3976
|
+
return this.transport.request(`/api/spaces/${this.id}/runtime/archives/prepare`, {
|
|
3977
|
+
method: "POST",
|
|
3978
|
+
headers: { "Content-Type": "application/json" },
|
|
3979
|
+
body: JSON.stringify(index),
|
|
3980
|
+
signal: options.signal
|
|
3981
|
+
});
|
|
3982
|
+
}
|
|
3983
|
+
commitRuntimeArchive(index, options = {}) {
|
|
3984
|
+
return this.transport.request(`/api/spaces/${this.id}/runtime/archives/commit`, {
|
|
3985
|
+
method: "POST",
|
|
3986
|
+
headers: { "Content-Type": "application/json" },
|
|
3987
|
+
body: JSON.stringify(index),
|
|
3988
|
+
signal: options.signal
|
|
3989
|
+
});
|
|
3990
|
+
}
|
|
3991
|
+
getRuntimeArchive(sessionId, turnId, options = {}) {
|
|
3992
|
+
return this.transport.request(`/api/spaces/${this.id}/runtime/archives/${sessionId}/${turnId}`, { signal: options.signal });
|
|
3993
|
+
}
|
|
3994
|
+
getRuntime(customFetch) {
|
|
3995
|
+
return this.transport.request(`/api/spaces/${this.id}/runtime`, { fetch: customFetch });
|
|
3996
|
+
}
|
|
3997
|
+
getSessionRuntime(sessionId, customFetch) {
|
|
3998
|
+
return this.transport.request(`/api/spaces/${this.id}/sessions/${sessionId}/runtime`, { fetch: customFetch });
|
|
3999
|
+
}
|
|
4000
|
+
confirmRuntimeStopped(sessionId, confirmation) {
|
|
4001
|
+
return this.transport.request(`/api/spaces/${this.id}/sessions/${sessionId}/runtime/confirm-stopped`, {
|
|
4002
|
+
method: "POST",
|
|
4003
|
+
headers: { "Content-Type": "application/json" },
|
|
4004
|
+
body: JSON.stringify(confirmation)
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
3975
4007
|
getStartup(customFetch) {
|
|
3976
4008
|
return this.transport.request(`/api/spaces/${this.id}/startup`, { fetch: customFetch });
|
|
3977
4009
|
}
|
|
@@ -4720,4 +4752,4 @@ var CohubHttpClient = class {
|
|
|
4720
4752
|
};
|
|
4721
4753
|
const createHttpClient = (options) => new CohubHttpClient(options);
|
|
4722
4754
|
//#endregion
|
|
4723
|
-
export {
|
|
4755
|
+
export { BoardEffectInputSchema as $, SkillsApi as A, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS as B, SessionPatchReducer as C, ReferencesApi as D, SessionAccessApi as E, ChannelsApi as F, parseDesktopCommand as G, DESKTOP_COMMAND_VERSION as H, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS as I, NAVIGATION_ERROR_MESSAGE_MAX_LENGTH as J, parseDesktopCommandId as K, DESKTOP_COMMAND_MAX_TIMEOUT_MS as L, ModelsApi as M, GenerationsApi as N, SearchApi as O, CronJobsApi as P, BoardSemanticMutationSchema as Q, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES as R, parseAssistantMessageCommit as S, ensureRealtimeConnected as T, isDesktopCallMethod as U, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS as V, isTerminalDesktopCommandStatus as W, BoardItemPatchSchema as X, BoardAuthoringItemSchema as Y, BoardSemanticCommandSchema as Z, PublicInviteApi as _, DesktopCommandsApi as a, BoardCompositionSchema as at, SessionGenerationStreamClient as b, ReferralsApi as c, parseBoardCompositionInput as ct, TasksApi as d, BOARD_BUILTIN_CAPABILITIES as dt, BoardEffectSchema as et, BoardClient as f, BOARD_BUILTIN_CLIP_KINDS as ft, SpacesApi as g, SpaceWebhooksApi as h, WorkCommerceApi as i, BoardCompositionInputSchema as it, PromptsApi as j, PublicAssetsApi as k, UsersApi as l, BoardConnectionSchema as lt, SpacePublicFilesApi as m, DEFAULT_BOARD_RENDER_LIMITS as mt, createHttpClient as n, BOARD_ANIMATION_CHANNELS as nt, UiCommandsApi as o, BoardProceduralClipSchema as ot, SpaceClient as p, BOARD_BUILTIN_EFFECT_KINDS as pt, resolveOpenSurface as q, AppCommerceApi as r, BOARD_ANIMATION_CHANNEL_CAPABILITIES as rt, AppsApi as s, BoardTrackSchema as st, CohubHttpClient as t, parseBoardEffectInput as tt, UserApi as u, BOARD_ARROW_STROKE_SIZE as ut, buildSpaceInvitePath as v, createSessionPatchReducer as w, createSessionGenerationStreamClient as x, buildSpacePath as y, DESKTOP_COMMAND_PENDING_TTL_SECONDS as z };
|