@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,4 +1,5 @@
1
1
  import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION } from "./board.js";
2
+ import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, normalizeBoardRemoteUrl } from "./board-url.js";
2
3
  import { z } from "zod";
3
4
  //#region ../protocol/dist/board-document.d.ts
4
5
  declare const BoardFrameSchema: z.ZodObject<{
@@ -484,19 +485,39 @@ declare const BoardFileItemSchema: z.ZodObject<{
484
485
  coverUrl: z.ZodOptional<z.ZodString>;
485
486
  }, z.core.$strip>>;
486
487
  }, z.core.$strip>;
487
- declare const BoardTaskOutputSchema: z.ZodObject<{
488
- type: z.ZodEnum<{
489
- audio: "audio";
490
- image: "image";
491
- text: "text";
492
- video: "video";
493
- }>;
494
- url: z.ZodOptional<z.ZodString>;
495
- textExcerpt: z.ZodOptional<z.ZodString>;
488
+ declare const BOARD_TASK_ARTIFACT_LIMIT = 6;
489
+ declare const BoardTaskArtifactSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
490
+ id: z.ZodString;
491
+ title: z.ZodOptional<z.ZodString>;
492
+ url: z.ZodString;
496
493
  mimeType: z.ZodOptional<z.ZodString>;
494
+ type: z.ZodLiteral<"image">;
497
495
  naturalWidth: z.ZodOptional<z.ZodNumber>;
498
496
  naturalHeight: z.ZodOptional<z.ZodNumber>;
499
- }, z.core.$strip>;
497
+ }, z.core.$strict>, z.ZodObject<{
498
+ id: z.ZodString;
499
+ title: z.ZodOptional<z.ZodString>;
500
+ url: z.ZodString;
501
+ mimeType: z.ZodOptional<z.ZodString>;
502
+ type: z.ZodLiteral<"video">;
503
+ previewUrl: z.ZodOptional<z.ZodString>;
504
+ durationMs: z.ZodOptional<z.ZodNumber>;
505
+ naturalWidth: z.ZodOptional<z.ZodNumber>;
506
+ naturalHeight: z.ZodOptional<z.ZodNumber>;
507
+ }, z.core.$strict>, z.ZodObject<{
508
+ id: z.ZodString;
509
+ title: z.ZodOptional<z.ZodString>;
510
+ url: z.ZodString;
511
+ mimeType: z.ZodOptional<z.ZodString>;
512
+ type: z.ZodLiteral<"audio">;
513
+ previewUrl: z.ZodOptional<z.ZodString>;
514
+ durationMs: z.ZodOptional<z.ZodNumber>;
515
+ }, z.core.$strict>, z.ZodObject<{
516
+ id: z.ZodString;
517
+ type: z.ZodLiteral<"text">;
518
+ title: z.ZodOptional<z.ZodString>;
519
+ textExcerpt: z.ZodString;
520
+ }, z.core.$strict>], "type">;
500
521
  /**
501
522
  * Cached task facts used for an immediate first paint. The task run remains the
502
523
  * source of truth and live clients refresh this projection by `taskRunId`.
@@ -512,22 +533,41 @@ declare const BoardTaskSnapshotSchema: z.ZodObject<{
512
533
  title: z.ZodString;
513
534
  model: z.ZodOptional<z.ZodString>;
514
535
  promptExcerpt: z.ZodOptional<z.ZodString>;
515
- outputCount: z.ZodDefault<z.ZodNumber>;
516
- primaryOutput: z.ZodOptional<z.ZodObject<{
517
- type: z.ZodEnum<{
518
- audio: "audio";
519
- image: "image";
520
- text: "text";
521
- video: "video";
522
- }>;
523
- url: z.ZodOptional<z.ZodString>;
524
- textExcerpt: z.ZodOptional<z.ZodString>;
536
+ artifactCount: z.ZodNumber;
537
+ artifacts: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
538
+ id: z.ZodString;
539
+ title: z.ZodOptional<z.ZodString>;
540
+ url: z.ZodString;
525
541
  mimeType: z.ZodOptional<z.ZodString>;
542
+ type: z.ZodLiteral<"image">;
526
543
  naturalWidth: z.ZodOptional<z.ZodNumber>;
527
544
  naturalHeight: z.ZodOptional<z.ZodNumber>;
528
- }, z.core.$strip>>;
545
+ }, z.core.$strict>, z.ZodObject<{
546
+ id: z.ZodString;
547
+ title: z.ZodOptional<z.ZodString>;
548
+ url: z.ZodString;
549
+ mimeType: z.ZodOptional<z.ZodString>;
550
+ type: z.ZodLiteral<"video">;
551
+ previewUrl: z.ZodOptional<z.ZodString>;
552
+ durationMs: z.ZodOptional<z.ZodNumber>;
553
+ naturalWidth: z.ZodOptional<z.ZodNumber>;
554
+ naturalHeight: z.ZodOptional<z.ZodNumber>;
555
+ }, z.core.$strict>, z.ZodObject<{
556
+ id: z.ZodString;
557
+ title: z.ZodOptional<z.ZodString>;
558
+ url: z.ZodString;
559
+ mimeType: z.ZodOptional<z.ZodString>;
560
+ type: z.ZodLiteral<"audio">;
561
+ previewUrl: z.ZodOptional<z.ZodString>;
562
+ durationMs: z.ZodOptional<z.ZodNumber>;
563
+ }, z.core.$strict>, z.ZodObject<{
564
+ id: z.ZodString;
565
+ type: z.ZodLiteral<"text">;
566
+ title: z.ZodOptional<z.ZodString>;
567
+ textExcerpt: z.ZodString;
568
+ }, z.core.$strict>], "type">>>;
529
569
  updatedAt: z.ZodOptional<z.ZodString>;
530
- }, z.core.$strip>;
570
+ }, z.core.$strict>;
531
571
  /** A stable reference to a task run with a small, replaceable display cache. */
