@neta-art/cohub 8.10.2 → 8.12.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 (45) hide show
  1. package/dist/board/animation.js +14 -2
  2. package/dist/board/core/file-preview.d.ts +20 -141
  3. package/dist/board/core/file-preview.js +25 -202
  4. package/dist/board/core/file-snapshot.d.ts +106 -0
  5. package/dist/board/core/file-snapshot.js +503 -0
  6. package/dist/board/index.d.ts +4 -2
  7. package/dist/board/index.js +4 -2
  8. package/dist/board/mutation.js +2 -1
  9. package/dist/board/render/board-background.d.ts +16 -0
  10. package/dist/board/render/{themes/clean-theme.js → board-background.js} +28 -35
  11. package/dist/board/render/index.d.ts +3 -3
  12. package/dist/board/render/index.js +2 -2
  13. package/dist/board/render/renderers/file-card-renderer.js +62 -17
  14. package/dist/board/replay.d.ts +52 -0
  15. package/dist/board/replay.js +261 -0
  16. package/dist/board/semantic-document.d.ts +9 -2
  17. package/dist/board/semantic-document.js +1 -3
  18. package/dist/chunks/environment.d.ts +272 -7
  19. package/dist/chunks/environment.js +1 -0
  20. package/dist/chunks/http.d.ts +109 -7
  21. package/dist/chunks/http.js +47 -10
  22. package/dist/chunks/websocket.d.ts +1 -1
  23. package/dist/http.d.ts +3 -3
  24. package/dist/index.d.ts +65 -4
  25. package/dist/index.js +514 -64
  26. package/dist/protocol/dist/board-animation.d.ts +1 -0
  27. package/dist/protocol/dist/board-animation.js +34 -0
  28. package/dist/protocol/dist/board-authoring.d.ts +2 -1
  29. package/dist/protocol/dist/board-capability-registry.js +53 -3
  30. package/dist/protocol/dist/board-codec.js +149 -2
  31. package/dist/protocol/dist/board-constants.js +29 -7
  32. package/dist/protocol/dist/board-document.d.ts +30 -16
  33. package/dist/protocol/dist/board-document.js +15 -12
  34. package/dist/protocol/dist/board-effect.d.ts +4 -2
  35. package/dist/protocol/dist/board-effect.js +3 -2
  36. package/dist/protocol/dist/board.d.ts +148 -3
  37. package/dist/protocol/dist/board.js +7 -0
  38. package/dist/protocol/dist/index.d.ts +4 -2
  39. package/dist/protocol/dist/provenance.d.ts +21 -0
  40. package/dist/types.d.ts +1 -1
  41. package/docs/app-runtime-guide.md +28 -3
  42. package/package.json +1 -1
  43. package/dist/board/render/themes/board-theme-registry.d.ts +0 -22
  44. package/dist/board/render/themes/board-theme-registry.js +0 -13
  45. package/dist/board/render/themes/clean-theme.d.ts +0 -5
