@neta-art/cohub 12.5.0 → 12.6.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 CHANGED
@@ -95,6 +95,14 @@ await session.messages.send({
95
95
  });
96
96
  ```
97
97
 
98
+ ## Space files
99
+
100
+ `space.files.read(path)` and `space.files.resolveUrl(path)` share requests: reads
101
+ made in the same task become one batched read, and concurrent reads of a file
102
+ share one request. In browsers with realtime, resolved URLs are remembered per
103
+ user across reloads, confirmed in the background and dropped when the file
104
+ changes; call `clearFileUrlCache()` on sign-out.
105
+
98
106
  ## Boards
99
107
 
100
108
  A Board is one document of `board` settings, `items` and `animations`. Bind
@@ -197,16 +205,14 @@ editor.addMedia("https://cdn.example.com/media?id=42", worldPoint(400, 0), {
197
205
  snapshot: { title: "Launch", naturalWidth: 1920, naturalHeight: 1080 },
198
206
  });
199
207
 
200
- // Media URLs load directly; these callbacks only receive Space paths.
201
- // A published copy can resolve paths against captured artifacts instead.
202
- const source = {
203
- resolveFileUrl: (path: string) => space.files.resolveUrl(path, { purpose: "preview" }),
204
- resolvePlaybackUrl: (path: string) => space.files.resolveUrl(path, { purpose: "playback" }),
205
- };
208
+ // Media URLs load directly; Space paths resolve through the Space's file URLs,
209
+ // which reload pictures when their file changes. A published copy can resolve
210
+ // paths against captured artifacts instead.
211
+ const source = space.boards.assetSource();
206
212
  const stage = mountBoardStage(element, {
207
213
  editor,
208
214
  source,
209
- assets: createBoardAssetManager({ resolveFileUrl: source.resolveFileUrl }),
215
+ assets: createBoardAssetManager(source),
210
216
  views: [{
211
217
  type: "acme.order",
212
218
  // Mount anything: a React root, a Vue app, plain DOM.
@@ -245,9 +251,10 @@ Pictures your own items show go through `itemAsset`. They share the built-in
245
251
  loader: CDN variants sized to the screen, loads ordered by where the view is
246
252
  heading, prefetch, compact copies when panned away, device budgets, one cache
247
253
  and exports. `src` is a Space path, resolved like an image item's, or a URL;
248
- `fit: "cover"` sizes pictures cropped to fill their box by the short edge. Call
249
- `invalidateItemAssets()` when the data it reads changes, and `invalidatePath`
250
- when a file changes:
254
+ `fit: "cover"` sizes pictures cropped to fill their box by the short edge. When
255
+ the data it reads changes for some items, call `invalidateItemAssets(ids)` and
256
+ `stage.invalidate({ items: ids })` (omit `ids` when everything changed); call
257
+ `invalidatePath` when a file changes:
251
258
 
252
259
  ```ts