532
572
  declare const BoardTaskItemSchema: z.ZodObject<{
533
573
  id: z.ZodString;
@@ -570,22 +610,41 @@ declare const BoardTaskItemSchema: z.ZodObject<{
570
610
  title: z.ZodString;
571
611
  model: z.ZodOptional<z.ZodString>;
572
612
  promptExcerpt: z.ZodOptional<z.ZodString>;
573
- outputCount: z.ZodDefault<z.ZodNumber>;
574
- primaryOutput: z.ZodOptional<z.ZodObject<{
575
- type: z.ZodEnum<{
576
- audio: "audio";
577
- image: "image";
578
- text: "text";
579
- video: "video";
580
- }>;
581
- url: z.ZodOptional<z.ZodString>;
582
- textExcerpt: z.ZodOptional<z.ZodString>;
613
+ artifactCount: z.ZodNumber;
614
+ artifacts: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
615
+ id: z.ZodString;
616
+ title: z.ZodOptional<z.ZodString>;
617
+ url: z.ZodString;
583
618
  mimeType: z.ZodOptional<z.ZodString>;
619
+ type: z.ZodLiteral<"image">;
584
620
  naturalWidth: z.ZodOptional<z.ZodNumber>;
585
621
  naturalHeight: z.ZodOptional<z.ZodNumber>;
586
- }, z.core.$strip>>;
622
+ }, z.core.$strict>, z.ZodObject<{
623
+ id: z.ZodString;
624
+ title: z.ZodOptional<z.ZodString>;
625
+ url: z.ZodString;
626
+ mimeType: z.ZodOptional<z.ZodString>;
627
+ type: z.ZodLiteral<"video">;
628
+ previewUrl: z.ZodOptional<z.ZodString>;
629
+ durationMs: z.ZodOptional<z.ZodNumber>;
630
+ naturalWidth: z.ZodOptional<z.ZodNumber>;
631
+ naturalHeight: z.ZodOptional<z.ZodNumber>;
632
+ }, z.core.$strict>, z.ZodObject<{
633
+ id: z.ZodString;
634
+ title: z.ZodOptional<z.ZodString>;
635
+ url: z.ZodString;
636
+ mimeType: z.ZodOptional<z.ZodString>;
637
+ type: z.ZodLiteral<"audio">;
638
+ previewUrl: z.ZodOptional<z.ZodString>;
639
+ durationMs: z.ZodOptional<z.ZodNumber>;
640
+ }, z.core.$strict>, z.ZodObject<{
641
+ id: z.ZodString;
642
+ type: z.ZodLiteral<"text">;
643
+ title: z.ZodOptional<z.ZodString>;
644
+ textExcerpt: z.ZodString;
645
+ }, z.core.$strict>], "type">>>;
587
646
  updatedAt: z.ZodOptional<z.ZodString>;