@@ -0,0 +1 @@
1
+ import { z } from "zod";
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ //#region ../protocol/dist/board-animation.js
3
+ const extensionKindSchema = z.string().regex(/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/).max(160);
4
+ const jsonObjectSchema = z.record(z.string(), z.unknown());
5
+ const finiteSchema = z.number().finite();
6
+ /** Parameters shared by the built-in deal entrance preset. */
7
+ const BoardDealParamsSchema = z.object({
8
+ lift: finiteSchema.nonnegative().max(2e3).optional(),
9
+ swing: finiteSchema.nonnegative().max(2e3).optional(),
10
+ curve: finiteSchema.nonnegative().max(2e3).optional(),
11
+ tilt: finiteSchema.nonnegative().max(180).optional(),
12
+ scale: finiteSchema.positive().max(2).optional(),
13
+ duration: finiteSchema.positive().max(1e4).optional(),
14
+ landing: finiteSchema.nonnegative().max(1e4).optional()
15
+ }).strict();
16
+ /** A versioned, reusable animation preset reference. */
17
+ const BoardAnimationSpecSchema = z.object({
18
+ kind: extensionKindSchema,
19
+ kindVersion: z.number().int().positive().default(1),
20
+ params: jsonObjectSchema.default({})
21
+ }).strict().superRefine((spec, context) => {
22
+ if (spec.kind !== "effects.deal" || spec.kindVersion !== 1) return;
23
+ const parsed = BoardDealParamsSchema.safeParse(spec.params);
24
+ if (parsed.success) return;
25
+ context.addIssue({
26
+ code: "custom",
27
+ message: parsed.error.issues[0]?.message ?? "invalid effects.deal parameters",
28
+ path: ["params", ...parsed.error.issues[0]?.path ?? []]
29
+ });
30
+ });
31
+ /** Board-wide default motion policies. Omitted policies mean no motion. */
32
+ const BoardMotionSchema = z.object({ enter: BoardAnimationSpecSchema.optional() }).strict();
33
+ //#endregion
34
+ export { BoardAnimationSpecSchema, BoardDealParamsSchema, BoardMotionSchema };
@@ -1140,10 +1140,11 @@ declare const BoardSemanticCommandSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1140
1140
  type: z.ZodLiteral<"board">;
1141
1141
  }, z.core.$strict>], "type">;
1142
1142
  kind: z.ZodString;
1143
- kindVersion: z.ZodNumber;
1143
+ kindVersion: z.ZodDefault<z.ZodNumber>;
1144
1144
  enabled: z.ZodDefault<z.ZodBoolean>;
1145
1145
  lifecycle: z.ZodEnum<{
1146
1146
  manual: "manual";
1147
+ "on-enter": "on-enter";
1147
1148
  persistent: "persistent";
1148
1149
  "when-visible": "when-visible";
1149
1150
  }>;
@@ -1,8 +1,17 @@
1
- import { BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, DEFAULT_BOARD_RENDER_LIMITS } from "./board-constants.js";
1
+ import { BOARD_BUILTIN_CAPABILITIES, BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, DEFAULT_BOARD_RENDER_LIMITS } from "./board-constants.js";
2
2
  import { BoardCameraFocusParamsSchema } from "./board.js";
3
+ import { BoardDealParamsSchema } from "./board-animation.js";
3
4
  //#region ../protocol/dist/board-capability-registry.js
4
5
  const CLIPS = new Set(BOARD_BUILTIN_CLIP_KINDS);
5
- new Set(BOARD_BUILTIN_EFFECT_KINDS);
6
+ const EFFECTS = new Set(BOARD_BUILTIN_EFFECT_KINDS);
7
+ const BUILTIN_VERSIONS = new Set(BOARD_BUILTIN_CAPABILITIES.map((c) => `${c.kind}:${c.id}@${c.version}`));
8
+ /**
9
+ * True when a built-in renderer exists for exactly this kind@version. A known
10
+ * kind at an unknown version is not built-in: it must not pass as one.
11
+ */
12
+ function isBuiltinBoardCapability(kind, id, version) {
13
+ return BUILTIN_VERSIONS.has(`${kind}:${id}@${version}`);
14
+ }
6
15
  const record = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
7
16
  const finite = (value) => typeof value === "number" && Number.isFinite(value);
8
17
  function validateBuiltinBoardClip(clip, path = "clip") {
@@ -36,6 +45,47 @@ function validateBuiltinBoardClip(clip, path = "clip") {
36
45
  }
37
46
  return errors;
38
47
  }