253
260
  const assets = createBoardAssetManager({
@@ -6,6 +6,7 @@ type BoardAssetUrlOptions = {
6
6
  type BoardAssetSource = {
7
7
  resolveFileUrl: (path: string, options?: BoardAssetUrlOptions) => Promise<string | null>;
8
8
  resolvePlaybackUrl?: (path: string, options?: BoardAssetUrlOptions) => Promise<string | null>;
9
+ subscribe?: (listener: (path: string) => void) => () => void;
9
10
  };
10
11
  declare function resolveBoardMediaUrl(src: string, source: BoardAssetSource, purpose?: "preview" | "playback"): Promise<string | null>;
11
12
  type BoardPlayableMedia = {
@@ -1,5 +1,5 @@
1
1
  import { BoardDelta, BoardDocument, BoardPatch } from "../../protocol/dist/board-model.js";
2
- import { BoardApplyResult, BoardPlaybackSnapshot, BoardReadResult } from "../../protocol/dist/board.js";
2
+ import { BoardApplyResult, BoardPlaybackSnapshot, BoardReadInput, BoardReadResult } from "../../protocol/dist/board.js";
3
3
  import "../../protocol/dist/index.js";
4
4
  import { BoardReplicaDatabaseOptions, BoardReplicaScope, clearBoardReplicaStorage, createIndexedDbBoardReplicaStorage } from "./indexeddb.js";
5
5
  //#region src/board/replica/index.d.ts
@@ -14,7 +14,8 @@ type BoardChangedPayload = {
14
14
  after?: BoardDelta;
15
15
  };
16
16
  type BoardRemote = {
17
- get(): Promise<BoardReadResult>;
17
+ /** `only: []` reads metadata only; remotes may return the full Board. */
18
+ get(read?: Pick<BoardReadInput, "only">): Promise<BoardReadResult>;
18
19
  apply(patch: BoardPatch, options: {
19
20
  mutationId: string;
20
21
  clientId?: string;
@@ -57,7 +57,7 @@ function createBoardReplica(options) {
57
57
  return remote.subscribe({
58
58
  changed: (event) => receive(event.payload),
59
59
  playback: (event) => receivePlayback(event.payload.playback),
60
- resync: () => void retry()
60
+ resync: () => void resync()
61
61
  });
62
62
  } catch {
63
63
  return null;
@@ -220,7 +220,7 @@ function createBoardReplica(options) {
220
220
  }
221
221
  emit();
222
222
  }
223
- function retry() {
223
+ function retry(read = true) {
224
224
  if (disposed) return Promise.resolve();
225
225
  if (retryTimer) clearTimeout(retryTimer);
226
226
  retryTimer = null;
@@ -228,7 +228,18 @@ function createBoardReplica(options) {
228
228
  readError = null;
229
229
  writeError = null;
230
230
  emit();
231
- return refresh().then(flush);
231
+ return (read ? refresh() : Promise.resolve()).then(flush);
232
+ }
233
+ async function resync() {
234
+ await refreshing;
235
+ if (disposed) return;
236
+ if (!loaded || readError) return retry();
237
+ const revision = playbackRevision;
238
+ const head = await remote.get({ only: [] }).catch(() => null);
239
+ if (disposed) return;
240
+ if (!head || head.version > version) return retry();
241
+ if (revision === playbackRevision) playback = head.playback;
242
+ return retry(false);
232
243
  }
233
244
  function onOnline() {
234
245
  if (pending.length || readError || writeError) retry();
@@ -276,7 +287,7 @@ function createBoardReplica(options) {
276
287
  receive,
277
288
  receivePlayback,
278
289
  refresh,
279
- retry,
290
+ retry: () => retry(),
280
291
  dispose() {
281
292
  disposed = true;
282
293
  globalThis.removeEventListener?.("online", onOnline);
@@ -1,102 +1,31 @@
1
+ import { deleteByIndex, indexedDb } from "../../indexeddb.js";
1
2
  //#region src/board/replica/indexeddb.ts
2
3
  const DATABASE = "cohub-board";
3
4
  const VERSION = 1;
4
- const OPEN_TIMEOUT_MS = 3e3;
5
- const connections = /* @__PURE__ */ new Map();
6
- function open(name) {
7
- const existing = connections.get(name);
8
- if (existing) return existing;
9
- const opening = new Promise((resolve, reject) => {
10
- const factory = globalThis.indexedDB;
11
- if (!factory) {
12
- reject(/* @__PURE__ */ new Error("IndexedDB is unavailable."));
13
- return;
14
- }
15
- let late = false;
16
- const timer = setTimeout(() => {
17
- late = true;
18
- reject(/* @__PURE__ */ new Error("IndexedDB did not open in time."));
19
- }, OPEN_TIMEOUT_MS);
20
- const request = factory.open(name, VERSION);
21
- request.onupgradeneeded = () => {
22
- const db = request.result;
23
- db.createObjectStore("documents", { keyPath: "board" }).createIndex("user", "userKey");
24
- const pending = db.createObjectStore("pending", { keyPath: ["board", "mutationId"] });
25
- pending.createIndex("board", "board");
26
- pending.createIndex("user", "userKey");
27
- };
28
- request.onsuccess = () => {
29
- clearTimeout(timer);
30
- const db = request.result;
31
- if (late) {
32
- db.close();
33
- return;
34
- }
35
- const forget = () => {
36
- if (connections.get(name) === opening) connections.delete(name);
37
- };
38
- db.onversionchange = () => {
39
- db.close();
40
- forget();
41
- };
42
- db.onclose = forget;
43
- resolve(db);
44
- };
45
- request.onerror = () => {
46
- clearTimeout(timer);
47
- reject(request.error ?? /* @__PURE__ */ new Error("IndexedDB failed to open."));
48
- };
49
- });
50
- connections.set(name, opening);
51
- opening.catch(() => {
52
- if (connections.get(name) === opening) connections.delete(name);
53
- });
54
- return opening;
55
- }
56
- async function transact(name, stores, mode, work, retry = true) {
57
- const db = await open(name);
58
- let tx;
59
- try {
60
- tx = db.transaction(stores, mode);
61
- } catch (error) {
62
- if (!retry) throw error;
63
- db.close();
64
- connections.delete(name);
65
- return transact(name, stores, mode, work, false);
66
- }
67
- return new Promise((resolve, reject) => {
68
- const result = work(tx);
69
- tx.oncomplete = () => resolve(result());
70
- tx.onerror = () => reject(tx.error ?? /* @__PURE__ */ new Error("IndexedDB transaction failed."));
71
- tx.onabort = () => reject(tx.error ?? /* @__PURE__ */ new Error("IndexedDB transaction aborted."));
72
- });
73
- }
74
- function deleteByIndex(store, index, key) {
75
- const request = store.index(index).openKeyCursor(IDBKeyRange.only(key));
76
- request.onsuccess = () => {
77
- const cursor = request.result;
78
- if (!cursor) return;
79
- store.delete(cursor.primaryKey);
80
- cursor.continue();
81
- };
5
+ function upgrade(db) {
6
+ db.createObjectStore("documents", { keyPath: "board" }).createIndex("user", "userKey");
7
+ const pending = db.createObjectStore("pending", { keyPath: ["board", "mutationId"] });
8
+ pending.createIndex("board", "board");
9
+ pending.createIndex("user", "userKey");
82
10
  }
11
+ const database = (name) => indexedDb(name, VERSION, upgrade);
83
12
  let lastOrder = 0;
84
13
  function createIndexedDbBoardReplicaStorage(scope, options = {}) {
85
- const name = options.database ?? DATABASE;
14
+ const { transact } = database(options.database ?? DATABASE);
86
15
  const board = JSON.stringify([
87
16
  scope.userKey,
88
17
  scope.spaceId,
89
18
  scope.boardId
90
19
  ]);
91
20
  return {
92
- listPending: () => transact(name, ["pending"], "readonly", (tx) => {
21
+ listPending: () => transact(["pending"], "readonly", (tx) => {
93
22
  const request = tx.objectStore("pending").index("board").getAll(IDBKeyRange.only(board));
94
23
  return () => request.result.sort((a, b) => a.order - b.order).map(({ mutationId, patch }) => ({
95
24
  mutationId,
96
25
  patch
97
26
  }));
98
27
  }),
99
- putPending: ({ mutationId, patch }) => transact(name, ["pending"], "readwrite", (tx) => {
28
+ putPending: ({ mutationId, patch }) => transact(["pending"], "readwrite", (tx) => {
100
29
  lastOrder = Math.max(Date.now(), lastOrder + 1);
101
30
  const record = {
102
31
  board,
@@ -108,11 +37,11 @@ function createIndexedDbBoardReplicaStorage(scope, options = {}) {
108
37
  tx.objectStore("pending").put(record);
109
38
  return () => void 0;
110
39
  }),
111
- deletePending: (mutationId) => transact(name, ["pending"], "readwrite", (tx) => {
40
+ deletePending: (mutationId) => transact(["pending"], "readwrite", (tx) => {
112
41
  tx.objectStore("pending").delete([board, mutationId]);
113
42
  return () => void 0;
114
43
  }),
115
- readDocument: () => transact(name, ["documents"], "readonly", (tx) => {
44
+ readDocument: () => transact(["documents"], "readonly", (tx) => {
116
45
  const request = tx.objectStore("documents").get(board);
117
46
  return () => {
118
47
  const record = request.result;
@@ -122,7 +51,7 @@ function createIndexedDbBoardReplicaStorage(scope, options = {}) {
122
51
  } : null;
123
52
  };
124
53
  }),
125
- writeDocument: (version, document) => transact(name, ["documents"], "readwrite", (tx) => {
54
+ writeDocument: (version, document) => transact(["documents"], "readwrite", (tx) => {
126
55
  const store = tx.objectStore("documents");
127
56
  const request = store.get(board);
128
57
  request.onsuccess = () => {
@@ -142,7 +71,7 @@ function createIndexedDbBoardReplicaStorage(scope, options = {}) {
142
71
  }
143
72
  async function clearBoardReplicaStorage(options = {}) {
144
73
  const { userKey } = options;
145
- await transact(options.database ?? DATABASE, ["documents", "pending"], "readwrite", (tx) => {
74
+ await database(options.database ?? DATABASE).transact(["documents", "pending"], "readwrite", (tx) => {
146
75
  for (const name of ["documents", "pending"]) {
147
76
  const store = tx.objectStore(name);
148
77
  if (userKey === void 0) store.clear();
@@ -1,7 +1,7 @@
1
1
  import { ModelFormat } from "../../protocol/dist/fs/mime.js";
2
2
  import { BoardSceneItem } from "../model/scene.js";
3
3
  import { BoardAssetMedia, BoardAssetRef } from "../model/asset-key.js";
4
- import { BoardAssetUrlOptions } from "../model/media-playback.js";
4
+ import { BoardAssetSource, BoardAssetUrlOptions } from "../model/media-playback.js";
5
5
  import "../model/index.js";
6
6
  import { LruBudget } from "./lru.js";
7
7
  import { BoardImageTexturePool } from "./texture-pool.js";
@@ -25,7 +25,7 @@ type BoardModelPreviews = {
25
25
  type BoardAssetManager = {
26
26
  assetKey: (item: BoardSceneItem) => string | null;
27
27
  invalidatePath: (path: string) => void;
28
- invalidateItemAssets: () => void;
28
+ invalidateItemAssets: (ids?: Iterable<string>) => void;
29
29
  requestItem: (item: BoardSceneItem, edge?: number) => void;
30
30
  /** World point used to prioritize queued loads. */
31
31
  focus: (point: {
@@ -61,6 +61,7 @@ type BoardAssetChange = "texture" | "tone";
61
61
  type BoardAssetManagerOptions = {
62
62
  /** Resolve a Space file path to a URL a texture can load from; null when unavailable. */
63
63
  resolveFileUrl: (path: string, options?: BoardAssetUrlOptions) => Promise<string | null>;
64
+ subscribe?: BoardAssetSource["subscribe"];
64
65
  /** undefined keeps the built-in rule, null shows none; cached until `invalidateItemAssets`. */
65
66
  itemAsset?: (item: BoardSceneItem) => BoardAssetRef | null | undefined;
66
67
  concurrency?: number;
@@ -80,6 +80,7 @@ function createBoardAssetManager(options) {
80
80
  }
81
81
  const resolveFileUrl = options.resolveFileUrl;
82
82
  const entries = /* @__PURE__ */ new Map();
83
+ const keysByPath = /* @__PURE__ */ new Map();
83
84
  const pathVersions = /* @__PURE__ */ new Map();
84
85
  const starters = /* @__PURE__ */ new Map();
85
86
  const failedModels = /* @__PURE__ */ new Set();
@@ -92,6 +93,7 @@ function createBoardAssetManager(options) {
92
93
  model: 0
93
94
  };
94
95
  let disposed = false;
96
+ let stopSource = null;
95
97
  let focus = null;
96
98
  let trimTimer = null;
97
99
  let trimSince = 0;
@@ -131,16 +133,33 @@ function createBoardAssetManager(options) {
131
133
  cancelTone = toneQueue.size > 0 ? scheduleBoardIdle(readNextTone, 0) : null;
132
134
  }
133
135
  const keys = /* @__PURE__ */ new WeakMap();
136
+ const itemEpochs = /* @__PURE__ */ new Map();
134
137
  let keyEpoch = 0;
135
138
  function managedAssetKey(item) {
136
- const cached = keys.get(item);
137
- if (cached?.epoch === keyEpoch) return cached.key;
138
- const key = resolveAssetKey(item);
139
- keys.set(item, {
140
- epoch: keyEpoch,
141
- key
142
- });
143
- return key;
139
+ const itemEpoch = itemEpochs.get(item.id) ?? 0;
140
+ let record = keys.get(item);
141
+ if (record?.epoch !== keyEpoch || record.itemEpoch !== itemEpoch) {
142
+ const base = resolveAssetKey(item);
143
+ const source = base ? boardAssetKeySource(base) : null;
144
+ const path = source?.kind === "file" ? source.value : null;
145
+ record = {
146
+ epoch: keyEpoch,
147
+ itemEpoch,
148
+ base,
149
+ path,
150
+ version: 0,
151
+ key: base
152
+ };
153
+ keys.set(item, record);
154
+ }
155
+ if (record.path !== null) {
156
+ const version = pathVersions.get(record.path) ?? 0;
157
+ if (version !== record.version) {
158
+ record.version = version;
159
+ record.key = `local:${version}:${record.base}`;
160
+ }
161
+ }
162
+ return record.key;
144
163
  }
145
164
  function resolveAssetKey(item) {
146
165
  const asset = options.itemAsset?.(item);
@@ -149,9 +168,7 @@ function createBoardAssetManager(options) {
149
168
  const source = boardAssetKeySource(key);
150
169
  if (source?.media === "video" && options.loadVideoPreviews === false) return null;
151
170
  if (source?.media === "model" && !modelPreviewable(item)) return null;
152
- if (source?.kind !== "file") return key;
153
- const version = pathVersions.get(source.value) ?? 0;
154
- return version > 0 ? `local:${version}:${key}` : key;
171
+ return key;
155
172
  }
156
173
  function clearRetry(entry) {
157
174
  if (entry.retryTimer) {
@@ -163,9 +180,11 @@ function createBoardAssetManager(options) {
163
180
  let entry = entries.get(key);
164
181
  if (!entry) {
165
182
  const source = boardAssetKeySource(key);
183
+ const path = source?.kind === "file" ? source.value : null;
166
184
  entry = {
167
185
  media: source?.media ?? "image",
168
186
  cover: source?.fit === "cover",
187
+ path,
169
188
  source: null,
170
189
  url: null,
171
190
  texture: null,
@@ -182,6 +201,11 @@ function createBoardAssetManager(options) {
182
201
  lastUsedAt: now()
183
202
  };
184
203
  entries.set(key, entry);
204
+ if (path !== null) {
205
+ const keyed = keysByPath.get(path);
206
+ if (keyed) keyed.add(key);
207
+ else keysByPath.set(path, /* @__PURE__ */ new Set([key]));
208
+ }
185
209
  }
186
210
  return entry;
187
211
  }
@@ -203,6 +227,10 @@ function createBoardAssetManager(options) {
203
227
  starters.delete(key);
204
228
  if (entry.url || entry.texture) releaseTexture(entry.media, entry.url ?? "", entry.texture);
205
229
  entries.delete(key);
230
+ if (entry.path === null) return;
231
+ const keyed = keysByPath.get(entry.path);
232
+ keyed?.delete(key);
233
+ if (keyed?.size === 0) keysByPath.delete(entry.path);
206
234
  }
207
235
  function scheduleTrim() {
208
236
  const at = now();
@@ -464,18 +492,19 @@ function createBoardAssetManager(options) {
464
492
  const manager = {
465
493
  assetKey: managedAssetKey,
466
494
  invalidatePath(path) {
467
- if (disposed) return;
468
- const stale = [...entries.keys()].filter((key) => {
469
- const source = boardAssetKeySource(key);
470
- return source?.kind === "file" && source.value === path;
471
- });
472
- if (stale.length === 0) return;
495
+ const stale = keysByPath.get(path);
496
+ if (disposed || !stale) return;
473
497
  pathVersions.set(path, (pathVersions.get(path) ?? 0) + 1);
474
- keyEpoch += 1;
475
- for (const key of stale) notify(key);
498
+ for (const key of [...stale]) notify(key);
476
499
  },
477
- invalidateItemAssets() {
478
- if (options.itemAsset) keyEpoch += 1;
500
+ invalidateItemAssets(ids) {
501
+ if (!options.itemAsset) return;
502
+ if (!ids) {
503
+ keyEpoch += 1;
504
+ itemEpochs.clear();
505
+ return;
506
+ }
507
+ for (const id of ids) itemEpochs.set(id, (itemEpochs.get(id) ?? 0) + 1);
479
508
  },
480
509
  requestItem(item, edge = Number.POSITIVE_INFINITY) {
481
510
  if (disposed) return;
@@ -659,6 +688,7 @@ function createBoardAssetManager(options) {
659
688
  },
660
689
  destroy() {
661
690
  disposed = true;
691
+ stopSource?.();
662
692
  if (trimTimer !== null) clearTimeout(trimTimer);
663
693
  trimTimer = null;
664
694
  cancelTone?.();
@@ -669,6 +699,7 @@ function createBoardAssetManager(options) {
669
699
  unwarmable.clear();
670
700
  listeners.clear();
671
701
  pathVersions.clear();
702
+ itemEpochs.clear();
672
703
  starters.clear();
673
704
  failedModels.clear();
674
705
  for (const [key, entry] of entries) evict(key, entry);
@@ -676,6 +707,7 @@ function createBoardAssetManager(options) {
676
707
  for (const release of [...retiring]) release();
677
708
  }
678
709
  };
710
+ stopSource = options.subscribe?.((path) => manager.invalidatePath(path)) ?? null;
679
711
  return manager;
680
712
  }
681
713
  //#endregion
@@ -14,6 +14,7 @@ const Z_LIVE_STROKE = Number.MAX_SAFE_INTEGER - 1;
14
14
  const Z_OVERLAY = Number.MAX_SAFE_INTEGER;
15
15
  const POOL_LIMIT_PER_RENDERER = 48;
16
16
  const EMPTY_IDS = /* @__PURE__ */ new Set();
17
+ const NO_PLATES = /* @__PURE__ */ new Map();
17
18
  function idSetSignature(ids) {
18
19
  let hash = ids.size;
19
20
  for (const id of ids) {
@@ -257,13 +258,19 @@ function createBoardScene(options) {
257
258
  let paintedPlan = null;
258
259
  let paintedSig = "";
259
260
  let platesPending = false;
260
- let covered = EMPTY_IDS;
261
+ let covered = NO_PLATES;
261
262
  /**
262
263
  * Repaint the plates whose cards changed, within a per-frame budget. A card
263
264
  * is covered once a plate draws it; until then it stays live if it already is.
264
265
  */
265
266
  function paintPlates(input, current) {
266
267
  const { context, globalSig, scene } = input;
268
+ for (const id of input.staleIds ?? EMPTY_IDS) {
269
+ const plate = covered.get(id);
270
+ if (!plate) continue;
271
+ plate.sig = "";
272
+ paintedPlan = null;
273
+ }
267
274
  if (current === paintedPlan && globalSig === paintedSig) return false;
268
275
  const start = performance.now();
269
276
  const allowance = budget.allow("plate");
@@ -303,8 +310,8 @@ function createBoardScene(options) {
303
310
  plate.graphics.destroy();
304
311
  changed = true;
305
312
  }
306
- const next = /* @__PURE__ */ new Set();
307
- for (const plate of plates.values()) for (const item of plate.items) next.add(item.id);
313
+ const next = /* @__PURE__ */ new Map();
314
+ for (const plate of plates.values()) for (const item of plate.items) next.set(item.id, plate);
308
315
  covered = next;
309
316
  budget.spend("plate", painted, paintMs);
310
317
  platesPending = pending;
@@ -328,7 +335,7 @@ function createBoardScene(options) {
328
335
  paintedPlan = null;
329
336
  paintedSig = "";
330
337
  platesPending = false;
331
- covered = EMPTY_IDS;
338
+ covered = NO_PLATES;
332
339
  plan = null;
333
340
  planInputs = [];
334
341
  nearIds = EMPTY_IDS;
@@ -10,7 +10,6 @@ import { pickBoardColor, resolveItemColor } from "../model/palette.js";
10
10
  import { elementClientToLocal } from "../model/client-geometry.js";
11
11
  import { isCreationBoardTool } from "../editor/tool.js";
12
12
  import { resizeCursorForHandle } from "../editor/selection-transform.js";
13
- import { createBoardPlayer } from "../player/index.js";
14
13
  import { parseBoardCssColor } from "../render/css-color.js";
15
14
  import { itemAlpha } from "../render/palette.js";
16
15
  import { onBoardTextFontsChange } from "../render/text-measurement.js";
@@ -21,6 +20,7 @@ import { DEFAULT_BOARD_RENDER_LABELS, getBoardCardRenderer } from "../render/ren
21
20
  import { createBoardScriptHost } from "../render/script-host.js";
22
21
  import { defaultBoardRenderStyle } from "../render/style.js";
23
22
  import { boardRenderTheme } from "../render/theme.js";
23
+ import { createBoardPlayer } from "../player/index.js";
24
24
  import { createBoardScriptObservers } from "../model/script-observers.js";
25
25
  import { defaultBoardDeviceBudget } from "./device.js";
26
26
  import { scheduleBoardIdle } from "./idle.js";
@@ -1,4 +1,4 @@
1
- import { O as readRtcTransportStats, k as waitForIceGathering } from "./http.js";
1
+ import { A as readRtcTransportStats, j as waitForIceGathering } from "./http.js";
2
2
  import { c as HttpError, p as REALTIME_ROOM_EVENT_NAME_PATTERN } from "./http-error.js";
3
3
  import { z } from "zod";
4
4
  //#region \0rolldown/runtime.js
@@ -5084,7 +5084,8 @@ type SystemAuthOkEvent = {
5084
5084
  sessionId?: string | null;
5085
5085
  payload: {
5086
5086
  connectionId: string;
5087
- user: Record<string, unknown>;
5087
+ user: Record<string, unknown> | null;
5088
+ anonymous?: true;
5088
5089
  capabilities?: string[];
5089
5090
  };
5090
5091
  };
@@ -5135,6 +5136,11 @@ type SystemSubscribeOkEvent = {
5135
5136
  rooms: RealtimeRoom[];
5136
5137
  };
5137
5138
  };
5139
+ type RealtimeRoomRejection = {
5140
+ room: string;
5141
+ code: "BAD_ROOM" | "FORBIDDEN" | "UNAVAILABLE";
5142
+ message: string;
5143
+ };
5138
5144
  type SystemSubscribeErrorEvent = {
5139
5145
  id: string;
5140
5146
  timestamp: number;
@@ -5144,11 +5150,7 @@ type SystemSubscribeErrorEvent = {
5144
5150
  spaceId?: string | null;
5145
5151
  sessionId?: string | null;
5146
5152
  payload: {
5147
- rejected: Array<{
5148
- room: string;
5149
- code: "BAD_ROOM" | "FORBIDDEN";
5150
- message: string;
5151
- }>;
5153
+ rejected: RealtimeRoomRejection[];
5152
5154
  };
5153
5155
  };
5154
5156
  type RealtimeSessionRecord = Pick<SessionRecord$1, "id" | "spaceId" | "userUuid" | "title" | "source" | "status" | "activeTurn" | "activeTurnSequence" | "lastTurnIssue" | "externalSessionId" | "latestMessageText" | "lastMessageAt" | "lastMessageId" | "createdAt" | "updatedAt"> & {
@@ -8620,4 +8622,4 @@ declare const resolveVoiceInputWebsocketUrl: (options?: {
8620
8622
  env?: CohubEnvironment;
8621
8623
  }) => string;
8622
8624
  //#endregion
8623
- export { CheckpointDiffDelivery as $, SpacePublicEndpoints as $a, DisplayElement as $c, RealtimePatchOperation as $i, SpaceCommerceProduct as $n, ProjectionCursor as $o, SpaceSandboxConfig as $r, CompletionMessageRole as $s, PromptTemplateCatalogResponse as $t, BillingCreditExpiryGroup as A, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES as Aa, BoardDelta as Ac, GenerationModelPolicy as Ai, isRequestSourceClientId as Al, SessionTurnSignedUrlsResponse as An, RUNTIME_PROTOCOL_VERSION as Ao, SpaceFsUploadPlanEntry as Ar, HarnessKind as As, JsonPrimitive as At, BillingProductBillingInterval as B, DesktopCommandRecord as Ba, BoardTrack as Bc, normalizeGenerationPolicy as Bi, SpaceActivityContributor as Bn, RuntimeStatus as Bo, SpaceListOptions as Br, resolveHarness as Bs, LabelScopeType as Bt, BillingBalanceActivityStatus as C, AppBoardAsset as Ca, BoardTransactionRecord as Cc, scopeListHasPermission as Ci, ActorModel as Cl, SessionListFork as Cn, SessionTurnIndexItem as Co, SpaceFsReadFilesInput as Cr, SETTLED_TURN_STATUSES as Cs, GlobalSearchChatHit as Ct, BillingCheckoutConfirmation as D, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS as Da, BoardAnimationHeader as Dc, ChannelRuntimeState as Di, RequestSource as Dl, SessionRecord as Dn, StoredToolCall as Do, SpaceFsUploadDestination as Dr, nativeTurnCompleteSchema as Ds, GlobalSearchViewerRelation as Dt, BillingCheckoutActionState as E, DESKTOP_COMMAND_ACCEPT_TIMEOUT_MS as Ea, BoardAnimation as Ec, ChannelHealthReasonCode as Ei, REQUEST_SOURCE_VIA_MAX_LENGTH as El, SessionMessagesResponse as En, StoredIntermediateMessage as Eo, SpaceFsTreeResponse as Er, nativeRuntimeEventSchema as Es, GlobalSearchType as Et, BillingDiscountOfferRef as F, DesktopAppTarget as Fa, BoardMarker as Fc, decodeGenerationPolicy as Fi, parseRequestSourceFromHeaders as Fl, SkillCatalogResponse as Fn, RuntimeContextMessage as Fo, SpaceInvitation as Fr, assertHarnessAccess as Fs, LabelItemsResponse as Ft, BillingProductPromotion as G, DesktopTarget as Ga, AppAuthorizationRequest as Gc, AppVersionPublishedEvent as Gi, SpaceBootstrapStatus as Gn, runtimeCommandSchema as Go, SpacePendingDiffFileResponse as Gr, RuntimeArchiveSegment as Gs, PaletteOverviewResponse as Gt, BillingProductDisplay as H, DesktopFileTarget as Ha, parseBoardItem as Hc, GenerationContentBlock as Hi, SpaceBootstrapMeta as Hn, RuntimeTraceContext as Ho, SpaceMember as Hr, HarnessArchiveIndex as Hs, MeResponse as Ht, BillingDiscountPricing as I, DesktopCall as Ia, BoardPatch as Ic, encodeGenerationPolicy as Ii, readRequestSourceFromEnv as Il, SkillCatalogSource as In, RuntimeExecutionEvent as Io, SpaceInvitationListResponse as Ir, harnessLabel as Is, LabelItemsSessionFork as It, BillingResponsePayload as J, isTerminalDesktopCommandStatus as Ja, SearchTextRange as Jc, BoardPlaybackChangedEvent as Ji, SpaceCommerceBenefit as Jn, contextToPiMessages as Jo, SpacePresenceUser as Jr, validateArchiveBoundary as Js, PatchResourceLabelsInput as Jt, BillingPromotionCodePreview as K, defaultDesktopCommandTimeoutMs as Ka, AppAuthorizationResult as Kc, BoardAwarenessUpdatedEvent as Ki, SpaceChannelBindingInput as Kn, runtimeEventSchema as Ko, SpacePendingDiffSummary as Kr, RuntimeArchiveUpload as Ks, PaletteOverviewSpace as Kt, BillingHistoryPagination as L, DesktopCommand as La, BoardPatchSchema as Lc, filterGenerationDeclarationsByPolicy as Li, requestSourceToHeaders as Ll, SpaceAccess as Ln, RuntimeMessage as Lo, SpaceInvitationLocation as Lr, harnessSchema as Ls, LabelListItem as Lt, BillingCreditStatus as M, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS as Ma, BoardDocument as Mc, GenerationPolicy as Mi, isRequestSourceUuid as Ml, SessionTurnWindowResponse as Mn, RuntimeCapabilities as Mo, SpaceFsUploadProgress as Mr, LOCAL_HARNESS_SPECS as Ms, LabelAssignmentListItem as Mt, BillingCreditUnit as N, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS as Na, BoardItem as Nc, GenerationPolicyError as Ni, mergeRequestSourceIntoMeta as Nl, SessionTurnsPaginatedResponse as Nn, RuntimeCommand as No, SpaceFsUploadResponse as Nr, LocalHarness as Ns, LabelAssignmentPageInfo as Nt, BillingCheckoutResult as O, DESKTOP_COMMAND_MAX_TIMEOUT_MS as Oa, BoardAnimationSchema as Oc, DiscordChannelConfig as Oi, RequestSourceVia as Ol, SessionTurnIndexResponse as On, TurnIntermediateMessagesFile as Oo, SpaceFsUploadEntry as Or, nativeTurnProgressSchema as Os, InvitationDetail as Ot, BillingDiscountOffer as P, DESKTOP_COMMAND_VERSION as Pa, BoardKeyframe as Pc, assertGenerationRequestAllowedByPolicy as Pi, normalizeRequestSource as Pl, SkillCatalogEntry as Pn, RuntimeContext as Po, SpaceFsWriteFileInput as Pr, LocalHarnessSpec as Ps, LabelAssignmentRecord as Pt, Channel as Q, NavigationLaunch as Qa, DisplayCaptureParams as Qc, RealtimeAppVersionRecord as Qi, SpaceCommerceOrder as Qn, NativeProjection as Qo, SpaceSandboxAutoDestroyPolicy as Qr, CompletionMessageInput as Qs, PromptTemplateCatalogEntry as Qt, BillingPaymentStatus as R, DesktopCommandDispatchedPayload as Ra, BoardSettings as Rc, findGenerationModelPolicy as Ri, resolveRequestSourceChannel as Rl, SpaceAccessPolicy as Rn, RuntimePendingExecution as Ro, SpaceListFilter as Rr, isLocalHarness as Rs, LabelRecord as Rt, BillingBalanceActivityList as S, AppBoardArtifactManifest as Sa, BoardSnapshot as Sc, isUserLevelPermission as Si, ActorKind as Sl, SessionBindingRecord as Sn, MessageToolCallsFile as So, SpaceFsReadFilesError as Sr, RuntimeNativeStop as Ss, GenerationUsageSummary as St, BillingCatalogProduct as T, AppVersionSource as Ta, BOARD_ITEM_TYPES as Tc, ChannelHealth as Ti, COHUB_SOURCE_HEADER_NAMES as Tl, SessionMessagesPaginatedResponse as Tn, SpaceTurnsResponse$1 as To, SpaceFsTreePage as Tr, nativeIngestTurnSchema as Ts, GlobalSearchResult as Tt, BillingProductKind as U, DesktopOpenCommand as Ua, BillingPayload as Uc, GenerationModelDeclaration as Ui, SpaceBootstrapSource as Un, RuntimeTurnInput as Uo, SpaceMeta as Ur, RUNTIME_ARCHIVE_SEGMENT_BYTES as Us, ModelCatalogEntry as Ut, BillingProductCreditBenefit as V, DesktopCommandStatus as Va, BoardTrackSchema as Vc, parseGenerationPolicyFromEnv as Vi, SpaceActivityResponse as Vn, RuntimeStopConfirmation as Vo, SpaceListPage as Vr, HarnessArchive as Vs, LabelSource as Vt, BillingProductPricing as W, DesktopSurface as Wa, AppAuthorizationGrant as Wc, GenerationResult as Wi, SpaceBootstrapStage as Wn, RuntimeTurnUserMessage as Wo, SpaceModListItem as Wr, RuntimeArchivePage as Ws, PERMISSIONS as Wt, BillingSubscriptionHistoryStatus as X, resolveOpenSurface as Xa, DISPLAY_SYSTEM_ACTIONS as Xc, LabelAssignmentsUpdatedEvent as Xi, SpaceCommerceCreditsBenefit as Xn, CanonicalProjectionMessage as Xo, SpaceRecord as Xr, CompletionImageInput as Xs, Permission as Xt, BillingSubscriptionHistoryList as Y, parseDesktopCommand as Ya, DISPLAY_ELEMENT_REF_PATTERN as Yc, ChannelEnvelope as Yi, SpaceCommerceBuyerProfile as Yn, selectRuntimeContextMessages as Yo, SpacePublicProfile as Yr, CompletionAssistantMessage as Ys, PatchResourceLabelsResponse as Yt, BillingSubscriptionSummary as Z, NavigationCall as Za, DisplayCapture as Zc, RealtimeAppRecord as Zi, SpaceCommerceFeatureBenefit as Zn, CanonicalProjectionTurn as Zo, SpaceRole as Zr, CompletionMessage as Zs, PromptAccessMode as Zt, AcceptInvitationResponse as _, normalizeAppDomainHostname as _a, BoardPlaybackCommand as _c, UserRulesResponse as _i, DisplayAction as _l, ReferralReward as _n, SessionTurnSegmentRecord as _o, SpaceFsFileKind as _r, NativeKnownResult as _s, CronJobRecord as _t, CohubRuntimeKind as a, RealtimeRoomMember as aa, SpaceCompletionStreamEvent as ac, SpaceUsageHourlyStat as ai, DisplayTree as al, PublicUserWorkItem as an, SpaceFsCopySource as ao, SpaceConfigUpdateResponse as ar, isProjectionCompaction as as, CheckpointDiffStatus as at, BillingBalanceActivity as b, AppArtifactManifest as ba, BoardReadResult as bc, UserSessionSpaceSummary as bi, SandboxSetupInfo as bl, SandboxSpecId as bn, SessionStats as bo, SpaceFsMoveInput as br, NativeTurnMessage as bs, GenerationUsageBlock as bt, normalizeVoiceInputWebsocketUrl as c, SessionCreatedEvent as ca, TaskRunBoard as cc, TaskRunDetailResponse as ci, DisplayVirtualStart as cl, ReferenceAggregateResponse as cn, BoardAwarenessGesture as co, SpaceEnvInput as cr, projectNativeSession as cs, ClaimReferralResponse as ct, resolveCohubEnvironment as d, AppDomainDnsRecord as da, BoardApplyResult as dc, UsageTotals as di, AppRtcMediaKind as dl, ReferenceQueryResponse as dn, BoardAwarenessUpdate as do, SpaceFsCreateDirectoryInput as dr, trimProjectionTurnsToCompaction as ds, CreateSpaceInput as dt, RealtimeRoom as ea, CompletionThinkingLevel as ec, SpaceSandboxProvider as ei, DisplayInfo as el, PublicReferral as en, SpaceFsCopyError as eo, SpaceCommerceProductBenefitBinding as er, ProjectionInput as es, CheckpointDiffFile as et, resolveExecutionAppId as f, AppDomainErrorCode as fa, BoardChangeSummary as fc, UserActivityQuery as fi, AppRtcPublication as fl, ReferenceQueryableType as fn, MessageRecord as fo, SpaceFsCreateUploadInput as fr, NATIVE_INGEST_MAX_TURNS as fs, CreateSpaceModInput as ft, resolveWebsocketUrl as g, AppDomainStatus as ga, BoardManifest as gc, UserProfile as gi, DISPLAY_ACTION_TYPES as gl, ReferralListItem as gn, SessionForkRecord as go, SpaceFsEntry as gr, NativeIngestTurn as gs, CronJobPayload as gt, resolveWebBaseUrl as h, AppDomainRemovedReason as ha, BoardHistoryPage as hc, UserActivityResponse as hi, RtcIceServers as hl, ReferralDashboard as hn, SessionFilesResponse as ho, SpaceFsEncoding as hr, NativeIngestResult as hs, CreateSpaceSessionInput as ht, CohubExecutionContext as i, RealtimeRoomHistoryEvent as ia, SpaceCompletionResult as ic, SpaceTurnsResponse as ii, DisplaySystemAction as il, PublicUserSpaceItem as in, SpaceFsCopyResult as io, SpaceConfigResponse as ir, fingerprintProjectionTurns as is, CheckpointDiffStats as it, BillingCreditGrantStatus as j, DESKTOP_COMMAND_PENDING_TTL_SECONDS as ja, BoardDiagnostic as jc, GenerationParameterConstraint as ji, isRequestSourceEmpty as jl, SessionTurnStreamSnapshotResponse as jn, RUNTIME_RECOVERY_BATCH_SIZE as jo, SpaceFsUploadPlanEntryInput as jr, LOCAL_HARNESSES as js, JsonValue as jt, BillingConversionIntent as k, DESKTOP_COMMAND_OPEN_TIMEOUT_MS as ka, BoardColor as kc, FeishuChannelConfig as ki, hasRequestSourceIdentity as kl, SessionTurnResponse as kn, RUNTIME_MAX_FRAME_BYTES as ko, SpaceFsUploadError as kr, runtimeNativeStopSchema as ks, JsonObject as kt, normalizeWebsocketUrl as l, SessionTurnPatchEvent as la, parseBoardDocument as lc, TaskRunRecord as li, normalizeDisplayPoint as ll, ReferenceDirection as ln, BoardAwarenessItemPreview as lo, SpaceFsCompleteUploadInput as lr, serializeProjection as ls, CreateInvitationInput as lt, resolveVoiceInputWebsocketUrl as m, AppDomainRecord as ma, BoardHistoryInput as mc, UserActivityRankings as mi, RtcIceServer as ml, ReferenceResourceType as mn, SessionFileRecord as mo, SpaceFsDeleteNodeInput as mr, NativeIngest as ms, CreateSpacePromptResponse as mt, CohubContext as n, RealtimeRoomEvent as na, CreateSpaceCompletionInput as nc, SpaceTurnAuthorFilter as ni, DisplayList as nl, PublicUserPageResponse as nn, SpaceFsCopyOptions as no, SpaceConfig as nr, ProjectionTarget as ns, CheckpointDiffPatchKind as nt, getCohubContext as o, RealtimeServerEvent as oa, Usage as oc, SpaceUsageResponse as oi, DisplayTreeParams as ol, ReferenceAggregateGroup as on, SpaceFsCopyStats as oo, SpaceCreateResponse as or, isProjectionPendingGeneration as os, CheckpointDiffSummary as ot, resolveExecutionToken as p, AppDomainListResponse as pa, BoardCreateInput as pc, UserActivityRange as pi, AppRtcQuality as pl, ReferenceRecord as pn, SessionFileChangeKind as po, SpaceFsCreateUploadResponse as pr, NATIVE_SYNC_SOURCE as ps, CreateSpacePromptInput as pt, BillingRedemptionResult as q, isDesktopCallMethod as qa, AppAuthorizationTarget as qc, BoardChangedEvent as qi, SpaceCheckpointDetailResponse as qn, runtimeReadySchema as qo, SpacePresenceSnapshot as qr, harnessArchiveIndexSchema as qs, PaletteOverviewSpaceRelation as qt, CohubEnvironment as r, RealtimeRoomHistory as ra, ModelThinkingLevel as rc, SpaceTurnListItem as ri, DisplaySession as rl, PublicUserProfile as rn, SpaceFsCopyResponse as ro, SpaceConfigInput as rr, ProjectionWarning as rs, CheckpointDiffPatchLine as rt, normalizeBaseUrl as s, RealtimeSessionFork as sa, ContentBlock as sc, SpaceUsageSummary as si, DisplayViewer as sl, ReferenceAggregateGroupBy as sn, SpaceFsCopyStatus as so, SpaceDefaultResponse as sr, projectNativeMessageMeta as ss, CheckpointRecord as st, COHUB_ENVIRONMENTS as t, RealtimeRoomDescriptor as ta, CompletionUsage as tc, SpaceSessionsResponse as ti, DisplayInputEvent as tl, PublicUserAppItem as tn, SpaceFsCopyInput as to, SpaceCommerceProductCreditBenefit as tr, ProjectionRecord as ts, CheckpointDiffFileResponse as tt, resolveApiBaseUrl as u, APP_DOMAIN_PRICE_USD as ua, BoardApplyInput as uc, USER_LEVEL_PERMISSIONS as ui, AppRtcDelivery as ul, ReferenceKind as un, BoardAwarenessStateUpdate as uo, SpaceFsCompleteUploadResponse as ur, serializeProjectionRecords as us, CreateInvitationResponse as ut, ApiError as v, AppArtifactDescriptor as va, BoardPlaybackSnapshot as vc, UserSessionListItem as vi, DisplayActionError as vl, ReferralStatus as vn, ExecutionStats as vo, SpaceFsFileResponse as vr, NativeRuntimeEvent as vs, CronJobUpdatePatch as vt, BillingCatalog as w, AppContentKind as wa, BOARD_COLOR_TOKENS as wc, ChannelConfig as wi, COHUB_SOURCE_HEADER as wl, SessionMessageResponse as wn, SessionTurnRecord as wo, SpaceFsReadFilesResponse as wr, isNativeClientTurn as ws, GlobalSearchResponse as wt, BillingBalanceActivityKind as x, AppArtifactManifestFile as xa, BoardRecord as xc, UserSessionsResponse as xi, Actor as xl, SendMessageCronJobPayload as xn, TurnMetrics as xo, SpaceFsPreparingFile as xr, NativeTurnProgress as xs, GenerationUsageHourlyStat as xt, BatchUserProfilesResponse as y, AppArtifactDownloadDescriptor as ya, BoardReadInput as yc, UserSessionSourceKey as yi, compileDisplayActions as yl, ResourceLabelsResponse as yn, RequestMetric as yo, SpaceFsListOptions as yr, NativeTurnComplete as ys, CursorPageInfo as yt, BillingPluginStatus as z, DesktopCommandError as za, BoardStyle as zc, getAllowedGenerationModelIds as zi, SpaceActivityAppRanking as zn, RuntimeSessionRecoveryStatus as zo, SpaceListItem as zr, localHarnessSchema as zs, LabelResourceType as zt };
8625
+ export { CheckpointDiffDelivery as $, SpacePublicEndpoints as $a, DisplayCaptureParams as $c, RealtimePatchOperation as $i, SpaceCommerceProduct as $n, NativeProjection as $o, SpaceSandboxConfig as $r, CompletionMessageInput as $s, PromptTemplateCatalogResponse as $t, BillingCreditExpiryGroup as A, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES as Aa, BoardColor as Ac, GenerationModelPolicy as Ai, hasRequestSourceIdentity as Al, SessionTurnSignedUrlsResponse as An, RUNTIME_MAX_FRAME_BYTES as Ao, SpaceFsUploadPlanEntry as Ar, runtimeNativeStopSchema as As, JsonPrimitive as At, BillingProductBillingInterval as B, DesktopCommandRecord as Ba, BoardStyle as Bc, normalizeGenerationPolicy as Bi, SpaceActivityContributor as Bn, RuntimeSessionRecoveryStatus as Bo, SpaceListOptions as Br, localHarnessSchema as Bs, LabelScopeType as Bt, BillingBalanceActivityStatus as C, AppBoardAsset as Ca, BoardSnapshot as Cc, scopeListHasPermission as Ci, ActorKind as Cl, SessionListFork as Cn, MessageToolCallsFile as Co, SpaceFsReadFilesInput as Cr, RuntimeNativeStop as Cs, GlobalSearchChatHit as Ct, BillingCheckoutConfirmation as D, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS as Da, BoardAnimation as Dc, ChannelRuntimeState as Di, REQUEST_SOURCE_VIA_MAX_LENGTH as Dl, SessionRecord as Dn, StoredIntermediateMessage as Do, SpaceFsUploadDestination as Dr, nativeRuntimeEventSchema as Ds, GlobalSearchViewerRelation as Dt, BillingCheckoutActionState as E, DESKTOP_COMMAND_ACCEPT_TIMEOUT_MS as Ea, BOARD_ITEM_TYPES as Ec, ChannelHealthReasonCode as Ei, COHUB_SOURCE_HEADER_NAMES as El, SessionMessagesResponse as En, SpaceTurnsResponse$1 as Eo, SpaceFsTreeResponse as Er, nativeIngestTurnSchema as Es, GlobalSearchType as Et, BillingDiscountOfferRef as F, DesktopAppTarget as Fa, BoardKeyframe as Fc, decodeGenerationPolicy as Fi, normalizeRequestSource as Fl, SkillCatalogResponse as Fn, RuntimeContext as Fo, SpaceInvitation as Fr, LocalHarnessSpec as Fs, LabelItemsResponse as Ft, BillingProductPromotion as G, DesktopTarget as Ga, AppAuthorizationGrant as Gc, AppVersionPublishedEvent as Gi, SpaceBootstrapStatus as Gn, RuntimeTurnUserMessage as Go, SpacePendingDiffFileResponse as Gr, RuntimeArchivePage as Gs, PaletteOverviewResponse as Gt, BillingProductDisplay as H, DesktopFileTarget as Ha, BoardTrackSchema as Hc, GenerationContentBlock as Hi, SpaceBootstrapMeta as Hn, RuntimeStopConfirmation as Ho, SpaceMember as Hr, HarnessArchive as Hs, MeResponse as Ht, BillingDiscountPricing as I, DesktopCall as Ia, BoardMarker as Ic, encodeGenerationPolicy as Ii, parseRequestSourceFromHeaders as Il, SkillCatalogSource as In, RuntimeContextMessage as Io, SpaceInvitationListResponse as Ir, assertHarnessAccess as Is, LabelItemsSessionFork as It, BillingResponsePayload as J, isTerminalDesktopCommandStatus as Ja, AppAuthorizationTarget as Jc, BoardPlaybackChangedEvent as Ji, SpaceCommerceBenefit as Jn, runtimeReadySchema as Jo, SpacePresenceUser as Jr, harnessArchiveIndexSchema as Js, PatchResourceLabelsInput as Jt, BillingPromotionCodePreview as K, defaultDesktopCommandTimeoutMs as Ka, AppAuthorizationRequest as Kc, BoardAwarenessUpdatedEvent as Ki, SpaceChannelBindingInput as Kn, runtimeCommandSchema as Ko, SpacePendingDiffSummary as Kr, RuntimeArchiveSegment as Ks, PaletteOverviewSpace as Kt, BillingHistoryPagination as L, DesktopCommand as La, BoardPatch as Lc, filterGenerationDeclarationsByPolicy as Li, readRequestSourceFromEnv as Ll, SpaceAccess as Ln, RuntimeExecutionEvent as Lo, SpaceInvitationLocation as Lr, harnessLabel as Ls, LabelListItem as Lt, BillingCreditStatus as M, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS as Ma, BoardDiagnostic as Mc, GenerationPolicy as Mi, isRequestSourceEmpty as Ml, SessionTurnWindowResponse as Mn, RUNTIME_RECOVERY_BATCH_SIZE as Mo, SpaceFsUploadProgress as Mr, LOCAL_HARNESSES as Ms, LabelAssignmentListItem as Mt, BillingCreditUnit as N, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS as Na, BoardDocument as Nc, GenerationPolicyError as Ni, isRequestSourceUuid as Nl, SessionTurnsPaginatedResponse as Nn, RuntimeCapabilities as No, SpaceFsUploadResponse as Nr, LOCAL_HARNESS_SPECS as Ns, LabelAssignmentPageInfo as Nt, BillingCheckoutResult as O, DESKTOP_COMMAND_MAX_TIMEOUT_MS as Oa, BoardAnimationHeader as Oc, DiscordChannelConfig as Oi, RequestSource as Ol, SessionTurnIndexResponse as On, StoredToolCall as Oo, SpaceFsUploadEntry as Or, nativeTurnCompleteSchema as Os, InvitationDetail as Ot, BillingDiscountOffer as P, DESKTOP_COMMAND_VERSION as Pa, BoardItem as Pc, assertGenerationRequestAllowedByPolicy as Pi, mergeRequestSourceIntoMeta as Pl, SkillCatalogEntry as Pn, RuntimeCommand as Po, SpaceFsWriteFileInput as Pr, LocalHarness as Ps, LabelAssignmentRecord as Pt, Channel as Q, NavigationLaunch as Qa, DisplayCapture as Qc, RealtimeAppVersionRecord as Qi, SpaceCommerceOrder as Qn, CanonicalProjectionTurn as Qo, SpaceSandboxAutoDestroyPolicy as Qr, CompletionMessage as Qs, PromptTemplateCatalogEntry as Qt, BillingPaymentStatus as R, DesktopCommandDispatchedPayload as Ra, BoardPatchSchema as Rc, findGenerationModelPolicy as Ri, requestSourceToHeaders as Rl, SpaceAccessPolicy as Rn, RuntimeMessage as Ro, SpaceListFilter as Rr, harnessSchema as Rs, LabelRecord as Rt, BillingBalanceActivityList as S, AppBoardArtifactManifest as Sa, BoardRecord as Sc, isUserLevelPermission as Si, Actor as Sl, SessionBindingRecord as Sn, TurnMetrics as So, SpaceFsReadFilesError as Sr, NativeTurnProgress as Ss, GenerationUsageSummary as St, BillingCatalogProduct as T, AppVersionSource as Ta, BOARD_COLOR_TOKENS as Tc, ChannelHealth as Ti, COHUB_SOURCE_HEADER as Tl, SessionMessagesPaginatedResponse as Tn, SessionTurnRecord as To, SpaceFsTreePage as Tr, isNativeClientTurn as Ts, GlobalSearchResult as Tt, BillingProductKind as U, DesktopOpenCommand as Ua, parseBoardItem as Uc, GenerationModelDeclaration as Ui, SpaceBootstrapSource as Un, RuntimeTraceContext as Uo, SpaceMeta as Ur, HarnessArchiveIndex as Us, ModelCatalogEntry as Ut, BillingProductCreditBenefit as V, DesktopCommandStatus as Va, BoardTrack as Vc, parseGenerationPolicyFromEnv as Vi, SpaceActivityResponse as Vn, RuntimeStatus as Vo, SpaceListPage as Vr, resolveHarness as Vs, LabelSource as Vt, BillingProductPricing as W, DesktopSurface as Wa, BillingPayload as Wc, GenerationResult as Wi, SpaceBootstrapStage as Wn, RuntimeTurnInput as Wo, SpaceModListItem as Wr, RUNTIME_ARCHIVE_SEGMENT_BYTES as Ws, PERMISSIONS as Wt, BillingSubscriptionHistoryStatus as X, resolveOpenSurface as Xa, DISPLAY_ELEMENT_REF_PATTERN as Xc, LabelAssignmentsUpdatedEvent as Xi, SpaceCommerceCreditsBenefit as Xn, selectRuntimeContextMessages as Xo, SpaceRecord as Xr, CompletionAssistantMessage as Xs, Permission as Xt, BillingSubscriptionHistoryList as Y, parseDesktopCommand as Ya, SearchTextRange as Yc, ChannelEnvelope as Yi, SpaceCommerceBuyerProfile as Yn, contextToPiMessages as Yo, SpacePublicProfile as Yr, validateArchiveBoundary as Ys, PatchResourceLabelsResponse as Yt, BillingSubscriptionSummary as Z, NavigationCall as Za, DISPLAY_SYSTEM_ACTIONS as Zc, RealtimeAppRecord as Zi, SpaceCommerceFeatureBenefit as Zn, CanonicalProjectionMessage as Zo, SpaceRole as Zr, CompletionImageInput as Zs, PromptAccessMode as Zt, AcceptInvitationResponse as _, normalizeAppDomainHostname as _a, BoardManifest as _c, UserRulesResponse as _i, DISPLAY_ACTION_TYPES as _l, ReferralReward as _n, SessionForkRecord as _o, SpaceFsFileKind as _r, NativeIngestTurn as _s, CronJobRecord as _t, CohubRuntimeKind as a, RealtimeRoomMember as aa, SpaceCompletionResult as ac, SpaceUsageHourlyStat as ai, DisplaySystemAction as al, PublicUserWorkItem as an, SpaceFsCopyResult as ao, SpaceConfigUpdateResponse as ar, fingerprintProjectionTurns as as, CheckpointDiffStatus as at, BillingBalanceActivity as b, AppArtifactManifest as ba, BoardReadInput as bc, UserSessionSpaceSummary as bi, compileDisplayActions as bl, SandboxSpecId as bn, RequestMetric as bo, SpaceFsMoveInput as br, NativeTurnComplete as bs, GenerationUsageBlock as bt, normalizeVoiceInputWebsocketUrl as c, SessionCreatedEvent as ca, ContentBlock as cc, TaskRunDetailResponse as ci, DisplayViewer as cl, ReferenceAggregateResponse as cn, SpaceFsCopyStatus as co, SpaceEnvInput as cr, projectNativeMessageMeta as cs, ClaimReferralResponse as ct, resolveCohubEnvironment as d, AppDomainDnsRecord as da, BoardApplyInput as dc, UsageTotals as di, AppRtcDelivery as dl, ReferenceQueryResponse as dn, BoardAwarenessStateUpdate as do, SpaceFsCreateDirectoryInput as dr, serializeProjectionRecords as ds, CreateSpaceInput as dt, RealtimeRoom as ea, CompletionMessageRole as ec, SpaceSandboxProvider as ei, DisplayElement as el, PublicReferral as en, SpaceFsChangedPayload as eo, SpaceCommerceProductBenefitBinding as er, ProjectionCursor as es, CheckpointDiffFile as et, resolveExecutionAppId as f, AppDomainErrorCode as fa, BoardApplyResult as fc, UserActivityQuery as fi, AppRtcMediaKind as fl, ReferenceQueryableType as fn, BoardAwarenessUpdate as fo, SpaceFsCreateUploadInput as fr, trimProjectionTurnsToCompaction as fs, CreateSpaceModInput as ft, resolveWebsocketUrl as g, AppDomainStatus as ga, BoardHistoryPage as gc, UserProfile as gi, RtcIceServers as gl, ReferralListItem as gn, SessionFilesResponse as go, SpaceFsEntry as gr, NativeIngestResult as gs, CronJobPayload as gt, resolveWebBaseUrl as h, AppDomainRemovedReason as ha, BoardHistoryInput as hc, UserActivityResponse as hi, RtcIceServer as hl, ReferralDashboard as hn, SessionFileRecord as ho, SpaceFsEncoding as hr, NativeIngest as hs, CreateSpaceSessionInput as ht, CohubExecutionContext as i, RealtimeRoomHistoryEvent as ia, ModelThinkingLevel as ic, SpaceTurnsResponse as ii, DisplaySession as il, PublicUserSpaceItem as in, SpaceFsCopyResponse as io, SpaceConfigResponse as ir, ProjectionWarning as is, CheckpointDiffStats as it, BillingCreditGrantStatus as j, DESKTOP_COMMAND_PENDING_TTL_SECONDS as ja, BoardDelta as jc, GenerationParameterConstraint as ji, isRequestSourceClientId as jl, SessionTurnStreamSnapshotResponse as jn, RUNTIME_PROTOCOL_VERSION as jo, SpaceFsUploadPlanEntryInput as jr, HarnessKind as js, JsonValue as jt, BillingConversionIntent as k, DESKTOP_COMMAND_OPEN_TIMEOUT_MS as ka, BoardAnimationSchema as kc, FeishuChannelConfig as ki, RequestSourceVia as kl, SessionTurnResponse as kn, TurnIntermediateMessagesFile as ko, SpaceFsUploadError as kr, nativeTurnProgressSchema as ks, JsonObject as kt, normalizeWebsocketUrl as l, SessionTurnPatchEvent as la, TaskRunBoard as lc, TaskRunRecord as li, DisplayVirtualStart as ll, ReferenceDirection as ln, BoardAwarenessGesture as lo, SpaceFsCompleteUploadInput as lr, projectNativeSession as ls, CreateInvitationInput as lt, resolveVoiceInputWebsocketUrl as m, AppDomainRecord as ma, BoardCreateInput as mc, UserActivityRankings as mi, AppRtcQuality as ml, ReferenceResourceType as mn, SessionFileChangeKind as mo, SpaceFsDeleteNodeInput as mr, NATIVE_SYNC_SOURCE as ms, CreateSpacePromptResponse as mt, CohubContext as n, RealtimeRoomEvent as na, CompletionUsage as nc, SpaceTurnAuthorFilter as ni, DisplayInputEvent as nl, PublicUserPageResponse as nn, SpaceFsCopyInput as no, SpaceConfig as nr, ProjectionRecord as ns, CheckpointDiffPatchKind as nt, getCohubContext as o, RealtimeServerEvent as oa, SpaceCompletionStreamEvent as oc, SpaceUsageResponse as oi, DisplayTree as ol, ReferenceAggregateGroup as on, SpaceFsCopySource as oo, SpaceCreateResponse as or, isProjectionCompaction as os, CheckpointDiffSummary as ot, resolveExecutionToken as p, AppDomainListResponse as pa, BoardChangeSummary as pc, UserActivityRange as pi, AppRtcPublication as pl, ReferenceRecord as pn, MessageRecord as po, SpaceFsCreateUploadResponse as pr, NATIVE_INGEST_MAX_TURNS as ps, CreateSpacePromptInput as pt, BillingRedemptionResult as q, isDesktopCallMethod as qa, AppAuthorizationResult as qc, BoardChangedEvent as qi, SpaceCheckpointDetailResponse as qn, runtimeEventSchema as qo, SpacePresenceSnapshot as qr, RuntimeArchiveUpload as qs, PaletteOverviewSpaceRelation as qt, CohubEnvironment as r, RealtimeRoomHistory as ra, CreateSpaceCompletionInput as rc, SpaceTurnListItem as ri, DisplayList as rl, PublicUserProfile as rn, SpaceFsCopyOptions as ro, SpaceConfigInput as rr, ProjectionTarget as rs, CheckpointDiffPatchLine as rt, normalizeBaseUrl as s, RealtimeSessionFork as sa, Usage as sc, SpaceUsageSummary as si, DisplayTreeParams as sl, ReferenceAggregateGroupBy as sn, SpaceFsCopyStats as so, SpaceDefaultResponse as sr, isProjectionPendingGeneration as ss, CheckpointRecord as st, COHUB_ENVIRONMENTS as t, RealtimeRoomDescriptor as ta, CompletionThinkingLevel as tc, SpaceSessionsResponse as ti, DisplayInfo as tl, PublicUserAppItem as tn, SpaceFsCopyError as to, SpaceCommerceProductCreditBenefit as tr, ProjectionInput as ts, CheckpointDiffFileResponse as tt, resolveApiBaseUrl as u, APP_DOMAIN_PRICE_USD as ua, parseBoardDocument as uc, USER_LEVEL_PERMISSIONS as ui, normalizeDisplayPoint as ul, ReferenceKind as un, BoardAwarenessItemPreview as uo, SpaceFsCompleteUploadResponse as ur, serializeProjection as us, CreateInvitationResponse as ut, ApiError as v, AppArtifactDescriptor as va, BoardPlaybackCommand as vc, UserSessionListItem as vi, DisplayAction as vl, ReferralStatus as vn, SessionTurnSegmentRecord as vo, SpaceFsFileResponse as vr, NativeKnownResult as vs, CronJobUpdatePatch as vt, BillingCatalog as w, AppContentKind as wa, BoardTransactionRecord as wc, ChannelConfig as wi, ActorModel as wl, SessionMessageResponse as wn, SessionTurnIndexItem as wo, SpaceFsReadFilesResponse as wr, SETTLED_TURN_STATUSES as ws, GlobalSearchResponse as wt, BillingBalanceActivityKind as x, AppArtifactManifestFile as xa, BoardReadResult as xc, UserSessionsResponse as xi, SandboxSetupInfo as xl, SendMessageCronJobPayload as xn, SessionStats as xo, SpaceFsPreparingFile as xr, NativeTurnMessage as xs, GenerationUsageHourlyStat as xt, BatchUserProfilesResponse as y, AppArtifactDownloadDescriptor as ya, BoardPlaybackSnapshot as yc, UserSessionSourceKey as yi, DisplayActionError as yl, ResourceLabelsResponse as yn, ExecutionStats as yo, SpaceFsListOptions as yr, NativeRuntimeEvent as ys, CursorPageInfo as yt, BillingPluginStatus as z, DesktopCommandError as za, BoardSettings as zc, getAllowedGenerationModelIds as zi, resolveRequestSourceChannel as zl, SpaceActivityAppRanking as zn, RuntimePendingExecution as zo, SpaceListItem as zr, isLocalHarness as zs, LabelResourceType as zt };
@@ -88,8 +88,8 @@ const readProcessEnv = () => {
88
88
  const readRuntimeEnv = () => readProcessEnv()?.ENV;
89
89
  /** Existing scoped identity injected into Sandbox command processes. */
90
90
  const resolveExecutionToken = () => readProcessEnv()?.COHUB_EXECUTION_TOKEN?.trim() || null;
91
- function decodeExecutionPayload() {
92
- const encoded = resolveExecutionToken()?.split(".")[1];
91
+ function decodeJwtPayload(token) {
92
+ const encoded = token?.split(".")[1];
93
93
  if (!encoded) return null;
94
94
  try {
95
95
  const base64 = encoded.replaceAll("-", "+").replaceAll("_", "/").padEnd(Math.ceil(encoded.length / 4) * 4, "=");
@@ -99,6 +99,7 @@ function decodeExecutionPayload() {
99
99
  return null;
100
100
  }
101
101
  }
102
+ const decodeExecutionPayload = () => decodeJwtPayload(resolveExecutionToken());
102
103
  const readString = (env, key) => env?.[key]?.trim() || null;
103
104
  const readPayloadString = (payload, key) => typeof payload?.[key] === "string" && payload[key] ? payload[key] : null;
104
105
  const KNOWN_PERMISSIONS = new Set(PERMISSIONS);
@@ -173,4 +174,4 @@ const resolveVoiceInputWebsocketUrl = (options = {}) => {
173
174
  return COHUB_ENVIRONMENTS[resolveCohubEnvironment(options.env)].voiceInputWebsocketUrl;
174
175
  };
175
176
  //#endregion
176
- export { normalizeWebsocketUrl as a, resolveExecutionAppId as c, resolveWebBaseUrl as d, resolveWebsocketUrl as f, scopeListHasPermission as g, isUserLevelPermission as h, normalizeVoiceInputWebsocketUrl as i, resolveExecutionToken as l, USER_LEVEL_PERMISSIONS as m, getCohubContext as n, resolveApiBaseUrl as o, PERMISSIONS as p, normalizeBaseUrl as r, resolveCohubEnvironment as s, COHUB_ENVIRONMENTS as t, resolveVoiceInputWebsocketUrl as u };
177
+ export { scopeListHasPermission as _, normalizeVoiceInputWebsocketUrl as a, resolveCohubEnvironment as c, resolveVoiceInputWebsocketUrl as d, resolveWebBaseUrl as f, isUserLevelPermission as g, USER_LEVEL_PERMISSIONS as h, normalizeBaseUrl as i, resolveExecutionAppId as l, PERMISSIONS as m, decodeJwtPayload as n, normalizeWebsocketUrl as o, resolveWebsocketUrl as p, getCohubContext as r, resolveApiBaseUrl as s, COHUB_ENVIRONMENTS as t, resolveExecutionToken as u };