@neta-art/cohub 5.7.0 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +18 -5
  2. package/dist/board/core/palette.d.ts +3 -2
  3. package/dist/board/core/shape-types.d.ts +3 -1
  4. package/dist/board/core/shape-types.js +3 -7
  5. package/dist/board/core/tool-styles.d.ts +2 -1
  6. package/dist/board/image-key.js +3 -5
  7. package/dist/board/index.d.ts +9 -4
  8. package/dist/board/index.js +7 -3
  9. package/dist/board/media-playback.d.ts +22 -0
  10. package/dist/board/media-playback.js +67 -0
  11. package/dist/board/media.d.ts +7 -0
  12. package/dist/board/media.js +70 -0
  13. package/dist/board/nodes.d.ts +113 -0
  14. package/dist/board/nodes.js +154 -0
  15. package/dist/board/render/index.d.ts +3 -1
  16. package/dist/board/render/index.js +4 -2
  17. package/dist/board/render/media-interaction.d.ts +19 -0
  18. package/dist/board/render/media-interaction.js +26 -0
  19. package/dist/board/render/renderers/audio-card-renderer.js +1 -1
  20. package/dist/board/render/renderers/board-renderer-registry.js +2 -2
  21. package/dist/board/render/renderers/draw-card-renderer.js +1 -1
  22. package/dist/board/render/renderers/file-card-renderer.js +1 -1
  23. package/dist/board/render/renderers/frame-card-renderer.js +1 -1
  24. package/dist/board/render/renderers/geo-card-renderer.js +1 -1
  25. package/dist/board/render/renderers/image-card-renderer.js +1 -1
  26. package/dist/board/render/renderers/task-card-renderer.js +16 -13
  27. package/dist/board/render/renderers/text-card-renderer.js +1 -1
  28. package/dist/board/render/renderers/unknown-card-renderer.js +1 -1
  29. package/dist/board/render/renderers/video-card-renderer.js +1 -1
  30. package/dist/board/render/video-thumbnail.d.ts +16 -0
  31. package/dist/board/render/video-thumbnail.js +86 -0
  32. package/dist/board/task.d.ts +10 -5
  33. package/dist/board/task.js +159 -103
  34. package/dist/chunks/environment.d.ts +6 -6
  35. package/dist/chunks/environment.js +6 -6
  36. package/dist/chunks/http.d.ts +71 -5
  37. package/dist/chunks/http.js +1535 -167
  38. package/dist/chunks/transport.js +8 -1
  39. package/dist/chunks/websocket.d.ts +138 -2
  40. package/dist/http.d.ts +3 -3
  41. package/dist/index.d.ts +245 -4
  42. package/dist/index.js +438 -788
  43. package/dist/protocol/dist/board-document.d.ts +155 -48
  44. package/dist/protocol/dist/board-document.js +40 -19
  45. package/dist/protocol/dist/board-node.d.ts +18 -0
  46. package/dist/protocol/dist/board-node.js +239 -0
  47. package/dist/protocol/dist/board-url.d.ts +12 -0
  48. package/dist/protocol/dist/board-url.js +83 -0
  49. package/dist/protocol/dist/board.d.ts +5 -0
  50. package/dist/protocol/dist/index.d.ts +2 -1
  51. package/dist/protocol/dist/index.js +2 -1
  52. package/dist/protocol/dist/provenance.js +1 -0
  53. package/docs/work-runtime-guide.md +7 -7
  54. package/package.json +1 -1
@@ -1,3 +1,5 @@
1
+ import { normalizeBoardRemoteUrl } from "../protocol/dist/board-url.js";
2
+ import "../protocol/dist/board-document.js";
1
3
  //#region src/board/task.ts
2
4
  const EXCERPT_LIMIT = 240;