48
+ function validateBuiltinBoardEffect(effect, path = "effect") {
49
+ const diagnostics = [];
50
+ if (effect.lifecycle === "on-enter") {
51
+ if (effect.target.type !== "item") diagnostics.push({
52
+ severity: "error",
53
+ code: "INVALID_BOARD_EFFECT",
54
+ message: "on-enter effects must target an item",
55
+ path: `${path}.target`
56
+ });
57
+ if (effect.timeOrigin !== "activation") diagnostics.push({
58
+ severity: "error",
59
+ code: "INVALID_BOARD_EFFECT",
60
+ message: "on-enter effects must use activation time",
61
+ path: `${path}.timeOrigin`
62
+ });
63
+ } else if (EFFECTS.has(effect.kind) && effect.target.type !== "item") diagnostics.push({
64
+ severity: "error",
65
+ code: "INVALID_BOARD_EFFECT",
66
+ message: `${effect.kind} must target an item`,
67
+ path: `${path}.target`
68
+ });
69
+ if (effect.kind === "effects.deal" && effect.kindVersion === 1) {
70
+ if (effect.lifecycle !== "on-enter") diagnostics.push({
71
+ severity: "error",
72
+ code: "INVALID_BOARD_EFFECT",
73
+ message: "effects.deal must use the on-enter lifecycle",
74
+ path: `${path}.lifecycle`
75
+ });
76
+ const parsed = BoardDealParamsSchema.safeParse(effect.params);
77
+ if (!parsed.success) diagnostics.push({
78
+ severity: "error",
79
+ code: "INVALID_BOARD_EFFECT",
80
+ message: parsed.error.issues[0]?.message ?? "invalid effects.deal parameters",
81
+ path: `${path}.params`
82
+ });
83
+ }
84
+ return diagnostics;
85
+ }
86
+ function estimateBuiltinBoardEffectCost(effect) {
87
+ return isBuiltinBoardCapability("effect", effect.kind, effect.kindVersion) ? { drawCalls: 1 } : {};
88
+ }
39
89
  function estimateBuiltinBoardClipCost(clip) {
40
90
  switch (clip.kind) {
41
91
  case "effects.particles": {
@@ -70,4 +120,4 @@ function estimateBuiltinBoardClipCost(clip) {
70
120
  }
71
121
  }
72
122
  //#endregion
73
- export { estimateBuiltinBoardClipCost, validateBuiltinBoardClip };
123
+ export { estimateBuiltinBoardClipCost, estimateBuiltinBoardEffectCost, isBuiltinBoardCapability, validateBuiltinBoardClip, validateBuiltinBoardEffect };
@@ -1,6 +1,6 @@
1
1
  import { BoardAuthoringItemSchema, BoardItemPatchSchema } from "./board-authoring.js";
2
2
  import { BoardNodeInputSchema } from "./board.js";
3
- import { boardArrowFrame, boardDrawBounds, boardDrawPointsToLocal } from "./board-geometry.js";
3
+ import { boardArrowFrame, boardDrawBounds, boardDrawPointsToLocal, boardDrawPointsToWorld } from "./board-geometry.js";
4
4
  import { BOARD_NATIVE_NODE_TYPES, validateBoardNodeInput } from "./board-node.js";
5
5
  //#region ../protocol/dist/board-codec.js
6
6
  var BoardItemValidationError = class extends Error {
@@ -30,6 +30,153 @@ function authoringDiagnostic(diagnostic, path) {
30
30
  };
31
31
  }
32
32
  const isRecord = (value) => Boolean(value && typeof value === "object" && !Array.isArray(value));
33
+ function baseItem(node) {
34
+ return {
35
+ id: node.nodeId,
36
+ position: {
37
+ x: node.x,
38
+ y: node.y
39
+ },
40
+ size: {
41
+ width: node.width,
42
+ height: node.height
43
+ },
44
+ rotation: node.rotation,
45
+ ...node.parentId ? { parentId: node.parentId } : {},
46
+ ...node.data.locked === true ? { locked: true } : {},
47
+ ...isRecord(node.data.metadata) ? { metadata: node.data.metadata } : {}
48
+ };
49
+ }
50
+ function filePath(node) {
51
+ if (!node.refPath) throw new Error(`Board item ${node.nodeId} is missing its source path`);
52
+ return node.refPath;
53
+ }
54
+ function style(node) {
55
+ const value = {};
56
+ if (typeof node.data.color === "string") value.color = node.data.color;
57
+ if (typeof node.data.size === "number") value.strokeWidth = node.data.size;
58
+ if (typeof node.data.fillOpacity === "number") value.fillOpacity = node.data.fillOpacity;
59
+ return Object.keys(value).length ? value : void 0;
60
+ }
61
+ function boardNodeToAuthoringItem(node) {
62
+ const base = baseItem(node);
63
+ if (node.type === "draw" || node.type === "arrow") {
64
+ delete base.size;
65
+ delete base.position;
66
+ }
67
+ const visual = style(node);
68
+ let candidate;
69
+ switch (node.type) {
70
+ case "text":
71
+ candidate = {
72
+ ...base,
73
+ type: "text",
74
+ props: {
75
+ text: node.data.text ?? "",
76
+ fontSize: node.data.fontSize ?? 24
77
+ },
78
+ ...visual ? { style: visual } : {}
79
+ };
80
+ break;
81
+ case "geo":
82
+ candidate = {
83
+ ...base,
84
+ type: "geo",
85
+ props: {
86
+ shape: node.data.geo ?? "rectangle",
87
+ text: node.data.text ?? ""
88
+ },
89
+ ...visual ? { style: visual } : {}
90
+ };
91
+ break;
92
+ case "draw":
93
+ candidate = {
94
+ ...base,
95
+ type: "draw",
96
+ props: { points: Array.isArray(node.data.points) ? boardDrawPointsToWorld(node.data.points, node.x, node.y) : [] },
97
+ ...visual ? { style: visual } : {}
98
+ };
99
+ break;
100
+ case "arrow":
101
+ candidate = {
102
+ ...base,
103
+ type: "arrow",
104
+ props: {
105
+ start: node.data.start,
106
+ end: node.data.end,
107
+ bend: node.data.bend ?? 0,
108
+ arrowStart: node.data.arrowStart ?? false,
109
+ arrowEnd: node.data.arrowEnd ?? true,
110
+ label: node.data.label ?? ""
111
+ },
112
+ ...visual ? { style: visual } : {}
113
+ };
114
+ break;
115
+ case "frame":
116
+ candidate = {
117
+ ...base,
118
+ type: "frame",
119
+ props: { label: node.data.label ?? "Frame" },
120
+ ...visual ? { style: visual } : {}
121
+ };
122
+ break;
123
+ case "image":
124
+ candidate = {
125
+ ...base,
126
+ type: "image",
127
+ props: isRecord(node.data.crop) ? { crop: node.data.crop } : {},
128
+ source: {
129
+ kind: "space-file",
130
+ path: filePath(node),
131
+ ...Object.keys(node.view).length ? { snapshot: node.view } : {}
132
+ }
133
+ };
134
+ break;
135
+ case "video":
136
+ case "audio":
137
+ case "file":
138
+ candidate = {
139
+ ...base,
140
+ type: node.type,
141
+ props: {},
142
+ source: {
143
+ kind: "space-file",
144
+ path: filePath(node),
145
+ ...Object.keys(node.view).length ? { snapshot: node.view } : {}
146
+ }
147
+ };
148
+ break;
149
+ case "task":
150
+ candidate = {
151
+ ...base,
152
+ type: "task",
153
+ props: {
154
+ taskRunId: node.data.taskRunId,
155
+ snapshot: node.view
156
+ }
157
+ };
158
+ break;
159
+ default: {
160
+ const props = { ...node.data };
161
+ delete props.locked;
162
+ delete props.metadata;
163
+ delete props.kindVersion;
164
+ candidate = {
165
+ ...base,
166
+ type: node.type,
167
+ kindVersion: typeof node.data.kindVersion === "number" ? node.data.kindVersion : 1,
168
+ props,
169
+ ...Object.keys(node.style).length ? { style: node.style } : {},
170
+ ...node.refPath ? { source: {
171
+ kind: node.refKind ?? "space-file",
172
+ ref: node.refPath,
173
+ ...Object.keys(node.view).length ? { snapshot: node.view } : {}
174
+ } } : {}
175
+ };
176
+ }
177
+ }
178
+ return BoardAuthoringItemSchema.parse(candidate);
179
+ }
33
180
  function commonData(item) {
34
181
  return {
35
182
  ...item.locked ? { locked: true } : {},
@@ -233,4 +380,4 @@ function mergePatch(current, patch) {
233
380
  return result;
234
381
  }
235
382
  //#endregion
236
- export { BoardItemValidationError, applyBoardItemPatch, authoringSchemaDiagnostics, boardAuthoringItemToNode };
383
+ export { BoardItemValidationError, applyBoardItemPatch, authoringSchemaDiagnostics, boardAuthoringItemToNode, boardNodeToAuthoringItem };
@@ -21,7 +21,11 @@ const BOARD_BUILTIN_CLIP_KINDS = [
21
21
  "camera.focus",
22
22
  "camera.shake"
23
23
  ];
24
- const BOARD_BUILTIN_EFFECT_KINDS = ["effects.pulse", "effects.float"];
24
+ const BOARD_BUILTIN_EFFECT_KINDS = [
25
+ "effects.pulse",
26
+ "effects.float",
27
+ "effects.deal"
28
+ ];
25
29
  /**
26
30
  * World-space typography for board text.
27
31
  *
@@ -85,6 +89,20 @@ function clipSchema(id) {
85
89
  default: return;
86
90
  }
87
91
  }
92
+ function effectSchema(id) {
93
+ switch (id) {
94
+ case "effects.deal": return { params: {
95
+ lift: { unit: "board" },
96
+ swing: { unit: "board" },
97
+ curve: { unit: "board" },
98
+ tilt: { unit: "degree" },
99
+ scale: { unit: "ratio" },
100
+ duration: { unit: "ms" },
101
+ landing: { unit: "ms" }
102
+ } };
103
+ default: return;
104
+ }
105
+ }
88
106
  const BOARD_BUILTIN_CAPABILITIES = [...BOARD_BUILTIN_CLIP_KINDS.map((id) => {
89
107
  const schema = clipSchema(id);
90
108
  return {
@@ -94,11 +112,15 @@ const BOARD_BUILTIN_CAPABILITIES = [...BOARD_BUILTIN_CLIP_KINDS.map((id) => {
94
112
  renderers: ["webgpu", "webgl"],
95
113
  ...schema ? { schema } : {}
96
114
  };
97
- }), ...BOARD_BUILTIN_EFFECT_KINDS.map((id) => ({
98
- kind: "effect",
99
- id,
100
- version: 1,
101
- renderers: ["webgpu", "webgl"]
102
- }))];
115
+ }), ...BOARD_BUILTIN_EFFECT_KINDS.map((id) => {
116
+ const schema = effectSchema(id);
117
+ return {
118
+ kind: "effect",
119
+ id,
120
+ version: 1,
121
+ renderers: ["webgpu", "webgl"],
122
+ ...schema ? { schema } : {}
123
+ };
124
+ })];
103
125
  //#endregion
104
126
  export { BOARD_ARROW_STROKE_SIZE, BOARD_BUILTIN_CAPABILITIES, BOARD_BUILTIN_CLIP_KINDS, BOARD_BUILTIN_EFFECT_KINDS, BOARD_CONNECTION_STROKE_SIZE, BOARD_FONT_STACK, BOARD_MONO_FONT_STACK, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BOARD_TEXT_FONT_FAMILY, DEFAULT_BOARD_RENDER_LIMITS, clampBoardStrokeSize };
@@ -21,7 +21,21 @@ declare const BoardViewportSchema: z.ZodObject<{
21
21
  zoom: z.ZodNumber;
22
22
  }, z.core.$strip>;
23
23
  declare const BoardAppearanceSchema: z.ZodObject<{
24
- theme: z.ZodDefault<z.ZodString>;
24
+ theme: z.ZodOptional<z.ZodString>;
25
+ motion: z.ZodOptional<z.ZodObject<{
26
+ enter: z.ZodOptional<z.ZodObject<{
27
+ kind: z.ZodString;
28
+ kindVersion: z.ZodDefault<z.ZodNumber>;
29
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
30
+ }, z.core.$strict>>;
31
+ }, z.core.$strict>>;
32
+ mood: z.ZodOptional<z.ZodEnum<{
33
+ arcane: "arcane";
34
+ clean: "clean";
35
+ cyber: "cyber";
36
+ natural: "natural";
37
+ playful: "playful";
38
+ }>>;
25
39
  background: z.ZodDefault<z.ZodObject<{
26
40
  kind: z.ZodDefault<z.ZodEnum<{
27
41
  custom: "custom";
@@ -52,13 +66,6 @@ declare const BoardAppearanceSchema: z.ZodObject<{
52
66
  size: z.ZodDefault<z.ZodNumber>;
53
67
  opacity: z.ZodDefault<z.ZodNumber>;
54
68
  }, z.core.$strip>>;
55
- mood: z.ZodDefault<z.ZodEnum<{
56
- arcane: "arcane";
57
- clean: "clean";
58
- cyber: "cyber";
59
- natural: "natural";
60
- playful: "playful";
61
- }>>;
62
69
  }, z.core.$strip>;
63
70
  /** Optional visual chrome still carried by a few older shapes. */
64
71
  declare const BoardItemStyleSchema: z.ZodObject<{
@@ -1046,7 +1053,21 @@ declare const BoardDocumentSchema: z.ZodObject<{
1046
1053
  kind: z.ZodLiteral<"cohub.board">;
1047
1054
  version: z.ZodLiteral<1>;
1048
1055
  appearance: z.ZodDefault<z.ZodObject<{
1049
- theme: z.ZodDefault<z.ZodString>;
1056
+ theme: z.ZodOptional<z.ZodString>;
1057
+ motion: z.ZodOptional<z.ZodObject<{
1058
+ enter: z.ZodOptional<z.ZodObject<{
1059
+ kind: z.ZodString;
1060
+ kindVersion: z.ZodDefault<z.ZodNumber>;
1061
+ params: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1062
+ }, z.core.$strict>>;
1063
+ }, z.core.$strict>>;
1064
+ mood: z.ZodOptional<z.ZodEnum<{
1065
+ arcane: "arcane";
1066
+ clean: "clean";
1067
+ cyber: "cyber";
1068
+ natural: "natural";
1069
+ playful: "playful";
1070
+ }>>;
1050
1071
  background: z.ZodDefault<z.ZodObject<{
1051
1072
  kind: z.ZodDefault<z.ZodEnum<{
1052
1073
  custom: "custom";
@@ -1077,13 +1098,6 @@ declare const BoardDocumentSchema: z.ZodObject<{
1077
1098
  size: z.ZodDefault<z.ZodNumber>;
1078
1099
  opacity: z.ZodDefault<z.ZodNumber>;
1079
1100
  }, z.core.$strip>>;
1080
- mood: z.ZodDefault<z.ZodEnum<{
1081
- arcane: "arcane";
1082
- clean: "clean";
1083
- cyber: "cyber";
1084
- natural: "natural";
1085
- playful: "playful";
1086
- }>>;
1087
1101
  }, z.core.$strip>>;
1088
1102
  viewport: z.ZodObject<{
1089
1103
  x: z.ZodNumber;
@@ -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 { BoardMotionSchema } from "./board-animation.js";
4
5
  import { BOARD_REMOTE_URL_MAX_LENGTH, BoardRemoteUrlSchema, isPublicBoardRemoteAddress, normalizeBoardRemoteUrl } from "./board-url.js";
5
6
  import { z } from "zod";
6
7
  //#region ../protocol/dist/board-document.js
@@ -23,7 +24,18 @@ const BoardViewportSchema = z.object({
23
24
  zoom: z.number().finite().min(.05).max(8)
24
25
  });
25
26
  const BoardAppearanceSchema = z.object({
26
- theme: z.string().min(1).default("clean"),
27
+ /** Legacy field retained when reading older Board documents; not used for rendering. */
28
+ theme: z.string().min(1).optional(),
29
+ /** Board-wide motion policies. Omitted policies mean no motion. */
30
+ motion: BoardMotionSchema.optional(),
31
+ /** Legacy field retained when reading older Board documents; not used for rendering. */
32
+ mood: z.enum([
33
+ "clean",
34
+ "playful",
35
+ "arcane",
36
+ "cyber",
37
+ "natural"
38
+ ]).optional(),
27
39
  background: z.object({
28
40
  kind: z.enum([
29
41
  "solid",
@@ -57,14 +69,7 @@ const BoardAppearanceSchema = z.object({
57
69
  visible: false,
58
70
  size: 24,
59
71
  opacity: .12
60
- }),
61
- mood: z.enum([
62
- "clean",
63
- "playful",
64
- "arcane",
65
- "cyber",
66
- "natural"
67
- ]).default("clean")
72
+ })
68
73
  });
69
74
  /** Optional visual chrome still carried by a few older shapes. */
70
75
  const BoardItemStyleSchema = z.object({
@@ -390,14 +395,12 @@ const BoardDocumentSchema = z.object({
390
395
  kind: z.literal(BOARD_DOCUMENT_KIND),
391
396
  version: z.literal(1),
392
397
  appearance: BoardAppearanceSchema.default({
393
- theme: "clean",
394
398
  background: { kind: "solid" },
395
399
  grid: {
396
400
  visible: false,
397
401
  size: 24,
398
402
  opacity: .12
399
- },
400
- mood: "clean"
403
+ }
401
404
  }),
402
405
  viewport: BoardViewportSchema,
403
406
  items: z.array(BoardItemSchema),
@@ -18,10 +18,11 @@ declare const BoardEffectSchema: z.ZodObject<{
18
18
  type: z.ZodLiteral<"board">;
19
19
  }, z.core.$strict>], "type">;
20
20
  kind: z.ZodString;
21
- kindVersion: z.ZodNumber;
21
+ kindVersion: z.ZodDefault<z.ZodNumber>;
22
22
  enabled: z.ZodDefault<z.ZodBoolean>;
23
23
  lifecycle: z.ZodEnum<{
24
24
  manual: "manual";
25
+ "on-enter": "on-enter";
25
26
  persistent: "persistent";
26
27
  "when-visible": "when-visible";
27
28
  }>;
@@ -60,10 +61,11 @@ declare const BoardEffectInputSchema: z.ZodObject<{
60
61
  type: z.ZodLiteral<"board">;
61
62
  }, z.core.$strict>], "type">;
62
63
  kind: z.ZodString;
63
- kindVersion: z.ZodNumber;
64
+ kindVersion: z.ZodDefault<z.ZodNumber>;
64
65
  enabled: z.ZodDefault<z.ZodBoolean>;
65
66
  lifecycle: z.ZodEnum<{
66
67
  manual: "manual";
68
+ "on-enter": "on-enter";
67
69
  persistent: "persistent";
68
70
  "when-visible": "when-visible";
69
71
  }>;
@@ -21,12 +21,13 @@ const BoardEffectSchema = z.object({
21
21
  itemId: idSchema
22
22
  }).strict(), z.object({ type: z.literal("board") }).strict()]),
23
23
  kind: extensionIdSchema,
24
- kindVersion: z.number().int().positive(),
24
+ kindVersion: z.number().int().positive().default(1),
25
25
  enabled: z.boolean().default(true),
26
26
  lifecycle: z.enum([
27
27
  "persistent",
28
28
  "when-visible",
29
- "manual"
29
+ "manual",
30
+ "on-enter"
30
31
  ]),
31
32
  timeOrigin: z.enum([
32
33
  "board",