588
- }, z.core.$strip>;
647
+ }, z.core.$strict>;
589
648
  }, z.core.$strip>;
590
649
  /**
591
650
  * The set of shape types this client understands natively. Anything else is
@@ -777,15 +836,39 @@ declare const BoardItemSchema: z.ZodPipe<z.ZodAny, z.ZodTransform<BoardUnknownIt
777
836
  title: string;
778
837
  model?: string | undefined;
779
838
  promptExcerpt?: string | undefined;
780
- outputCount: number;
781
- primaryOutput?: {
782
- type: "audio" | "image" | "text" | "video";
783
- url?: string | undefined;
784
- textExcerpt?: string | undefined;
839
+ artifactCount: number;
840
+ artifacts: ({
841
+ id: string;
842
+ title?: string | undefined;
843
+ url: string;
785
844
  mimeType?: string | undefined;
845
+ type: "image";
786
846
  naturalWidth?: number | undefined;
787
847
  naturalHeight?: number | undefined;
788
- } | undefined;
848
+ } | {
849
+ id: string;
850
+ title?: string | undefined;
851
+ url: string;
852
+ mimeType?: string | undefined;
853
+ type: "video";
854
+ previewUrl?: string | undefined;
855
+ durationMs?: number | undefined;
856
+ naturalWidth?: number | undefined;
857
+ naturalHeight?: number | undefined;
858
+ } | {
859
+ id: string;
860
+ title?: string | undefined;
861
+ url: string;
862
+ mimeType?: string | undefined;
863
+ type: "audio";
864
+ previewUrl?: string | undefined;
865
+ durationMs?: number | undefined;
866
+ } | {
867
+ id: string;
868
+ type: "text";
869
+ title?: string | undefined;
870
+ textExcerpt: string;
871
+ })[];
789
872
  updatedAt?: string | undefined;
790
873
  };
791
874
  } | {
@@ -1123,15 +1206,39 @@ declare const BoardDocumentSchema: z.ZodObject<{
1123
1206
  title: string;
1124
1207
  model?: string | undefined;
1125
1208
  promptExcerpt?: string | undefined;
1126
- outputCount: number;
1127
- primaryOutput?: {
1128
- type: "audio" | "image" | "text" | "video";
1129
- url?: string | undefined;
1130
- textExcerpt?: string | undefined;
1209
+ artifactCount: number;
1210
+ artifacts: ({
1211
+ id: string;
1212
+ title?: string | undefined;
1213
+ url: string;
1131
1214
  mimeType?: string | undefined;
1215
+ type: "image";
1132
1216
  naturalWidth?: number | undefined;
1133
1217
  naturalHeight?: number | undefined;
1134
- } | undefined;
1218
+ } | {
1219
+ id: string;
1220
+ title?: string | undefined;
1221
+ url: string;
1222
+ mimeType?: string | undefined;
1223
+ type: "video";
1224
+ previewUrl?: string | undefined;
1225
+ durationMs?: number | undefined;
1226
+ naturalWidth?: number | undefined;
1227
+ naturalHeight?: number | undefined;
1228
+ } | {
1229
+ id: string;
1230
+ title?: string | undefined;
1231
+ url: string;
1232
+ mimeType?: string | undefined;
1233
+ type: "audio";
1234
+ previewUrl?: string | undefined;
1235
+ durationMs?: number | undefined;
1236
+ } | {
1237
+ id: string;
1238
+ type: "text";
1239
+ title?: string | undefined;
1240
+ textExcerpt: string;
1241
+ })[];
1135
1242
  updatedAt?: string | undefined;
1136
1243
  };
1137
1244
  } | {
@@ -1354,7 +1461,7 @@ type BoardVideoItem = z.infer<typeof BoardVideoItemSchema>;
1354
1461
  type BoardAudioItem = z.infer<typeof BoardAudioItemSchema>;
1355
1462
  type BoardFileSnapshot = z.infer<typeof BoardFileSnapshotSchema>;
1356
1463
  type BoardFileItem = z.infer<typeof BoardFileItemSchema>;
1357
- type BoardTaskOutput = z.infer<typeof BoardTaskOutputSchema>;
1464
+ type BoardTaskArtifact = z.infer<typeof BoardTaskArtifactSchema>;
1358
1465
  type BoardTaskSnapshot = z.infer<typeof BoardTaskSnapshotSchema>;
1359
1466
  type BoardTaskItem = z.infer<typeof BoardTaskItemSchema>;
1360
1467
  /** Known (natively handled) item variants. */
