@neta-art/cohub 11.2.0 → 11.3.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.
@@ -36,7 +36,7 @@ const colorString = z.string().max(120).refine(isBoardColorString, "expected a p
36
36
  const BoardColorSchema = z.union([colorString, z.object({
37
37
  light: colorString,
38
38
  dark: colorString
39
- }).strict()]);
39
+ }).strict()]).describe("Palette token (follows the theme), CSS color, or { light, dark }.");
40
40
  const BOARD_DASHES = [
41
41
  "solid",
42
42
  "dashed",
@@ -44,12 +44,12 @@ const BOARD_DASHES = [
44
44
  ];
45
45
  const BoardStyleSchema = z.object({
46
46
  fill: BoardColorSchema.optional(),
47
- fillOpacity: ratio.optional(),
47
+ fillOpacity: ratio.optional().describe("Fill opacity, independent of the item's opacity."),
48
48
  stroke: BoardColorSchema.optional(),
49
49
  strokeWidth: finite.min(0).max(64).optional(),
50
50
  dash: z.enum(BOARD_DASHES).optional(),
51
- radius: nonNegative.optional(),
52
- trim: ratio.optional()
51
+ radius: nonNegative.optional().describe("Corner radius in board units."),
52
+ trim: ratio.optional().describe("Fraction of the outline drawn; animate 0 → 1 to draw it in.")
53
53
  }).strict();
54
54
  function isSafeBoardSourcePath(value) {
55
55
  return value.length > 0 && value.length <= 4096 && !value.startsWith("/") && !/^[a-z][a-z\d+.-]*:/i.test(value.trimStart()) && !value.includes("\\") && value.split("/").every((part) => part.length > 0 && part !== "." && part !== "..");
@@ -65,18 +65,18 @@ function parseBoardMediaSource(src) {
65
65
  value: src
66
66
  } : null;
67
67
  }
68
- const BoardMediaSourceSchema = z.string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a stable public HTTP(S) URL; relative Space file paths remain supported.");
68
+ const BoardMediaSourceSchema = z.string().max(4096).refine((src) => parseBoardMediaSource(src) !== null, "src must be a public HTTP(S) URL or relative Space file path").describe("Prefer a public HTTP(S) URL; a Space path relative to the workspace root also works.");
69
69
  const BoardScriptSchema = z.object({
70
- src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module"),
71
- params: z.record(z.string(), z.json()).default({}),
72
- targets: z.record(z.string().min(1).max(80), BoardIdSchema).default({}),
73
- seed: z.string().min(1).max(160).optional(),
70
+ src: srcSchema.refine((path) => /\.m?js$/.test(path), "script src must be a .js or .mjs module").describe("A .js or .mjs Space file."),
71
+ params: z.record(z.string(), z.json()).default({}).describe("Values the module reads as params."),
72
+ targets: z.record(z.string().min(1).max(80), BoardIdSchema).default({}).describe("Named items the module can reach, as ctx.targets."),
73
+ seed: z.string().min(1).max(160).optional().describe("Seed for ctx.random(); defaults to the item id."),
74
74
  enabled: z.boolean().default(true)
75
- }).strict();
75
+ }).strict().describe("A JavaScript module attached to the item; `cohub boards schema script` lists its API.");
76
76
  const itemEnvelope = {
77
77
  script: BoardScriptSchema.optional(),
78
- parent: BoardIdSchema.optional(),
79
- z: finite.optional(),
78
+ parent: BoardIdSchema.optional().describe("A frame id; position becomes relative to the frame, and the item moves with it."),
79
+ z: finite.optional().describe("Order among siblings; new items go on top."),
80
80
  position: BoardVec2Schema.default({
81
81
  x: 0,
82
82
  y: 0
@@ -86,7 +86,7 @@ const itemEnvelope = {
86
86
  origin: BoardVec2Schema.default({
87
87
  x: .5,
88
88
  y: .5
89
- }),
89
+ }).describe("Rotation and scale origin as fractions of the size."),
90
90
  opacity: ratio.default(1),
91
91
  style: BoardStyleSchema.default({}),
92
92
  locked: z.boolean().optional(),
@@ -119,8 +119,8 @@ const BoardFrameItemSchema = z.object({
119
119
  type: z.literal("frame"),
120
120
  props: z.object({
121
121
  label: z.string().max(280).default(""),
122
- decoration: z.enum(["frame", "none"]).optional(),
123
- clip: z.boolean().default(true)
122
+ decoration: z.enum(["frame", "none"]).optional().describe("none hides the title, border and background: an invisible group whose tracks move every child."),
123
+ clip: z.boolean().default(true).describe("Hide children outside the frame.")
124
124
  }).strict().prefault({})
125
125
  }).strict();
126
126
  const BoardTextItemSchema = z.object({
@@ -130,12 +130,12 @@ const BoardTextItemSchema = z.object({
130
130
  text: z.string().default(""),
131
131
  fontSize: fontSize.default(24),
132
132
  fontWeight: finite.min(100).max(900).default(500),
133
- font: z.string().min(1).max(120).default("sans"),
133
+ font: z.string().min(1).max(120).default("sans").describe("sans, serif, mono, or a font family name."),
134
134
  align: z.enum(BOARD_TEXT_ALIGNS).default("left"),
135
135
  lineHeight: finite.min(.5).max(4).default(4 / 3),
136
- width: finite.positive().optional(),
137
- reveal: ratio.default(1),
138
- caret: z.boolean().default(false)
136
+ width: finite.positive().optional().describe("Wrap width; the height follows the text."),
137
+ reveal: ratio.default(1).describe("Fraction of the text shown; animate 0 → 1 to type it."),
138
+ caret: z.boolean().default(false).describe("Blink a caret while the text is being revealed.")
139
139
  }).strict().prefault({})
140
140
  }).strict();
141
141
  const BoardShapeItemSchema = z.object({
@@ -143,7 +143,7 @@ const BoardShapeItemSchema = z.object({
143
143
  type: z.literal("shape"),
144
144
  props: z.object({
145
145
  geometry: z.enum(BOARD_SHAPE_GEOMETRIES).default("rectangle"),
146
- path: z.string().min(1).max(2e5).optional(),
146
+ path: z.string().min(1).max(2e5).optional().describe("SVG path data for path geometry, fitted to the item size."),
147
147
  text: z.string().default(""),
148
148
  fontSize: fontSize.default(20),
149
149
  align: z.enum(BOARD_TEXT_ALIGNS).default("center")
@@ -155,12 +155,12 @@ const BoardShapeItemSchema = z.object({
155
155
  const BoardDrawPointSchema = z.object({
156
156
  x: finite,
157
157
  y: finite,
158
- p: ratio.default(.5)
158
+ p: ratio.default(.5).describe("Pen pressure.")
159
159
  }).strict();
160
160
  const BoardDrawItemSchema = z.object({
161
161
  ...unsized,
162
162
  type: z.literal("draw"),
163
- props: z.object({ points: z.array(BoardDrawPointSchema).min(1).max(1e5) }).strict()
163
+ props: z.object({ points: z.array(BoardDrawPointSchema).min(1).max(1e5).describe("Stroke points relative to position; the size follows them.") }).strict()
164
164
  }).strict();
165
165
  const BOARD_ANCHOR_SIDES = [
166
166
  "top",
@@ -181,10 +181,10 @@ const BoardArrowAnchorSchema = z.union([
181
181
  ]);
182
182
  const BoardArrowBindingSchema = z.object({
183
183
  item: BoardIdSchema,
184
- anchor: BoardArrowAnchorSchema.default("auto"),
184
+ anchor: BoardArrowAnchorSchema.default("auto").describe("auto uses the side facing the other end; or a side with an offset, or a point as fractions of the item."),
185
185
  port: z.string().min(1).max(120).optional()
186
186
  }).strict();
187
- const BoardArrowEndSchema = z.union([BoardVec2Schema, BoardArrowBindingSchema]);
187
+ const BoardArrowEndSchema = z.union([BoardVec2Schema, BoardArrowBindingSchema]).describe("A point relative to position, or { item } to follow that item.");
188
188
  const BOARD_ARROW_ROUTES = [
189
189
  "straight",
190
190
  "curve",
@@ -197,13 +197,13 @@ const BoardArrowItemSchema = z.object({
197
197
  start: BoardArrowEndSchema,
198
198
  end: BoardArrowEndSchema,
199
199
  route: z.enum(BOARD_ARROW_ROUTES).default("straight"),
200
- bend: finite.min(-.85).max(.85).default(0),
201
- waypoints: z.array(BoardVec2Schema).max(64).default([]),
200
+ bend: finite.min(-.85).max(.85).default(0).describe("Sideways curve as a fraction of the length; the sign picks the side."),
201
+ waypoints: z.array(BoardVec2Schema).max(64).default([]).describe("Points the route passes through."),
202
202
  arrowStart: z.boolean().default(false),
203
203
  arrowEnd: z.boolean().default(true),
204
204
  label: z.string().max(280).default(""),
205
205
  fontSize: fontSize.default(14),
206
- relation: z.string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional()
206
+ relation: z.string().max(64).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*$/, "relation must be a lowercase slug").optional().describe("What the arrow means, as a slug such as triggers or depends-on.")
207
207
  }).strict()
208
208
  }).strict();
209
209
  const BoardMediaSnapshotSchema = z.object({
@@ -217,7 +217,7 @@ const BoardMediaSnapshotSchema = z.object({
217
217
  excerpt: z.string().optional(),
218
218
  coverPath: z.string().optional(),
219
219
  coverUrl: z.string().optional()
220
- }).strict();
220
+ }).strict().describe("Cached facts for an instant preview; filled in when the media loads.");
221
221
  const fileProps = {
222
222
  src: BoardMediaSourceSchema,
223
223
  snapshot: BoardMediaSnapshotSchema.optional()
@@ -225,21 +225,21 @@ const fileProps = {
225
225
  const BoardMediaOriginSchema = z.object({
226
226
  taskRunId: z.string().min(1).max(160),
227
227
  artifactId: z.string().min(1).max(240)
228
- }).strict();
228
+ }).strict().describe("The generation run and result this media came from.");
229
229
  const mediaProps = {
230
230
  ...fileProps,
231
231
  origin: BoardMediaOriginSchema.optional()
232
232
  };
233
233
  const timedFileProps = {
234
234
  ...mediaProps,
235
- time: nonNegative.optional()
235
+ time: nonNegative.optional().describe("Playback position in milliseconds; animate props.time to play it on a timeline.")
236
236
  };
237
237
  const BoardCropSchema = z.object({
238
238
  x: ratio,
239
239
  y: ratio,
240
240
  w: ratio,
241
241
  h: ratio
242
- }).strict();
242
+ }).strict().describe("Region shown, as fractions of the image. Without it the whole image fits inside size.");
243
243
  const BoardImageItemSchema = z.object({
244
244
  ...boxed(640, 360),
245
245
  type: z.literal("image"),
@@ -320,8 +320,8 @@ const BoardTaskItemSchema = z.object({
320
320
  ...boxed(420, 240),
321
321
  type: z.literal("task"),
322
322
  props: z.object({
323
- taskRunId: z.string().min(1).max(160),
324
- snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server for tasks in the Board's Space; writers may omit it.")
323
+ taskRunId: z.string().min(1).max(160).describe("The generation run shown; the server keeps the card's status and results up to date."),
324
+ snapshot: BoardTaskSnapshotSchema.describe("Maintained by the server; omit it.")
325
325
  }).strict()
326
326
  }).strict();
327
327
  const BOARD_EFFECT_KINDS = [
@@ -397,8 +397,8 @@ const BoardEffectItemSchema = z.object({
397
397
  spread: finite.min(0).max(360).default(360),
398
398
  gravity: finite.default(0),
399
399
  intensity: nonNegative.max(10).default(1),
400
- follow: BoardIdSchema.optional(),
401
- seed: z.string().min(1).max(160).optional()
400
+ follow: BoardIdSchema.optional().describe("trail: the item to follow."),
401
+ seed: z.string().min(1).max(160).optional().describe("Makes procedural motion repeatable.")
402
402
  }).strict()
403
403
  }).strict();
404
404
  const BoardCustomItemSchema = z.object({
@@ -517,21 +517,21 @@ function isBoardEase(value) {
517
517
  }
518
518
  const BoardEaseSchema = z.string().max(120).refine(isBoardEase, "expected a CSS easing: linear, ease-in-out, cubic-bezier(…) or steps(…)");
519
519
  const BoardKeyframeSchema = z.object({
520
- at: nonNegative,
520
+ at: nonNegative.describe("Time in milliseconds."),
521
521
  value: z.unknown(),
522
- ease: BoardEaseSchema.optional()
522
+ ease: BoardEaseSchema.optional().describe("Easing into this keyframe: a CSS keyword, cubic-bezier() or steps(); defaults to linear.")
523
523
  }).strict();
524
524
  const BoardTrackSchema = z.object({
525
- target: z.string().min(1).max(160),
526
- property: z.string().min(1).max(200),
527
- keyframes: z.array(BoardKeyframeSchema).min(1).max(1e5),
528
- composite: z.enum(["replace", "add"]).default("replace"),
525
+ target: z.string().min(1).max(160).describe("An item id, camera, or another animation id (its time property nests that timeline)."),
526
+ property: z.string().min(1).max(200).describe("JSON path in the target, e.g. position, opacity, style.fill, props.text."),
527
+ keyframes: z.array(BoardKeyframeSchema).min(1).max(1e5).describe("Ordered by at. The value holds before the first and after the last keyframe."),
528
+ composite: z.enum(["replace", "add"]).default("replace").describe("replace: the latest-started track wins. add: positions and rotations add; scale and opacity multiply."),
529
529
  interpolation: z.enum([
530
530
  "auto",
531
531
  "step",
532
532
  "spline"
533
- ]).default("auto"),
534
- orient: z.boolean().optional()
533
+ ]).default("auto").describe("auto blends numbers, vectors and colors and steps other values; spline smooths position paths."),
534
+ orient: z.boolean().optional().describe("Rotate the item along its path.")
535
535
  }).strict().superRefine((track, context) => {
536
536
  for (let index = 1; index < track.keyframes.length; index += 1) if ((track.keyframes[index]?.at ?? 0) < (track.keyframes[index - 1]?.at ?? 0)) context.addIssue({
537
537
  code: "custom",
@@ -546,7 +546,7 @@ const BoardTrackSchema = z.object({
546
546
  const BoardMarkerSchema = z.object({
547
547
  at: nonNegative,
548
548
  label: z.string().max(280).optional(),
549
- pause: z.boolean().optional()
549
+ pause: z.boolean().optional().describe("Hold shared playback here until next.")
550
550
  }).strict();
551
551
  const BOARD_PLAY_MODES = [
552
552
  "manual",
@@ -555,12 +555,12 @@ const BOARD_PLAY_MODES = [
555
555
  ];
556
556
  const BoardAnimationHeaderSchema = z.object({
557
557
  name: z.string().max(280).optional(),
558
- duration: finite.positive().max(864e5),
559
- play: z.enum(BOARD_PLAY_MODES).default("manual"),
558
+ duration: finite.positive().max(864e5).describe("Milliseconds; a new animation without it ends at its last keyframe."),
559
+ play: z.enum(BOARD_PLAY_MODES).default("manual").describe("manual: only shared playback starts it. auto: plays when the Board opens. always: loops continuously."),
560
560
  delay: nonNegative.default(0),
561
561
  loop: z.boolean().default(false),
562
- end: z.enum(["hold", "reset"]).default("hold"),
563
- markers: z.array(BoardMarkerSchema).max(1e4).default([])
562
+ end: z.enum(["hold", "reset"]).default("hold").describe("hold keeps the last frame; reset returns to the start."),
563
+ markers: z.array(BoardMarkerSchema).max(1e4).default([]).describe("Labeled points on this timeline; a nested animation's markers do not carry over.")
564
564
  }).strict();
565
565
  const BoardAnimationSchema = BoardAnimationHeaderSchema.extend({ tracks: z.record(BoardKeySchema, BoardTrackSchema).default({}) }).strict();
566
566
  const BOARD_ENTER_PRESETS = [
@@ -578,7 +578,7 @@ const BoardBackgroundSchema = z.object({
578
578
  "image"
579
579
  ]).default("dots"),
580
580
  color: BoardColorSchema.optional(),
581
- imageUrl: z.string().url().max(4096).optional(),
581
+ imageUrl: z.string().url().max(4096).optional().describe("Background image for kind image."),
582
582
  fit: z.enum([
583
583
  "cover",
584
584
  "contain",
@@ -593,13 +593,13 @@ const BoardSettingsSchema = z.object({
593
593
  title: z.string().min(1).max(255).optional(),
594
594
  background: BoardBackgroundSchema.default({ kind: "dots" }),
595
595
  grid: z.object({
596
- visible: z.boolean().default(false),
596
+ visible: z.boolean().default(false).describe("Show the grid overlay."),
597
597
  size: finite.min(4).max(512).default(24)
598
598
  }).strict().optional(),
599
599
  enter: z.object({
600
600
  preset: z.enum(BOARD_ENTER_PRESETS),
601
601
  duration: finite.positive().max(1e4).optional()
602
- }).strict().optional()
602
+ }).strict().optional().describe("Motion for items as they are added.")
603
603
  }).strict();
604
604
  function emptyBoardDocument() {
605
605
  return {
@@ -1,6 +1,6 @@
1
1
  //#region ../protocol/dist/board-schema.d.ts
2
2
  type JsonSchema = Record<string, unknown>;
3
- declare const BOARD_SCHEMA_TARGETS: readonly ["board", "animation", "track", "camera", ...("arrow" | "audio" | "custom" | "draw" | "effect" | "file" | "frame" | "image" | "shape" | "task" | "text" | "video")[]];
3
+ declare const BOARD_SCHEMA_TARGETS: readonly ["board", "animation", "track", "script", "camera", ...("arrow" | "audio" | "custom" | "draw" | "effect" | "file" | "frame" | "image" | "shape" | "task" | "text" | "video")[]];
4
4
  type BoardJsonSchemaResult = {
5
5
  schema?: JsonSchema;
6
6
  properties?: Array<{
@@ -11,7 +11,6 @@ type BoardJsonSchemaResult = {
11
11
  description: string;
12
12
  parameters: Record<string, string>;
13
13
  }>;
14
- semantics?: Record<string, string>;
15
14
  };
16
15
  declare function boardJsonSchema(target: string): BoardJsonSchemaResult | null;
17
16
  declare function boardSchemaOverview(): {
@@ -1,4 +1,4 @@
1
- import { BOARD_CAMERA_TARGET, BOARD_COLOR_TOKENS, BOARD_EFFECT_KINDS, BOARD_EFFECT_KIND_INFO, BOARD_ITEM_SCHEMAS, BOARD_ITEM_TYPES, BoardAnimationHeaderSchema, BoardKeySchema, BoardSettingsSchema, BoardTrackSchema, isBuiltinItemType } from "./board-model.js";
1
+ import { BOARD_CAMERA_TARGET, BOARD_COLOR_TOKENS, BOARD_EFFECT_KINDS, BOARD_EFFECT_KIND_INFO, BOARD_ITEM_SCHEMAS, BOARD_ITEM_TYPES, BoardAnimationHeaderSchema, BoardKeySchema, BoardScriptSchema, BoardSettingsSchema, BoardTrackSchema, isBuiltinItemType } from "./board-model.js";
2
2
  import { listBoardProperties } from "./board-patch.js";
3
3
  import { z } from "zod";
4
4
  //#region ../protocol/dist/board-schema.js
@@ -13,6 +13,7 @@ const BOARD_SCHEMA_TARGETS = [
13
13
  "board",
14
14
  "animation",
15
15
  "track",
16
+ "script",
16
17
  BOARD_CAMERA_TARGET,
17
18
  ...BOARD_ITEM_TYPES
18
19
  ];
@@ -20,32 +21,16 @@ function boardJsonSchema(target) {
20
21
  if (target === "board") return { schema: toJsonSchema(BoardSettingsSchema) };
21
22
  if (target === "animation") return {
22
23
  schema: toJsonSchema(BoardAnimationHeaderSchema.extend({ tracks: z.record(BoardKeySchema, BoardTrackSchema).optional() })),
23
- properties: listBoardProperties("animation"),
24
- semantics: { composition: "Target another animation's time property to drive its local clock. Parent markers control pauses; child markers are not automatically promoted." }
25
- };
26
- if (target === "track") return {
27
- schema: toJsonSchema(BoardTrackSchema),
28
- semantics: {
29
- boundary: "Before the first keyframe and after the last, the value is held. Use opacity tracks to control visibility.",
30
- easing: "Defaults to linear. The destination keyframe controls the incoming segment. Supports CSS easing keywords, cubic-bezier() and steps().",
31
- composition: "replace: the most recently started track wins; ties use the lexicographically larger track ID. Before any start, the nearest upcoming track wins. add: numbers and positions add; opacity and scale multiply.",
32
- interpolation: "auto interpolates numbers, colors and vectors; other values step. spline smooths vector motion. orient follows the position tangent."
33
- }
34
- };
35
- if (target === "effect") return {
36
- schema: toJsonSchema(BOARD_ITEM_SCHEMAS.effect),
37
- properties: listBoardProperties("effect"),
38
- semantics: {
39
- follow: "follow is used by trail only. Parent a particle effect to a decoration:none frame to move it with other items.",
40
- time: "Effects use animation time in milliseconds. trail samples target history; seed makes procedural particles repeatable."
41
- },
42
- kinds: Object.fromEntries(BOARD_EFFECT_KINDS.map((kind) => [kind, BOARD_EFFECT_KIND_INFO[kind]]))
24
+ properties: listBoardProperties("animation")
43
25
  };
26
+ if (target === "track") return { schema: toJsonSchema(BoardTrackSchema) };
27
+ if (target === "script") return { schema: toJsonSchema(BoardScriptSchema) };
44
28
  if (target === "camera") return { properties: listBoardProperties(BOARD_CAMERA_TARGET) };
45
29
  if (!isBuiltinItemType(target)) return null;
46
30
  return {
47
31
  schema: toJsonSchema(BOARD_ITEM_SCHEMAS[target]),
48
- properties: listBoardProperties(target)
32
+ properties: listBoardProperties(target),
33
+ ...target === "effect" ? { kinds: Object.fromEntries(BOARD_EFFECT_KINDS.map((kind) => [kind, BOARD_EFFECT_KIND_INFO[kind]])) } : {}
49
34
  };
50
35
  }
51
36
  function boardSchemaOverview() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neta-art/cohub",
3
- "version": "11.2.0",
3
+ "version": "11.3.0",
4
4
  "description": "Cohub SDK for spaces, sessions, boards, and realtime agent collaboration.",
5
5
  "license": "Apache-2.0",
6
6
  "private": false,