3
5
  function record(value) {
@@ -9,85 +11,12 @@ function cleanExcerpt(value, limit = EXCERPT_LIMIT) {
9
11
  if (!clean) return void 0;
10
12
  return clean.length > limit ? `${clean.slice(0, limit - 3).trimEnd()}...` : clean;
11
13
  }
12
- function parseIpv4(host) {
13
- const parts = host.split(".").map(Number);
14
- return parts.length === 4 && parts.every((part) => Number.isInteger(part) && part >= 0 && part <= 255) ? parts : null;
15
- }
16
- function isBlockedIpv4(host) {
17
- const parts = parseIpv4(host);
18
- if (!parts) return false;
19
- const [first, second, third] = parts;
20
- if (first === 0 || first === 10 || first === 127) return true;
21
- if (first === 100 && second >= 64 && second <= 127) return true;
22
- if (first === 169 && second === 254) return true;
23
- if (first === 172 && second >= 16 && second <= 31) return true;
24
- if (first === 192 && second === 168) return true;
25
- if (first === 192 && second === 0 && (third === 0 || third === 2)) return true;
26
- if (first === 192 && second === 88 && third === 99) return true;
27
- if (first === 198 && (second === 18 || second === 19)) return true;
28
- if (first === 198 && second === 51 && third === 100) return true;
29
- if (first === 203 && second === 0 && third === 113) return true;
30
- return first >= 224;
31
- }
32
- function expandIpv6(host) {
33
- const [head, tail, extra] = host.toLowerCase().split("::");
34
- if (extra !== void 0) return null;
35
- const headParts = head ? head.split(":").filter(Boolean) : [];
36
- const tailParts = tail ? tail.split(":").filter(Boolean) : [];
37
- const missing = 8 - headParts.length - tailParts.length;
38
- if (missing < 0 || tail === void 0 && missing !== 0) return null;
39
- const parts = [
40
- ...headParts,
41
- ...Array.from({ length: missing }, () => "0"),
42
- ...tailParts
43
- ];
44
- if (parts.length !== 8 || parts.some((part) => !/^[0-9a-f]{1,4}$/.test(part))) return null;
45
- return parts.map((part) => part.padStart(4, "0"));
46
- }
47
- function isBlockedIpv6(host) {
48
- const parts = expandIpv6(host);
49
- if (!parts) return true;
50
- if (parts.every((part) => part === "0000")) return true;
51
- if (parts.slice(0, 7).every((part) => part === "0000") && parts[7] === "0001") return true;
52
- if (parts.slice(0, 5).every((part) => part === "0000") && parts[5] === "ffff") {
53
- const high = Number.parseInt(parts[6] ?? "0", 16);
54
- const low = Number.parseInt(parts[7] ?? "0", 16);
55
- return isBlockedIpv4(`${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`);
56
- }
57
- if (parts.slice(0, 6).every((part) => part === "0000")) return true;
58
- const first = Number.parseInt(parts[0] ?? "0", 16);
59
- if ((first & 65024) === 64512) return true;
60
- if ((first & 65472) === 65152 || (first & 65472) === 65216) return true;
61
- if ((first & 65280) === 65280) return true;
62
- return parts[0] === "2001" && parts[1] === "0db8";
63
- }
64
- function isBlockedTaskOutputHost(hostname) {
65
- const host = hostname.toLowerCase().replace(/^\[|\]$/g, "").replace(/\.$/, "");
66
- if (host === "localhost" || host.endsWith(".localhost") || host.endsWith(".local") || host.endsWith(".internal")) return true;
67
- if (parseIpv4(host)) return isBlockedIpv4(host);
68
- return host.includes(":") && isBlockedIpv6(host);
69
- }
70
- /**
71
- * Normalize a persistable remote media URL and reject credentialed or visibly
72
- * non-public hosts. Server-side fetchers must still validate resolved DNS addresses.
73
- */
74
- function normalizeBoardTaskOutputUrl(value) {
75
- if (typeof value !== "string") return void 0;
76
- try {
77
- const url = new URL(value.trim());
78
- if (url.protocol !== "https:" && url.protocol !== "http:") return void 0;
79
- if (url.username || url.password || isBlockedTaskOutputHost(url.hostname)) return void 0;
80
- return url.toString();
81
- } catch {
82
- return;
83
- }
84
- }
85
14
  function blockText(block) {
86
15
  return cleanExcerpt(block.text ?? block.content ?? block.value);
87
16
  }
88
17
  function blockUrl(block) {
89
18
  const source = record(block.source);
90
- return normalizeBoardTaskOutputUrl(source?.url ?? source?.src ?? block.url ?? block.src);
19
+ return normalizeBoardRemoteUrl(source?.url ?? source?.src ?? block.url ?? block.src);
91
20
  }
92
21
  function blockMimeType(block) {
93
22
  const source = record(block.source);
@@ -122,37 +51,163 @@ function generationPrompt(run) {
122
51
  if (text) return text;
123
52
  }
124
53
  }
125
- function primaryOutput(blocks) {
126
- for (const block of blocks) {
127
- if (block.type !== "image" && block.type !== "video") continue;
128
- const url = blockUrl(block);
129
- if (!url) continue;
130
- const mimeType = blockMimeType(block);
131
- return {
132
- type: block.type,
133
- url,
134
- ...mimeType ? { mimeType } : {},
135
- ...blockNaturalSize(block)
136
- };
54
+ function blockMeta(block) {
55
+ return record(block.meta);
56
+ }
57
+ function blockIdentity(block) {
58
+ const meta = blockMeta(block);
59
+ const value = meta?.id ?? meta?.clip_id ?? meta?.clipId ?? block.id ?? block.clip_id ?? block.clipId;
60
+ if (typeof value !== "string" && typeof value !== "number") return void 0;
61
+ return cleanExcerpt(String(value), 220);
62
+ }
63
+ function blockTitle(block) {
64
+ return cleanExcerpt(blockMeta(block)?.title ?? block.title ?? block.name, 240);
65
+ }
66
+ function blockDurationMs(block) {
67
+ const source = record(block.source);
68
+ const meta = blockMeta(block);
69
+ const milliseconds = positiveNumber(source?.durationMs ?? meta?.durationMs ?? block.durationMs);
70
+ if (milliseconds) return Math.round(milliseconds);
71
+ const seconds = positiveNumber(source?.duration ?? meta?.duration ?? block.duration);
72
+ return seconds ? Math.round(seconds * 1e3) : void 0;
73
+ }
74
+ function blockPreviewUrl(block) {
75
+ const source = record(block.source);
76
+ return normalizeBoardRemoteUrl(source?.poster ?? source?.thumbnail ?? source?.previewUrl ?? block.poster ?? block.thumbnail ?? block.previewUrl);
77
+ }
78
+ function artifactId(base, used, suffix) {
79
+ const stem = cleanExcerpt(base, 220) ?? "output";
80
+ let candidate = suffix ? `${stem}-${suffix}` : stem;
81
+ let sequence = 2;
82
+ while (used.has(candidate)) {
83
+ candidate = `${stem}-${suffix ? `${suffix}-` : ""}${sequence}`;
84
+ sequence += 1;
137
85
  }
138
- for (const block of blocks) {
139
- if (block.type === "audio") {
140
- const url = blockUrl(block);
86
+ used.add(candidate);
87
+ return candidate;
88
+ }
89
+ /**
90
+ * Group provider blocks into user-facing works. A cover/poster sharing a stable
91
+ * provider id with playable media belongs to that work instead of becoming a
92
+ * competing image result.
93
+ */
94
+ function taskArtifacts(blocks) {
95
+ const groups = /* @__PURE__ */ new Map();
96
+ blocks.forEach((block, index) => {
97
+ const key = blockIdentity(block) ?? `output-${index + 1}`;
98
+ const group = groups.get(key);
99
+ if (group) group.push(block);
100
+ else groups.set(key, [block]);
101
+ });
102
+ const artifacts = [];
103
+ const usedIds = /* @__PURE__ */ new Set();
104
+ for (const [groupId, blocksInGroup] of groups) {
105
+ const images = blocksInGroup.filter((block) => block.type === "image").map((block) => ({
106
+ block,
107
+ url: blockUrl(block)
108
+ })).filter((entry) => Boolean(entry.url));
109
+ const media = blocksInGroup.filter((block) => block.type === "video" || block.type === "audio").map((block) => ({
110
+ block,
111
+ url: blockUrl(block)
112
+ })).filter((entry) => Boolean(entry.url));
113
+ const pairedPreview = images[0];
114
+ media.forEach(({ block, url }, mediaIndex) => {
115
+ const type = block.type;
116
+ const mimeType = blockMimeType(block);
117
+ const title = blockTitle(block);
118
+ const durationMs = blockDurationMs(block);
119
+ const previewUrl = blockPreviewUrl(block) ?? pairedPreview?.url;
120
+ const id = artifactId(groupId, usedIds, media.length > 1 ? `${type}-${mediaIndex + 1}` : void 0);
121
+ if (type === "video") {
122
+ artifacts.push({
123
+ id,
124
+ type,
125
+ url,
126
+ ...title ? { title } : {},
127
+ ...previewUrl ? { previewUrl } : {},
128
+ ...mimeType ? { mimeType } : {},
129
+ ...durationMs ? { durationMs } : {},
130
+ ...blockNaturalSize(block)
131
+ });
132
+ return;
133
+ }
134
+ artifacts.push({
135
+ id,
136
+ type,
137
+ url,
138
+ ...title ? { title } : {},
139
+ ...previewUrl ? { previewUrl } : {},
140
+ ...mimeType ? { mimeType } : {},
141
+ ...durationMs ? { durationMs } : {}
142
+ });
143
+ });
144
+ const firstUnpairedImage = media.length > 0 ? 1 : 0;
145
+ images.slice(firstUnpairedImage).forEach(({ block, url }, imageIndex) => {
141
146
  const mimeType = blockMimeType(block);
142
- return {
143
- type: "audio",
144
- ...url ? { url } : {},
145
- ...mimeType ? { mimeType } : {}
146
- };
147
- }
148
- if (block.type === "text") {
147
+ const title = blockTitle(block);
148
+ artifacts.push({
149
+ id: artifactId(groupId, usedIds, images.length - firstUnpairedImage > 1 ? `image-${imageIndex + 1}` : void 0),
150
+ type: "image",
151
+ url,
152
+ ...title ? { title } : {},
153
+ ...mimeType ? { mimeType } : {},
154
+ ...blockNaturalSize(block)
155
+ });
156
+ });
157
+ blocksInGroup.filter((block) => block.type === "text").forEach((block, textIndex, texts) => {
149
158
  const textExcerpt = blockText(block);
150
- if (textExcerpt) return {
159
+ if (!textExcerpt) return;
160
+ const title = blockTitle(block);
161
+ artifacts.push({
162
+ id: artifactId(groupId, usedIds, texts.length > 1 ? `text-${textIndex + 1}` : void 0),
151
163
  type: "text",
164
+ ...title ? { title } : {},
152
165
  textExcerpt
153
- };
154
- }
166
+ });
167
+ });
155
168
  }
169
+ return artifacts;
170
+ }
171
+ function artifactScore(artifact) {
172
+ const kind = {
173
+ text: 1,
174
+ image: 2,
175
+ audio: 3,
176
+ video: 4
177
+ }[artifact.type];
178
+ if (artifact.type === "text") return [kind, artifact.textExcerpt.length];
179
+ if (artifact.type === "image") return [kind, (artifact.naturalWidth ?? 0) * (artifact.naturalHeight ?? 0)];
180
+ return [
181
+ kind,
182
+ artifact.previewUrl ? 1 : 0,
183
+ artifact.durationMs ? 1 : 0,
184
+ artifact.durationMs ?? 0
185
+ ];
186
+ }
187
+ function compareArtifacts(a, b) {
188
+ const left = artifactScore(a);
189
+ const right = artifactScore(b);
190
+ for (let index = 0; index < Math.max(left.length, right.length); index += 1) {
191
+ const difference = (right[index] ?? 0) - (left[index] ?? 0);
192
+ if (difference !== 0) return difference;
193
+ }
194
+ return 0;
195
+ }
196
+ /** Highest-value artifact first, with provider order as the stable final tie. */
197
+ function rankedTaskArtifacts(artifacts) {
198
+ return artifacts.map((artifact, index) => ({
199
+ artifact,
200
+ index
201
+ })).sort((a, b) => compareArtifacts(a.artifact, b.artifact) || a.index - b.index).map(({ artifact }) => artifact);
202
+ }
203
+ function featuredTaskArtifact(artifacts) {
204
+ let featured;
205
+ for (const artifact of artifacts) if (!featured || compareArtifacts(artifact, featured) < 0) featured = artifact;
206
+ return featured;
207
+ }
208
+ function taskArtifactPreviewUrl(artifact) {
209
+ if (artifact?.type === "image") return artifact.url;
210
+ if (artifact?.type === "video" || artifact?.type === "audio") return artifact.previewUrl;
156
211
  }
157
212
  function taskTypeTitle(taskType) {
158
213
  return taskType.replace(/[._-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase());
@@ -166,17 +221,18 @@ function taskRunToBoardTaskSnapshot(run) {
166
221
  const blocks = run.taskType === "generation" ? generationOutput(run) : [];
167
222
  const promptExcerpt = run.taskType === "generation" ? generationPrompt(run) : cleanExcerpt(data?.command ?? data?.prompt ?? data?.title);
168
223
  const model = typeof data?.model === "string" ? data.model : void 0;
169
- const primary = primaryOutput(blocks);
224
+ const allArtifacts = taskArtifacts(blocks);
225
+ const artifacts = rankedTaskArtifacts(allArtifacts).slice(0, 6);
170
226
  return {
171
227
  taskType: run.taskType,
172
228
  status: run.status,
173
229
  title: promptExcerpt ?? taskTypeTitle(run.taskType),
174
230
  ...model ? { model } : {},
175
231
  ...promptExcerpt ? { promptExcerpt } : {},
176
- outputCount: blocks.length,
177
- ...primary ? { primaryOutput: primary } : {},
232
+ artifactCount: allArtifacts.length,
233
+ artifacts,
178
234
  updatedAt: run.updatedAt
179
235
  };
180
236
  }
181
237
  //#endregion
182
- export { normalizeBoardTaskOutputUrl, taskRunToBoardTaskSnapshot };
238
+ export { featuredTaskArtifact, rankedTaskArtifacts, taskArtifactPreviewUrl, taskArtifacts, taskRunToBoardTaskSnapshot };
@@ -2,14 +2,14 @@
2
2
  type CohubEnvironment = "prod" | "dev";
3
3
  declare const COHUB_ENVIRONMENTS: {
4
4
  readonly prod: {
5
- readonly apiBaseUrl: "https://api.cohub.run";
6
- readonly websocketUrl: "wss://gateway.cohub.run/ws";
7
- readonly voiceInputWebsocketUrl: "wss://gateway.cohub.run/asr/ws";
5
+ readonly apiBaseUrl: "https://api.cohub.live";
6
+ readonly websocketUrl: "wss://gateway.cohub.live/ws";
7
+ readonly voiceInputWebsocketUrl: "wss://gateway.cohub.live/asr/ws";
8
8
  };
9
9
  readonly dev: {
10
- readonly apiBaseUrl: "https://api-dev.cohub.run";
11
- readonly websocketUrl: "wss://gateway-dev.cohub.run/ws";
12
- readonly voiceInputWebsocketUrl: "wss://gateway-dev.cohub.run/asr/ws";
10
+ readonly apiBaseUrl: "https://api-dev.cohub.live";
11
+ readonly websocketUrl: "wss://gateway-dev.cohub.live/ws";
12
+ readonly voiceInputWebsocketUrl: "wss://gateway-dev.cohub.live/asr/ws";
13
13
  };
14
14
  };
15
15
  declare const resolveCohubEnvironment: (env?: CohubEnvironment) => CohubEnvironment;
@@ -1,14 +1,14 @@
1
1
  //#region src/environment.ts
2
2
  const COHUB_ENVIRONMENTS = {
3
3
  prod: {
4
- apiBaseUrl: "https://api.cohub.run",
5
- websocketUrl: "wss://gateway.cohub.run/ws",
6
- voiceInputWebsocketUrl: "wss://gateway.cohub.run/asr/ws"
4
+ apiBaseUrl: "https://api.cohub.live",
5
+ websocketUrl: "wss://gateway.cohub.live/ws",
6
+ voiceInputWebsocketUrl: "wss://gateway.cohub.live/asr/ws"
7
7
  },
8
8
  dev: {
9
- apiBaseUrl: "https://api-dev.cohub.run",
10
- websocketUrl: "wss://gateway-dev.cohub.run/ws",
11
- voiceInputWebsocketUrl: "wss://gateway-dev.cohub.run/asr/ws"
9
+ apiBaseUrl: "https://api-dev.cohub.live",
10
+ websocketUrl: "wss://gateway-dev.cohub.live/ws",
11
+ voiceInputWebsocketUrl: "wss://gateway-dev.cohub.live/asr/ws"
12
12
  }
13
13
  };
14
14
  const readRuntimeEnv = () => {
@@ -1,4 +1,4 @@
1
- import { $ as CreateSpacePromptInput, $n as SpaceFsTreeResponse, Aa as SessionTurnRecord, Ai as WorkContentKind, Ar as SpaceUsageResponse, At as Permission, Ba as SpaceCompletionStreamEvent, Bi as UiCommandError, Br as ChannelHealth, Bt as ReferenceAggregateGroupBy, Ci as BoardAwarenessUpdate, Cn as SpaceCommerceBenefit, Ct as LabelResourceType, Da as SessionForkRecord, Dn as SpaceCommerceOrder, Dt as ModelCatalogEntry, Ea as MessageRecord, Er as SpaceTurnAuthorFilter, Et as MeResponse, Fn as SpaceCreateResponse, Fr as UserRulesResponse, Ft as PublicUserPageResponse, Gt as ReferenceQueryableType, Ha as BillingPayload, Hi as UiCommandStatus, Hn as SpaceFsCreateUploadResponse, Ht as ReferenceDirection, In as SpaceDefaultResponse, J as ClaimReferralResponse, Jn as SpaceFsMoveInput, Jt as ReferralDashboard, K as CheckpointDiffSummary, La as CreateSpaceCompletionInput, Ln as SpaceEnvInput, Mn as SpaceConfigInput, Mr as TaskRunDetailResponse, Nn as SpaceConfigResponse, Nr as TaskRunRecord, Nt as PromptTemplateCatalogResponse, On as SpaceCommerceProduct, Ot as PatchResourceLabelsInput, Pn as SpaceConfigUpdateResponse, Pr as UserProfile, Pt as PublicReferral, Qi as BoardCapabilities, Qn as SpaceFsReadFilesResponse, R as Channel, Ri as UiCommand, Rn as SpaceFsCompleteUploadInput, Rr as UserSessionsResponse, Sa as BoardConnectionRecord, Sn as SpaceCheckpointDetailResponse, Ta as SpacePublicEndpoints, Tr as SpaceSessionsResponse, Ua as ContentBlock, Ut as ReferenceKind, V as CheckpointDiffFileResponse, Va as Usage, Vi as UiCommandRecord, Vn as SpaceFsCreateUploadInput, Vt as ReferenceAggregateResponse, Wt as ReferenceQueryResponse, X as CreateInvitationResponse, Y as CreateInvitationInput, Yn as SpaceFsPreparingFile, Z as CreateSpaceInput, Zi as BoardBootstrap, _a as BoardTransaction, _r as SpacePresenceSnapshot, a as WebsocketClientOptions, an as SessionRecord, at as CursorPageInfo, ba as BoardConnection, br as SpaceRecord, ci as BoardTransactionAppliedEvent$1, cn as SessionTurnSignedUrlsResponse, d as BatchUserProfilesResponse, di as RealtimePatchOperation, dn as SessionTurnsPaginatedResponse, dt as GlobalSearchType, ea as BoardCreateInput, et as CreateSpacePromptResponse, fr as SpaceMember, ft as InvitationDetail, gn as SpaceAccessPolicy, gr as SpacePendingDiffSummary, hr as SpacePendingDiffFileResponse, ia as BoardInspectInput, ii as GenerationModelDeclaration, in as SessionMessagesResponse, it as CronJobUpdatePatch, ja as SpaceTurnsResponse, kn as SpaceCommerceProductBenefitBinding, kt as PatchResourceLabelsResponse, l as AcceptInvitationResponse, ln as SessionTurnStreamSnapshotResponse, lr as SpaceInvitationListResponse, lt as GlobalSearchResponse, mr as SpaceModListItem, nn as SessionMessageResponse, oi as BoardAwarenessUpdatedEvent$1, on as SessionTurnIndexResponse, or as SpaceFsUploadResponse, pa as BoardPlaybackSnapshot, pn as SkillCatalogResponse, q as CheckpointRecord, qa as RequestSource, qn as SpaceFsFileResponse, r as WebsocketClient, ri as GenerationContentBlock, rn as SessionMessagesPaginatedResponse, rt as CronJobRecord, s as WebsocketEventPayload, si as BoardPlaybackChangedEvent$1, sn as SessionTurnResponse, sr as SpaceFsWriteFileInput, tt as CreateSpaceSessionInput, ua as BoardPlaybackCommand, un as SessionTurnWindowResponse, va as BoardValidationResult, vi as SessionTurnPatchEvent, vt as LabelAssignmentRecord, wi as WorkArtifactDescriptor, wn as SpaceCommerceBuyerProfile, xa as BoardConnectionDirection, xr as SpaceRole, xt as LabelListItem, yr as SpacePublicProfile, yt as LabelItemsResponse, za as SpaceCompletionResult, zn as SpaceFsCompleteUploadResponse, zr as ChannelConfig } from "./websocket.js";
1
+ import { $ as CreateInvitationInput, $n as SpaceFsPreparingFile, Ar as SpaceTurnAuthorFilter, At as MeResponse, Ba as BoardConnectionRecord, Bn as SpaceDefaultResponse, Cr as SpacePublicProfile, Ct as LabelItemsResponse, Dn as SpaceCommerceBenefit, Dt as LabelResourceType, Ea as BoardValidationResult, Ei as SessionTurnPatchEvent, En as SpaceCheckpointDetailResponse, G as CheckpointDiffFileResponse, Ga as SessionForkRecord, Gn as SpaceFsCreateUploadInput, Gt as ReferenceAggregateResponse, H as Channel, Hn as SpaceFsCompleteUploadInput, Hr as UserProfile, In as SpaceConfigInput, Ir as TaskRunDetailResponse, Ja as SessionTurnRecord, Ji as UiCommandError, Jr as ChannelHealth, Jt as ReferenceQueryResponse, Ki as UiCommand, Kn as SpaceFsCreateUploadResponse, Kr as UserSessionsResponse, Kt as ReferenceDirection, Ln as SpaceConfigResponse, Lr as TaskRunRecord, Lt as PromptTemplateCatalogResponse, Mi as WorkArtifactDescriptor, Mn as SpaceCommerceProduct, Mt as PatchResourceLabelsInput, Nn as SpaceCommerceProductBenefitBinding, Nt as PatchResourceLabelsResponse, On as SpaceCommerceBuyerProfile, Pr as SpaceUsageResponse, Pt as Permission, Q as ClaimReferralResponse, Qn as SpaceFsMoveInput, Qt as ReferralDashboard, Ra as BoardConnection, Ri as WorkContentKind, Rn as SpaceConfigUpdateResponse, Rr as UserActivityQuery, Rt as PublicReferral, St as LabelAssignmentRecord, Ta as BoardTransaction, Tr as SpaceRole, Tt as LabelListItem, Ua as SpacePublicEndpoints, Un as SpaceFsCompleteUploadResponse, Ur as UserRulesResponse, Vn as SpaceEnvInput, Vr as UserActivityResponse, Wa as MessageRecord, Wt as ReferenceAggregateGroupBy, X as CheckpointDiffSummary, Xi as UiCommandStatus, Ya as SpaceTurnsResponse, Yi as UiCommandRecord, Yt as ReferenceQueryableType, Z as CheckpointRecord, Zn as SpaceFsFileResponse, _n as SkillCatalogResponse, a as WebsocketClientOptions, aa as BoardBootstrap, ao as Usage, at as CreateSpaceSessionInput, bn as SpaceAccessPolicy, br as SpacePendingDiffSummary, ca as BoardCreateInput, cn as SessionMessagesResponse, ct as CronJobUpdatePatch, d as BatchUserProfilesResponse, di as GenerationContentBlock, dn as SessionTurnResponse, do as RequestSource, dr as SpaceFsWriteFileInput, et as CreateInvitationResponse, fa as BoardInspectInput, fi as GenerationModelDeclaration, fn as SessionTurnSignedUrlsResponse, gi as BoardTransactionAppliedEvent$1, gr as SpaceMember, gt as InvitationDetail, hi as BoardPlaybackChangedEvent$1, hn as SessionTurnsPaginatedResponse, ht as GlobalSearchType, io as SpaceCompletionStreamEvent, it as CreateSpacePromptResponse, ji as BoardAwarenessUpdate, jn as SpaceCommerceOrder, jt as ModelCatalogEntry, kr as SpaceSessionsResponse, l as AcceptInvitationResponse, ln as SessionRecord, lt as CursorPageInfo, mi as BoardAwarenessUpdatedEvent$1, mn as SessionTurnWindowResponse, nr as SpaceFsReadFilesResponse, oa as BoardCapabilities, on as SessionMessageResponse, oo as BillingPayload, pn as SessionTurnStreamSnapshotResponse, pr as SpaceInvitationListResponse, pt as GlobalSearchResponse, qr as ChannelConfig, qt as ReferenceKind, r as WebsocketClient, ro as SpaceCompletionResult, rr as SpaceFsTreeResponse, rt as CreateSpacePromptInput, s as WebsocketEventPayload, sn as SessionMessagesPaginatedResponse, so as ContentBlock, st as CronJobRecord, to as CreateSpaceCompletionInput, tt as CreateSpaceInput, un as SessionTurnIndexResponse, ur as SpaceFsUploadResponse, va as BoardPlaybackCommand, vr as SpaceModListItem, wr as SpaceRecord, xa as BoardPlaybackSnapshot, xr as SpacePresenceSnapshot, yi as RealtimePatchOperation, yr as SpacePendingDiffFileResponse, za as BoardConnectionDirection, zn as SpaceCreateResponse, zt as PublicUserPageResponse } from "./websocket.js";
2
2
  import { n as CohubEnvironment } from "./environment.js";
3
3
  import { a as VoiceInputCreateOptions } from "./voice-input.js";
4
4
  //#region ../protocol/dist/model/status.d.ts
@@ -161,6 +161,45 @@ type SpaceStartupResponse = {
161
161
  retryAfterMs?: number;
162
162
  };
163
163
  //#endregion
164
+ //#region ../protocol/dist/public-files.d.ts
165
+ type PublicFileUploadEntryInput = {
166
+ id: string;
167
+ relativePath: string;
168
+ size: number;
169
+ mimeType?: string | null;
170
+ };
171
+ type PublicFileCreateUploadInput = {
172
+ entries: PublicFileUploadEntryInput[];
173
+ overwrite?: boolean;
174
+ };
175
+ type PublicFileUploadPlanEntry = {
176
+ id: string;
177
+ path: string;
178
+ uploadUrl: string;
179
+ publicUrl: string;
180
+ headers?: Record<string, string>;
181
+ };
182
+ type PublicFileCreateUploadResponse = {
183
+ entries: PublicFileUploadPlanEntry[];
184
+ };
185
+ type PublicFileListEntry = {
186
+ path: string;
187
+ name: string;
188
+ kind: "file" | "directory";
189
+ size: number | null;
190
+ updatedAt: string | null;
191
+ publicUrl: string | null;
192
+ };
193
+ type PublicFileListResponse = {
194
+ path: string;
195
+ entries: PublicFileListEntry[];
196
+ nextCursor: string | null;
197
+ };
198
+ type PublicFileUrlResponse = {
199
+ path: string;
200
+ url: string;
201
+ };
202
+ //#endregion
164
203
  //#region src/work-runtime.d.ts
165
204
  type WorkRuntimeContext = {
166
205
  work: {
@@ -293,7 +332,7 @@ declare class WorkRuntimeApi {
293
332
  type WorkRuntimeModeConfig = {
294
333
  /** Explicit mode selection. When omitted, auto-detection is used. */
295
334
  mode?: "bridge" | "broker";
296
- /** Cohub origin for the broker page (e.g. "https://cohub.run"). */
335
+ /** Cohub origin for the broker page (e.g. "https://cohub.live"). */
297
336
  brokerOrigin?: string;
298
337
  /**
299
338
  * The work's public id. Required for broker mode unless the slug triple
@@ -961,12 +1000,38 @@ declare class SpacesApi {
961
1000
  getBySlug(username: string, slug: string, customFetch?: Fetch): Promise<SpaceRecord>;
962
1001
  create(input: CreateSpaceInput, headers?: Record<string, string>): Promise<SpaceCreateResponse>;
963
1002
  }
1003
+ type SpaceFileUrlPurpose = "preview" | "playback";
1004
+ type ResolveSpaceFileUrlOptions = {
1005
+ /** Playback only accepts a streamable URL; previews may fall back to a data URL. */
1006
+ purpose?: SpaceFileUrlPurpose;
1007
+ /** Maximum time to wait while CDN delivery is being prepared. */
1008
+ timeoutMs?: number;
1009
+ signal?: AbortSignal;
1010
+ fetch?: Fetch;
1011
+ };
1012
+ declare class SpacePublicFilesApi {
1013
+ private readonly transport;
1014
+ private readonly spaceId;
1015
+ constructor(transport: HttpTransport, spaceId: string);
1016
+ createUpload(input: PublicFileCreateUploadInput, options?: {
1017
+ signal?: AbortSignal;
1018
+ }): Promise<PublicFileCreateUploadResponse>;
1019
+ list(path?: string, options?: {
1020
+ recursive?: boolean;
1021
+ limit?: number;
1022
+ cursor?: string;
1023
+ fetch?: Fetch;
1024
+ }): Promise<PublicFileListResponse>;
1025
+ url(path: string, customFetch?: Fetch): Promise<PublicFileUrlResponse>;
1026
+ }
964
1027
  declare class SpaceFilesApi {
965
1028
  private readonly transport;
966
1029
  private readonly spaceId;
967
1030
  constructor(transport: HttpTransport, spaceId: string);
968
1031
  list(path?: string, customFetch?: Fetch): Promise<SpaceFsTreeResponse>;
969
- read(path: string, customFetch?: Fetch): Promise<SpaceFsFileResponse | SpaceFsPreparingFile>;
1032
+ read(path: string, customFetch?: Fetch, signal?: AbortSignal): Promise<SpaceFsFileResponse | SpaceFsPreparingFile>;
1033
+ /** Resolve a browser-ready file URL, waiting for CDN delivery when necessary. */
1034
+ resolveUrl(path: string, options?: ResolveSpaceFileUrlOptions): Promise<string | null>;
970
1035
  /** Pending workspace changes vs the space head checkpoint. */
971
1036
  diff(customFetch?: Fetch): Promise<SpacePendingDiffSummary>;
972
1037
  /** Per-file pending workspace diff vs the space head checkpoint. */
@@ -1600,6 +1665,7 @@ declare class SpaceClient {
1600
1665
  private readonly transport;
1601
1666
  private readonly websocketClient;
1602
1667
  readonly files: SpaceFilesApi;
1668
+ readonly publicFiles: SpacePublicFilesApi;
1603
1669
  readonly sessions: SpaceSessionsApi;
1604
1670
  readonly turns: SpaceTurnsApi;
1605
1671
  readonly members: SpaceMembersApi;
@@ -1744,7 +1810,7 @@ declare class UserApi {
1744
1810
  space: SpaceRecord;
1745
1811
  session: SessionRecord;
1746
1812
  }>;
1747
- getUsage(days?: number, customFetch?: Fetch): Promise<SpaceUsageResponse>;
1813
+ getActivity(options?: UserActivityQuery, customFetch?: Fetch): Promise<UserActivityResponse>;
1748
1814
  setAuthToken(token: string): Promise<any>;
1749
1815
  clearAuthToken(): Promise<null>;
1750
1816
  }
@@ -2098,4 +2164,4 @@ declare class CohubHttpClient {
2098
2164
  }
2099
2165
  declare const createHttpClient: (options?: CohubClientOptions) => CohubHttpClient;
2100
2166
  //#endregion
2101
- export { SpaceEventName as $, HttpTransport as $t, WorkViewSource as A, ReferenceResourceSelector as At, TasksApi as B, UploadChatAttachmentInput as Bt, WorkRecord as C, ListGenerationModelsResponse as Cn, SessionPatchApplyInput as Ct, WorkTargetType as D, SessionPatchStatus as Dt, WorkStatus as E, ModelStatusResponse as En, SessionPatchState as Et, UsersApi as F, PublicAssetMimeType as Ft, BoardSubscriptionHandlers as G, ModelsApi as Gt, BoardClient as H, UploadPublicAssetInput as Ht, UserApi as I, PublicAssetPurpose as It, BoardTransactionInput as J, ChannelsApi as Jt, BoardTransactionAppliedEvent as K, GenerationsApi as Kt, CreateUiCommandInput as L, PublicAssetUploadProgress as Lt, WorkVisibility as M, SearchApi as Mt, WorksApi as N, CreatePublicAssetUploadInput as Nt, WorkUpdateInput as O, createSessionPatchReducer as Ot, ReferralsApi as P, CreatePublicAssetUploadResponse as Pt, SpaceClient as Q, HttpTraceContext as Qt, UiCommandsApi as R, PublicAssetUploadProtocol as Rt, WorkPublicSpaceRecord as S, GenerationUsageBilling as Sn, parseAssistantMessageCommit as St, WorkSessionResponse as T, ModelStatusEntry as Tn, SessionPatchReducer as Tt, BoardEventName as U, SkillsApi as Ut, BoardAwarenessUpdatedEvent as V, UploadChatImageAttachmentInput as Vt, BoardPlaybackChangedEvent as W, PromptsApi as Wt, SessionSubscriptionHandlers as X, Fetch as Xt, SessionEventName as Y, CohubClientOptions as Yt, SpaceChannelBindingRecord as Z, HttpError as Zt, WorkExtractedPageMeta as _, resolveWorkTransport as _n, GenerationStreamSubscribeOptions as _t, WorkCommerceCreditConsumeResponse as a, ParentBridgeTransport as an, PublicInviteApi as at, WorkPresentationMeta as b, CreateGenerationTaskResponse as bn, SessionGenerationStreamClient as bt, WorkCommerceEntitlementsResponse as c, WorkRuntimeApi as cn, AssistantMessageCommit as ct, WorkCommercePurchaseResponse as d, WorkRuntimeContext as dn, GenerationStreamEvent as dt, RawHttpResponse as en, SpaceTurnListOptions as et, WorkAuthorizeResponse as f, WorkRuntimeModeConfig as fn, GenerationStreamFinalizedEvent as ft, WorkDetailResponse as g, createWorkRuntime as gn, GenerationStreamStateEvent as gt, WorkCreateInput as h, createSlugWorkIdResolver as hn, GenerationStreamOutOfSyncEvent as ht, WorkCommerceCheckoutStatus as i, sanitizeAccessToken as in, BuildSpacePathInput as it, WorkViewStatsResponse as j, ReferencesApi as jt, WorkVersionRecord as k, SessionAccessApi as kt, WorkCommerceOrder as l, WorkRuntimeCheckoutState as ln, GenerationStreamCommitEvent as lt, WorkContentDownload as m, WorkRuntimeTransport as mn, GenerationStreamLifecycleEvent as mt, createHttpClient as n, joinApiUrl as nn, WebSocketConnectionState as nt, WorkCommerceCreditConsumeStatus as o, PopupBrokerTransport as on, buildSpaceInvitePath as ot, WorkContent as p, WorkRuntimeRequestOptions as pn, GenerationStreamIntermediateMessage as pt, BoardTransactionError as q, CronJobsApi as qt, WorkCommerceApi as r, matchesUnauthorizedErrorToken as rn, BuildSpaceInvitePathInput as rt, WorkCommerceEntitlement as s, WorkIdResolver as sn, buildSpacePath as st, CohubHttpClient as t, UnauthorizedContext as tn, SpacesApi as tt, WorkCommerceProductResolveResponse as u, WorkRuntimeCheckoutStatus as un, GenerationStreamErrorEvent as ut, WorkGetResponse as v, SpaceStartupResponse as vn, GenerationStreamSubscriptionHandlers as vt, WorkResolveResponse as w, PublicGenerationDeclaration as wn, SessionPatchApplyResult as wt, WorkPublicOwnerRecord as x, GenerationTaskResult as xn, createSessionGenerationStreamClient as xt, WorkMeta as y, CreateGenerationTaskRequest as yn, GenerationStreamTurnUpdatedEvent as yt, WaitForUiCommandOptions as z, PublicAssetsApi as zt };
2167
+ export { SpaceEventName as $, HttpTraceContext as $t, WorkViewSource as A, GenerationUsageBilling as An, SessionAccessApi as At, TasksApi as B, PublicAssetsApi as Bt, WorkRecord as C, PublicFileUploadEntryInput as Cn, parseAssistantMessageCommit as Ct, WorkTargetType as D, CreateGenerationTaskRequest as Dn, SessionPatchState as Dt, WorkStatus as E, SpaceStartupResponse as En, SessionPatchReducer as Et, UsersApi as F, CreatePublicAssetUploadResponse as Ft, BoardSubscriptionHandlers as G, PromptsApi as Gt, BoardClient as H, UploadChatImageAttachmentInput as Ht, UserApi as I, PublicAssetMimeType as It, BoardTransactionInput as J, CronJobsApi as Jt, BoardTransactionAppliedEvent as K, ModelsApi as Kt, CreateUiCommandInput as L, PublicAssetPurpose as Lt, WorkVisibility as M, PublicGenerationDeclaration as Mn, ReferencesApi as Mt, WorksApi as N, ModelStatusEntry as Nn, SearchApi as Nt, WorkUpdateInput as O, CreateGenerationTaskResponse as On, SessionPatchStatus as Ot, ReferralsApi as P, ModelStatusResponse as Pn, CreatePublicAssetUploadInput as Pt, SpaceClient as Q, HttpError as Qt, UiCommandsApi as R, PublicAssetUploadProgress as Rt, WorkPublicSpaceRecord as S, PublicFileListResponse as Sn, createSessionGenerationStreamClient as St, WorkSessionResponse as T, PublicFileUrlResponse as Tn, SessionPatchApplyResult as Tt, BoardEventName as U, UploadPublicAssetInput as Ut, BoardAwarenessUpdatedEvent as V, UploadChatAttachmentInput as Vt, BoardPlaybackChangedEvent as W, SkillsApi as Wt, SessionSubscriptionHandlers as X, CohubClientOptions as Xt, SessionEventName as Y, ChannelsApi as Yt, SpaceChannelBindingRecord as Z, Fetch as Zt, WorkExtractedPageMeta as _, createWorkRuntime as _n, GenerationStreamStateEvent as _t, WorkCommerceCreditConsumeResponse as a, sanitizeAccessToken as an, BuildSpacePathInput as at, WorkPresentationMeta as b, PublicFileCreateUploadResponse as bn, GenerationStreamTurnUpdatedEvent as bt, WorkCommerceEntitlementsResponse as c, WorkIdResolver as cn, buildSpacePath as ct, WorkCommercePurchaseResponse as d, WorkRuntimeCheckoutStatus as dn, GenerationStreamErrorEvent as dt, HttpTransport as en, SpacePublicFilesApi as et, WorkAuthorizeResponse as f, WorkRuntimeContext as fn, GenerationStreamEvent as ft, WorkDetailResponse as g, createSlugWorkIdResolver as gn, GenerationStreamOutOfSyncEvent as gt, WorkCreateInput as h, WorkRuntimeTransport as hn, GenerationStreamLifecycleEvent as ht, WorkCommerceCheckoutStatus as i, matchesUnauthorizedErrorToken as in, BuildSpaceInvitePathInput as it, WorkViewStatsResponse as j, ListGenerationModelsResponse as jn, ReferenceResourceSelector as jt, WorkVersionRecord as k, GenerationTaskResult as kn, createSessionPatchReducer as kt, WorkCommerceOrder as l, WorkRuntimeApi as ln, AssistantMessageCommit as lt, WorkContentDownload as m, WorkRuntimeRequestOptions as mn, GenerationStreamIntermediateMessage as mt, createHttpClient as n, UnauthorizedContext as nn, SpacesApi as nt, WorkCommerceCreditConsumeStatus as o, ParentBridgeTransport as on, PublicInviteApi as ot, WorkContent as p, WorkRuntimeModeConfig as pn, GenerationStreamFinalizedEvent as pt, BoardTransactionError as q, GenerationsApi as qt, WorkCommerceApi as r, joinApiUrl as rn, WebSocketConnectionState as rt, WorkCommerceEntitlement as s, PopupBrokerTransport as sn, buildSpaceInvitePath as st, CohubHttpClient as t, RawHttpResponse as tn, SpaceTurnListOptions as tt, WorkCommerceProductResolveResponse as u, WorkRuntimeCheckoutState as un, GenerationStreamCommitEvent as ut, WorkGetResponse as v, resolveWorkTransport as vn, GenerationStreamSubscribeOptions as vt, WorkResolveResponse as w, PublicFileUploadPlanEntry as wn, SessionPatchApplyInput as wt, WorkPublicOwnerRecord as x, PublicFileListEntry as xn, SessionGenerationStreamClient as xt, WorkMeta as y, PublicFileCreateUploadInput as yn, GenerationStreamSubscriptionHandlers as yt, WaitForUiCommandOptions as z, PublicAssetUploadProtocol as zt };