@@ -1383,4 +1490,4 @@ declare function isMediaItem(item: BoardItem): item is BoardImageItem | BoardVid
1383
1490
  /** Whether an item references a workspace file (media or file card). */
1384
1491
  declare function isFileBackedItem(item: BoardItem): item is BoardImageItem | BoardVideoItem | BoardAudioItem | BoardFileItem;
1385
1492
  //#endregion
1386
- export { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAudioItem, BoardAudioItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardPoint, BoardPointSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskOutput, BoardTaskOutputSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, DrawPoint, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, SpaceFileRef, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections };
1493
+ export { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardAudioItem, BoardAudioItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardPoint, BoardPointSchema, BoardRemoteUrlSchema, BoardTaskArtifact, BoardTaskArtifactSchema, BoardTaskItem, BoardTaskItemSchema, BoardTaskSnapshot, BoardTaskSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, DrawPoint, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, SpaceFileRef, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, normalizeBoardRemoteUrl, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections };
@@ -1,6 +1,7 @@
1
1
  import { BOARD_ARROW_STROKE_SIZE } from "./board-constants.js";
2
2
  import { BoardConnectionSchema } from "./board-connection.js";
3
3
  import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION } from "./board.js";
4
+ import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, normalizeBoardRemoteUrl } from "./board-url.js";
4
5
  import { z } from "zod";
5
6
  //#region ../protocol/dist/board-document.js
6
7
  const BoardFrameSchema = z.object({
@@ -208,21 +209,41 @@ const BoardFileItemSchema = BoardItemBaseSchema.extend({
208
209
  ref: SpaceFileRefSchema,
209
210
  snapshot: BoardFileSnapshotSchema.optional()
210
211
  });
211
- const BoardTaskOutputSchema = z.object({
212
- type: z.enum([
213
- "image",
214
- "video",
215
- "audio",
216
- "text"
217
- ]),
218
- /** Remote preview only. Inline data is intentionally never persisted. */
219
- url: z.string().url().optional(),
220
- textExcerpt: z.string().max(480).optional(),
221
- mimeType: z.string().max(160).optional(),
222
- /** Intrinsic media size, cached so the node can match the preview aspect. */
223
- naturalWidth: z.number().positive().optional(),
224
- naturalHeight: z.number().positive().optional()
225
- });
212
+ const BOARD_TASK_ARTIFACT_LIMIT = 6;
213
+ const BoardTaskMediaArtifactFields = {
214
+ id: z.string().min(1).max(240),
215
+ title: z.string().max(240).optional(),
216
+ url: BoardRemoteUrlSchema,
217
+ mimeType: z.string().max(160).optional()
218
+ };
219
+ const BoardTaskArtifactSchema = z.discriminatedUnion("type", [
220
+ z.object({
221
+ ...BoardTaskMediaArtifactFields,
222
+ type: z.literal("image"),
223
+ naturalWidth: z.number().positive().optional(),
224
+ naturalHeight: z.number().positive().optional()
225
+ }).strict(),
226
+ z.object({
227
+ ...BoardTaskMediaArtifactFields,
228
+ type: z.literal("video"),
229
+ previewUrl: BoardRemoteUrlSchema.optional(),
230
+ durationMs: z.number().int().positive().optional(),
231
+ naturalWidth: z.number().positive().optional(),
232
+ naturalHeight: z.number().positive().optional()
233
+ }).strict(),
234
+ z.object({
235
+ ...BoardTaskMediaArtifactFields,
236
+ type: z.literal("audio"),
237
+ previewUrl: BoardRemoteUrlSchema.optional(),
238
+ durationMs: z.number().int().positive().optional()
239
+ }).strict(),
240
+ z.object({
241
+ id: z.string().min(1).max(240),
242
+ type: z.literal("text"),
243
+ title: z.string().max(240).optional(),
244
+ textExcerpt: z.string().min(1).max(480)
245
+ }).strict()
246
+ ]);
226
247
  /**
227
248
  * Cached task facts used for an immediate first paint. The task run remains the
228
249
  * source of truth and live clients refresh this projection by `taskRunId`.
@@ -238,10 +259,10 @@ const BoardTaskSnapshotSchema = z.object({
238
259
  title: z.string().min(1).max(240),
239
260
  model: z.string().max(160).optional(),
240
261
  promptExcerpt: z.string().max(480).optional(),
241
- outputCount: z.number().int().nonnegative().default(0),
242
- primaryOutput: BoardTaskOutputSchema.optional(),
262
+ artifactCount: z.number().int().nonnegative(),
263
+ artifacts: z.array(BoardTaskArtifactSchema).max(6).default([]),
243
264
  updatedAt: z.string().optional()
244
- });
265
+ }).strict();
245
266
  /** A stable reference to a task run with a small, replaceable display cache. */
246
267
  const BoardTaskItemSchema = BoardItemBaseSchema.extend({
247
268
  type: z.literal("task"),
@@ -414,4 +435,4 @@ function isFileBackedItem(item) {
414
435
  return item.type === "image" || item.type === "video" || item.type === "audio" || item.type === "file";
415
436
  }
416
437
  //#endregion
417
- export { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardTaskItemSchema, BoardTaskOutputSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections };
438
+ export { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BOARD_REMOTE_URL_MAX_LENGTH, BOARD_TASK_ARTIFACT_LIMIT, BoardAppearanceSchema, BoardArrowItemSchema, BoardAudioItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardPointSchema, BoardRemoteUrlSchema, BoardTaskArtifactSchema, BoardTaskItemSchema, BoardTaskSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, normalizeBoardRemoteUrl, parseBoardDocument, parseBoardItemLoose, unknownRealType, withResolvedConnections };
@@ -0,0 +1,18 @@
1
+ import { z } from "zod";
2
+ //#region ../protocol/dist/board-node.d.ts
3
+ declare const BOARD_COLOR_IDS: readonly ["brand", "neutral", "black", "white", "blue", "green", "amber", "violet", "rose"];
4
+ type BoardColorId = (typeof BOARD_COLOR_IDS)[number];
5
+ declare const BOARD_GEO_KINDS: readonly ["rectangle", "rounded", "ellipse", "diamond", "triangle"];
6
+ type BoardGeoKind = (typeof BOARD_GEO_KINDS)[number];
7
+ type BoardNodeValidationDiagnostic = {
8
+ severity: "error";
9
+ code: "INVALID_BOARD_NODE" | "INVALID_BOARD_GEOMETRY";
10
+ message: string;
11
+ path: string;
12
+ expected?: string;
13
+ received?: unknown;
14
+ allowedValues?: readonly string[];
15
+ coordinateSpace?: "frame-local" | "world";
16
+ };
17
+ //#endregion
18
+ export { BOARD_COLOR_IDS, BOARD_GEO_KINDS, BoardColorId, BoardGeoKind, BoardNodeValidationDiagnostic };
@@ -0,0 +1,239 @@
1
+ import { BOARD_ARROW_STROKE_SIZE } from "./board-constants.js";
2
+ import { BoardTaskSnapshotSchema } from "./board-document.js";
3
+ import { z } from "zod";
4
+ //#region ../protocol/dist/board-node.js
5
+ const BOARD_COLOR_IDS = [
6
+ "brand",
7
+ "neutral",
8
+ "black",
9
+ "white",
10
+ "blue",
11
+ "green",
12
+ "amber",
13
+ "violet",
14
+ "rose"
15
+ ];
16
+ const BoardColorIdSchema = z.enum(BOARD_COLOR_IDS);
17
+ const BOARD_GEO_KINDS = [
18
+ "rectangle",
19
+ "rounded",
20
+ "ellipse",
21
+ "diamond",
22
+ "triangle"
23
+ ];
24
+ const BoardGeoKindSchema = z.enum(BOARD_GEO_KINDS);
25
+ const BOARD_NATIVE_NODE_TYPES = [
26
+ "image",
27
+ "video",
28
+ "audio",
29
+ "file",
30
+ "task",
31
+ "text",
32
+ "geo",
33
+ "draw",
34
+ "arrow",
35
+ "frame"
36
+ ];
37
+ const metadataSchema = z.record(z.string(), z.unknown());
38
+ const commonData = {
39
+ locked: z.boolean().optional(),
40
+ metadata: metadataSchema.optional()
41
+ };
42
+ const pointSchema = z.object({
43
+ x: z.number().finite(),
44
+ y: z.number().finite(),
45
+ p: z.number().finite().min(0).max(1).default(.5)
46
+ }).strict();
47
+ const worldPointSchema = z.object({
48
+ x: z.number().finite(),
49
+ y: z.number().finite()
50
+ }).strict();
51
+ const strokeSizeSchema = z.number().finite().min(1).max(64);
52
+ const mediaViewSchema = z.object({
53
+ title: z.string().optional(),
54
+ mimeType: z.string().optional(),
55
+ size: z.number().finite().nonnegative().optional(),
56
+ mtimeMs: z.number().finite().nonnegative().optional(),
57
+ naturalWidth: z.number().finite().positive().optional(),
58
+ naturalHeight: z.number().finite().positive().optional()
59
+ }).strict();
60
+ const audioViewSchema = mediaViewSchema.extend({ durationMs: z.number().finite().nonnegative().optional() });
61
+ const dataSchemas = {
62
+ text: z.object({
63
+ ...commonData,
64
+ text: z.string().default(""),
65
+ color: BoardColorIdSchema.default("neutral"),
66
+ fontSize: z.number().finite().min(2).max(512).default(24)
67
+ }).strict(),
68
+ geo: z.object({
69
+ ...commonData,
70
+ geo: BoardGeoKindSchema.default("rectangle"),
71
+ text: z.string().default(""),
72
+ color: BoardColorIdSchema.default("brand"),
73
+ fillOpacity: z.number().finite().min(0).max(1).default(0)
74
+ }).strict(),
75
+ draw: z.object({
76
+ ...commonData,
77
+ points: z.array(pointSchema).min(1),
78
+ color: BoardColorIdSchema.default("brand"),
79
+ size: strokeSizeSchema.default(4)
80
+ }).strict(),
81
+ arrow: z.object({
82
+ ...commonData,
83
+ start: worldPointSchema,
84
+ end: worldPointSchema,
85
+ bend: z.number().finite().min(-.85).max(.85).default(0),
86
+ color: BoardColorIdSchema.default("brand"),
87
+ size: strokeSizeSchema.default(BOARD_ARROW_STROKE_SIZE),
88
+ arrowStart: z.boolean().default(false),
89
+ arrowEnd: z.boolean().default(true),
90
+ label: z.string().default("")
91
+ }).strict(),
92
+ frame: z.object({
93
+ ...commonData,
94
+ label: z.string().default("Frame"),
95
+ color: BoardColorIdSchema.default("neutral")
96
+ }).strict(),
97
+ image: z.object({
98
+ ...commonData,
99
+ crop: z.object({
100
+ x: z.number().finite().min(0).max(1),
101
+ y: z.number().finite().min(0).max(1),
102
+ w: z.number().finite().min(0).max(1),
103
+ h: z.number().finite().min(0).max(1)
104
+ }).strict().optional()
105
+ }).strict(),
106
+ video: z.object(commonData).strict(),
107
+ audio: z.object(commonData).strict(),
108
+ file: z.object(commonData).strict(),
109
+ task: z.object({
110
+ ...commonData,
111
+ taskRunId: z.string().min(1)
112
+ }).strict()
113
+ };
114
+ const fileViewSchema = z.object({
115
+ title: z.string().optional(),
116
+ mimeType: z.string().optional(),
117
+ size: z.number().finite().nonnegative().optional(),
118
+ mtimeMs: z.number().finite().nonnegative().optional(),
119
+ excerpt: z.string().optional(),
120
+ coverPath: z.string().optional(),
121
+ coverUrl: z.string().url().optional()
122
+ }).strict();
123
+ const taskViewSchema = BoardTaskSnapshotSchema;
124
+ const emptyViewSchema = z.object({}).strict();
125
+ const viewSchemas = {
126
+ image: mediaViewSchema,
127
+ video: mediaViewSchema,
128
+ audio: audioViewSchema,
129
+ file: fileViewSchema,
130
+ task: taskViewSchema,
131
+ text: emptyViewSchema,
132
+ geo: emptyViewSchema,
133
+ draw: emptyViewSchema,
134
+ arrow: emptyViewSchema,
135
+ frame: emptyViewSchema
136
+ };
137
+ const nodeEnvelopeSchema = z.object({
138
+ nodeId: z.string().min(1).max(160),
139
+ type: z.string().min(1).max(40),
140
+ parentId: z.string().min(1).max(160).nullable(),
141
+ orderKey: z.string().max(4096).nullable(),
142
+ x: z.number().finite(),
143
+ y: z.number().finite(),
144
+ width: z.number().finite().positive(),
145
+ height: z.number().finite().positive(),
146
+ rotation: z.number().finite(),
147
+ refKind: z.string().max(40).nullable(),
148
+ refPath: z.string().max(4096).nullable(),
149
+ refUrl: z.string().max(4096).nullable(),
150
+ view: z.record(z.string(), z.unknown()),
151
+ style: z.record(z.string(), z.unknown()),
152
+ data: z.record(z.string(), z.unknown())
153
+ }).strict();
154
+ function jsonSchema(schema) {
155
+ return z.toJSONSchema(schema);
156
+ }
157
+ jsonSchema(nodeEnvelopeSchema), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(dataSchemas[type])])), Object.fromEntries(BOARD_NATIVE_NODE_TYPES.map((type) => [type, jsonSchema(viewSchemas[type])]));
158
+ function issueDiagnostic(issue, path) {
159
+ const fullPath = [path, ...issue.path].join(".");
160
+ const values = "values" in issue && Array.isArray(issue.values) ? issue.values.filter((value) => typeof value === "string") : void 0;
161
+ return {
162
+ severity: "error",
163
+ code: "INVALID_BOARD_NODE",
164
+ message: `${fullPath}: ${issue.message}`,
165
+ path: fullPath,
166
+ ...values?.length ? { allowedValues: values } : {}
167
+ };
168
+ }
169
+ function drawGeometryDiagnostic(node, data, path) {
170
+ let minX = Number.POSITIVE_INFINITY;
171
+ let minY = Number.POSITIVE_INFINITY;
172
+ let maxX = Number.NEGATIVE_INFINITY;
173
+ let maxY = Number.NEGATIVE_INFINITY;
174
+ for (const point of data.points) {
175
+ const radius = Math.max(.5, data.size / 2 * (.5 + point.p));
176
+ minX = Math.min(minX, point.x - radius);
177
+ minY = Math.min(minY, point.y - radius);
178
+ maxX = Math.max(maxX, point.x + radius);
179
+ maxY = Math.max(maxY, point.y + radius);
180
+ }
181
+ const width = Math.max(1, maxX - minX);
182
+ const height = Math.max(1, maxY - minY);
183
+ const tolerance = Math.max(.01, node.width * 1e-6, node.height * 1e-6);
184
+ if (Math.abs(minX) <= tolerance && Math.abs(minY) <= tolerance && Math.abs(width - node.width) <= tolerance && Math.abs(height - node.height) <= tolerance) return null;
185
+ return {
186
+ severity: "error",
187
+ code: "INVALID_BOARD_GEOMETRY",
188
+ message: `${path}.data.points must use frame-local coordinates and match the node frame`,
189
+ path: `${path}.data.points`,
190
+ expected: "frame-local points with bounds matching width and height",
191
+ coordinateSpace: "frame-local"
192
+ };
193
+ }
194
+ function validateBoardNodeInput(node, path = "node") {
195
+ const envelopeResult = nodeEnvelopeSchema.safeParse(node);
196
+ if (!envelopeResult.success) return envelopeResult.error.issues.map((issue) => issueDiagnostic(issue, path));
197
+ if (typeof node.type !== "string" || !BOARD_NATIVE_NODE_TYPES.includes(node.type)) return [{
198
+ severity: "error",
199
+ code: "INVALID_BOARD_NODE",
200
+ message: `${path}.type is not supported`,
201
+ path: `${path}.type`,
202
+ expected: "BoardNativeNodeType",
203
+ received: node.type,
204
+ allowedValues: BOARD_NATIVE_NODE_TYPES
205
+ }];
206
+ const type = node.type;
207
+ const dataResult = dataSchemas[type].safeParse(node.data ?? {});
208
+ if (!dataResult.success) return dataResult.error.issues.map((issue) => issueDiagnostic(issue, `${path}.data`));
209
+ const viewResult = viewSchemas[type].safeParse(node.view ?? {});
210
+ if (!viewResult.success) return viewResult.error.issues.map((issue) => issueDiagnostic(issue, `${path}.view`));
211
+ if (type === "image" || type === "video" || type === "audio" || type === "file") {
212
+ if (node.refKind !== "space_file" || typeof node.refPath !== "string" || !node.refPath) return [{
213
+ severity: "error",
214
+ code: "INVALID_BOARD_NODE",
215
+ message: `${path} requires a space file reference`,
216
+ path: `${path}.refPath`,
217
+ expected: "non-empty refPath with refKind space_file"
218
+ }];
219
+ }
220
+ if (type === "draw") {
221
+ const diagnostic = drawGeometryDiagnostic(node, dataResult.data, path);
222
+ return diagnostic ? [diagnostic] : [];
223
+ }
224
+ if (type === "arrow") {
225
+ const data = dataResult.data;
226
+ const inside = (point) => point.x >= node.x && point.x <= node.x + node.width && point.y >= node.y && point.y <= node.y + node.height;
227
+ if (!inside(data.start) || !inside(data.end)) return [{
228
+ severity: "error",
229
+ code: "INVALID_BOARD_GEOMETRY",
230
+ message: `${path}.data endpoints must be covered by the node frame`,
231
+ path: `${path}.data`,
232
+ expected: "world-space endpoints inside the node frame",
233
+ coordinateSpace: "world"
234
+ }];
235
+ }
236
+ return [];
237
+ }
238
+ //#endregion
239
+ export { BOARD_COLOR_IDS, BOARD_GEO_KINDS, BOARD_NATIVE_NODE_TYPES, BoardColorIdSchema, BoardGeoKindSchema, validateBoardNodeInput };
@@ -0,0 +1,12 @@
1
+ import { z } from "zod";
2
+ //#region ../protocol/dist/board-url.d.ts
3
+ declare const BOARD_REMOTE_URL_MAX_LENGTH = 4096;
4
+ /**
5
+ * Normalize a browser-loadable public HTTP(S) URL. This blocks explicit local
6
+ * addresses; any future server-side fetcher must additionally validate DNS
7
+ * resolution to defend against rebinding.
8
+ */
9
+ declare function normalizeBoardRemoteUrl(value: unknown): string | undefined;
10
+ declare const BoardRemoteUrlSchema: z.ZodString;
11
+ //#endregion
12
+ export { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, normalizeBoardRemoteUrl };