@vibevibes/sdk 0.2.0 → 0.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.
package/dist/index.d.cts CHANGED
@@ -1,46 +1,23 @@
1
- import React$1 from 'react';
1
+ import React from 'react';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
5
- * Experience SDK Types - Simplified state sync
5
+ * Experience SDK Types
6
6
  */
7
7
 
8
8
  type ToolRisk = "low" | "medium" | "high";
9
- /**
10
- * Netcode mode declaration — experiences declare their sync strategy.
11
- * The runtime picks the right optimizations automatically.
12
- */
13
- type NetcodeMode = "default" | "tick" | "p2p-ephemeral";
14
- /**
15
- * JSON Patch operation (RFC 6902 subset).
16
- */
17
- type JsonPatchOp = {
18
- op: "add" | "remove" | "replace";
19
- path: string;
20
- value?: any;
21
- };
22
- type ExperienceImport = {
23
- experienceId: string;
24
- tools: string[] | '*';
25
- prefix?: string;
26
- };
27
- /**
28
- * Event emitted after a tool executes (used by typed event subscriptions).
29
- */
9
+ type CallToolFn = (name: string, input: Record<string, unknown>) => Promise<unknown>;
10
+ type ZodFactory = typeof z;
30
11
  type ToolEvent = {
31
12
  id: string;
32
13
  ts: number;
33
14
  actorId: string;
34
15
  owner?: string;
35
16
  tool: string;
36
- input: any;
37
- output?: any;
17
+ input: Record<string, unknown>;
18
+ output?: unknown;
38
19
  error?: string;
39
20
  };
40
- /**
41
- * Agent slot definition for multi-agent rooms.
42
- * Experience authors define named agent roles with system prompts and tool restrictions.
43
- */
44
21
  type AgentSlot = {
45
22
  role: string;
46
23
  systemPrompt: string;
@@ -48,74 +25,42 @@ type AgentSlot = {
48
25
  autoSpawn?: boolean;
49
26
  maxInstances?: number;
50
27
  };
28
+ type ParticipantSlot = {
29
+ role: string;
30
+ type?: "human" | "ai" | "any";
31
+ systemPrompt?: string;
32
+ allowedTools?: string[];
33
+ autoSpawn?: boolean;
34
+ maxInstances?: number;
35
+ };
36
+ type ParticipantDetail = {
37
+ actorId: string;
38
+ type: "human" | "ai" | "unknown";
39
+ role?: string;
40
+ metadata?: Record<string, string>;
41
+ };
51
42
  type ExperienceManifest = {
52
43
  id: string;
53
44
  version: string;
54
45
  title: string;
55
46
  description: string;
56
47
  requested_capabilities: string[];
57
- imports?: ExperienceImport[];
58
48
  agentSlots?: AgentSlot[];
49
+ participantSlots?: ParticipantSlot[];
59
50
  category?: string;
60
51
  tags?: string[];
61
- /** Sync strategy: 'default' | 'tick' | 'p2p-ephemeral'. Default: 'default'. */
62
- netcode?: NetcodeMode;
63
- /** For 'tick' netcode: server tick interval in ms (e.g. 50 = 20Hz). */
52
+ netcode?: "default" | "tick" | "p2p-ephemeral";
64
53
  tickRateMs?: number;
65
- /** State keys routed through fast ephemeral channel (no tool gate). */
66
54
  hotKeys?: string[];
67
55
  };
68
- /**
69
- * Room configuration schema + metadata.
70
- *
71
- * Experience authors declare what values a room accepts when spawned.
72
- * Each room becomes an instance of the experience with a specific config.
73
- * Think of it as: experience = game engine, config = level parameters.
74
- *
75
- * Example:
76
- * roomConfig: defineRoomConfig({
77
- * schema: z.object({
78
- * mode: z.enum(["combat", "explore", "dialogue"]).describe("Room game mode"),
79
- * difficulty: z.number().min(1).max(10).default(5).describe("Difficulty level"),
80
- * theme: z.string().default("forest").describe("Visual theme"),
81
- * }),
82
- * defaults: { mode: "explore", difficulty: 5, theme: "forest" },
83
- * presets: {
84
- * "boss-fight": { mode: "combat", difficulty: 10, theme: "volcano" },
85
- * "peaceful": { mode: "explore", difficulty: 1, theme: "meadow" },
86
- * },
87
- * })
88
- */
89
- type RoomConfigDef<TConfig extends Record<string, any> = Record<string, any>> = {
90
- /** Zod schema defining the config shape. Used for validation + JSON schema generation. */
91
- schema: z.ZodTypeAny;
92
- /** Default config values for rooms that don't specify config at spawn time. */
93
- defaults?: Partial<TConfig>;
94
- /** Named presets: quick ways to spawn rooms with predefined configs. */
95
- presets?: Record<string, TConfig>;
96
- /** Human-readable description of what this config controls. */
97
- description?: string;
98
- };
99
- /** Stream definition for high-frequency continuous state updates.
100
- * Bypasses the full tool handler pipeline but still validates and persists to state. */
101
56
  type StreamDef<TInput = any> = {
102
57
  name: string;
103
58
  description?: string;
104
59
  input_schema: z.ZodTypeAny;
105
- /** Pure merge function: takes current state, stream input, and actorId, returns new state. */
106
60
  merge: (state: Record<string, any>, input: TInput, actorId: string) => Record<string, any>;
107
- /** Max inputs per second per actor (server-enforced). Default: 60. */
108
61
  rateLimit?: number;
109
62
  };
110
- /**
111
- * Simplified Tool Context (no yjs, no events array)
112
- *
113
- * Use the generic parameter for typed state:
114
- * handler: async (ctx: ToolCtx<{ count: number }>, input) => {
115
- * const current = ctx.state.count; // typed
116
- * }
117
- */
118
- type ToolCtx<TState extends Record<string, any> = Record<string, any>, TConfig extends Record<string, any> = Record<string, any>> = {
63
+ type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
119
64
  roomId: string;
120
65
  actorId: string;
121
66
  owner?: string;
@@ -124,22 +69,6 @@ type ToolCtx<TState extends Record<string, any> = Record<string, any>, TConfig e
124
69
  timestamp: number;
125
70
  memory: Record<string, any>;
126
71
  setMemory: (updates: Record<string, any>) => void;
127
- /**
128
- * This room's config values. Set at spawn time, immutable after creation.
129
- * Allows tools to behave differently based on the room's modality.
130
- * e.g. `ctx.roomConfig.mode === "combat"` to branch tool behavior.
131
- */
132
- roomConfig: TConfig;
133
- /**
134
- * Spawn a child room with a specified experience.
135
- * Only available when manifest declares "room.spawn" in requested_capabilities.
136
- * Rate limited to 5 spawns per room per 5 minutes.
137
- */
138
- spawnRoom?: (opts: SpawnRoomOpts) => Promise<SpawnRoomResult>;
139
- /** Store a binary blob (pixel buffers, audio, etc). Returns the blob key. */
140
- setBlob?: (key: string, data: ArrayBuffer) => string;
141
- /** Retrieve a binary blob by key. */
142
- getBlob?: (key: string) => ArrayBuffer | undefined;
143
72
  };
144
73
  type ToolDef<TInput = any, TOutput = any> = {
145
74
  name: string;
@@ -150,74 +79,34 @@ type ToolDef<TInput = any, TOutput = any> = {
150
79
  handler: (ctx: ToolCtx, input: TInput) => Promise<TOutput>;
151
80
  emits?: string[];
152
81
  on?: Record<string, (ctx: ToolCtx, event: ToolEvent) => Promise<void>>;
153
- /**
154
- * If false, skip persisting state + event to DB after execution.
155
- * State is still broadcast to clients. Use for high-frequency tools
156
- * like cursor moves, animations, etc. Default: true.
157
- */
158
82
  persist?: boolean;
159
83
  };
160
- /**
161
- * Simplified Canvas Props - Hybrid State Model
162
- *
163
- * Use the generic parameter for typed sharedState:
164
- * const Canvas: React.FC<CanvasProps<{ count: number }>> = ({ sharedState }) => {
165
- * const count = sharedState.count; // fully typed
166
- * };
167
- */
168
- type CanvasProps<TState extends Record<string, any> = Record<string, any>, TConfig extends Record<string, any> = Record<string, any>> = {
169
- roomId: string;
84
+ type CanvasProps<TState extends Record<string, any> = Record<string, any>> = {
170
85
  actorId: string;
171
86
  sharedState: TState;
172
- callTool: (name: string, input: any, predictFn?: (state: TState) => TState) => Promise<any>;
173
- /** Batch multiple tool calls in a single round-trip. */
87
+ callTool: (name: string, input: Record<string, unknown>, predictFn?: (state: TState) => TState) => Promise<unknown>;
174
88
  callTools?: (calls: Array<{
175
89
  name: string;
176
- input: any;
177
- }>) => Promise<any[]>;
90
+ input: Record<string, unknown>;
91
+ }>) => Promise<unknown[]>;
178
92
  ephemeralState: Record<string, Record<string, any>>;
179
93
  setEphemeral: (data: Record<string, any>) => void;
180
- /** Fire a client-authoritative action via Broadcast (no tool gate, no persistence). */
181
- dispatchEphemeralAction?: (name: string, input: any) => void;
182
- /** Subscribe to ephemeral actions from other participants. */
183
- onEphemeralAction?: (handler: (action: {
184
- name: string;
185
- input: any;
186
- actorId: string;
187
- ts: number;
188
- }) => void) => () => void;
189
- /** Send high-frequency continuous input via WebSocket stream. Bypasses tool gate. */
190
- stream?: (name: string, input: any) => void;
94
+ stream?: (name: string, input: Record<string, unknown>) => void;
191
95
  participants: string[];
192
- /**
193
- * This room's config values, set at spawn time.
194
- * Use this to adapt the UI based on the room's modality.
195
- * e.g. render a combat UI vs exploration UI based on `roomConfig.mode`.
196
- */
197
- roomConfig: TConfig;
96
+ participantDetails?: ParticipantDetail[];
97
+ role?: "spectator" | "player";
198
98
  };
199
- /**
200
- * Assertion chain returned by `expect()` in test helpers.
201
- */
202
99
  type ExpectChain<T> = {
203
100
  toBe: (expected: T) => void;
204
- toEqual: (expected: any) => void;
101
+ toEqual: (expected: unknown) => void;
205
102
  toBeTruthy: () => void;
206
103
  toBeFalsy: () => void;
207
- toContain: (item: any) => void;
208
- toHaveProperty: (key: string, value?: any) => void;
104
+ toContain: (item: unknown) => void;
105
+ toHaveProperty: (key: string, value?: unknown) => void;
106
+ toBeGreaterThan: (expected: number) => void;
107
+ toBeLessThan: (expected: number) => void;
209
108
  not: ExpectChain<T>;
210
109
  };
211
- /**
212
- * Helpers injected into each test's `run` function.
213
- *
214
- * - `tool(name)` looks up a tool from the experience's tools array
215
- * - `ctx(opts?)` creates a mock ToolCtx; call `getState()` after mutations
216
- * - `expect(actual)` returns an assertion chain for type-safe assertions
217
- * - `snapshot(label, value)` stores/compares values within a test session
218
- *
219
- * Tests signal failure by throwing. If `run` resolves, the test passed.
220
- */
221
110
  type TestHelpers = {
222
111
  tool: (name: string) => ToolDef;
223
112
  ctx: (opts?: {
@@ -225,189 +114,36 @@ type TestHelpers = {
225
114
  actorId?: string;
226
115
  roomId?: string;
227
116
  owner?: string;
228
- roomConfig?: Record<string, any>;
229
117
  }) => ToolCtx & {
230
118
  getState: () => Record<string, any>;
231
119
  };
232
120
  expect: <T>(actual: T) => ExpectChain<T>;
233
- snapshot: (label: string, value: any) => void;
121
+ snapshot: (label: string, value: unknown) => void;
122
+ observe: (state: Record<string, any>, actorId?: string) => Record<string, any>;
123
+ agentSlots: () => Array<{
124
+ role: string;
125
+ systemPrompt?: string;
126
+ allowedTools?: string[];
127
+ [k: string]: unknown;
128
+ }>;
234
129
  };
235
- /**
236
- * Inline test for experience tool handlers.
237
- * Throw to fail; resolve to pass.
238
- */
239
130
  type TestDef = {
240
131
  name: string;
241
132
  run: (helpers: TestHelpers) => Promise<void>;
242
133
  };
243
- /**
244
- * Combined context for the agent's Stop hook.
245
- * Returned by the /agent-context endpoint — everything the agent needs
246
- * to decide what to do next in a single HTTP call.
247
- */
248
- type AgentContext = {
249
- events: ToolEvent[];
250
- observation: Record<string, any>;
251
- participants: string[];
252
- sharedState: Record<string, any>;
253
- };
254
- /**
255
- * Client-authoritative action that bypasses the tool gate entirely.
256
- * Goes through Supabase Broadcast directly — no persistence, no server validation.
257
- * Use for cursor positions, hover states, drag previews, etc.
258
- */
259
- type EphemeralActionDef = {
260
- name: string;
261
- description: string;
262
- input_schema: z.ZodTypeAny;
263
- };
264
- /**
265
- * Performance metrics exposed by the room sync system.
266
- */
267
- type PerfMetrics = {
268
- toolCallRtts: number[];
269
- broadcastLatencies: number[];
270
- stateSize: number;
271
- rendersPerSecond: number;
272
- pendingOptimistic: number;
273
- };
274
- /**
275
- * Follow protocol: allows participants to "follow" another user's viewport/actions.
276
- * Stored in ephemeral state under the `_follow` key.
277
- */
278
- type FollowState = {
279
- targetActorId: string;
280
- mode: 'viewport' | 'actions' | 'both';
281
- since: number;
282
- };
283
- /**
284
- * Multi-agent message for negotiation protocol.
285
- * Agents communicate through shared state under the `_agentMessages` key.
286
- */
287
- type AgentMessage = {
288
- id: string;
289
- from: string;
290
- to: string | '*';
291
- type: 'proposal' | 'vote' | 'delegate' | 'inform' | 'request';
292
- content: string;
293
- data?: Record<string, any>;
294
- ts: number;
295
- ttl?: number;
296
- };
297
- /**
298
- * State migration function for experience versioning.
299
- * Called when a room's experience version changes.
300
- */
301
- type StateMigration = {
302
- from: string;
303
- to: string;
304
- migrate: (oldState: Record<string, any>) => Record<string, any>;
305
- };
306
- /**
307
- * Webhook event types that can be filtered.
308
- */
309
- type WebhookEventType = 'tool.executed' | 'tool.error' | 'participant.joined' | 'participant.left' | 'state.changed' | 'room.created' | 'room.reset';
310
- /**
311
- * Options for spawning a child room from a tool handler.
312
- * Requires "room.spawn" in manifest.requested_capabilities.
313
- */
314
- type SpawnRoomOpts = {
315
- experienceId: string;
316
- name?: string;
317
- initialState?: Record<string, any>;
318
- /** If true, store parent roomId in child state as _parentRoom */
319
- linkBack?: boolean;
320
- /**
321
- * Config values for the new room. Validated against the experience's roomConfig schema.
322
- * If a preset name is given as a string, the preset's config is used.
323
- * If omitted, the experience's default config is applied.
324
- */
325
- config?: Record<string, any> | string;
326
- };
327
- type SpawnRoomResult = {
328
- roomId: string;
329
- url: string;
330
- /** The resolved config applied to the spawned room. */
331
- config: Record<string, any>;
332
- };
333
- /**
334
- * A link between two rooms (parent/child relationship).
335
- */
336
- type RoomLink = {
337
- parentRoomId: string;
338
- childRoomId: string;
339
- linkType: 'spawned' | 'referenced' | 'forked';
340
- metadata?: Record<string, any>;
341
- createdAt: string;
342
- };
343
- /**
344
- * A single entry in the experience registry (vibevibes.registry.json).
345
- * Maps an experience ID to its source path for cross-experience room spawning.
346
- */
347
134
  type RegistryEntry = {
348
135
  path: string;
349
136
  };
350
- /**
351
- * Per-project experience registry format (vibevibes.registry.json).
352
- * Enables cross-experience room spawning by mapping experience IDs to source paths.
353
- */
354
137
  type ExperienceRegistry = {
355
138
  experiences: Record<string, RegistryEntry>;
356
139
  };
357
140
  type ExperienceModule = {
358
141
  manifest: ExperienceManifest;
359
- Canvas: React$1.FC<CanvasProps>;
142
+ Canvas: React.FC<CanvasProps>;
360
143
  tools: ToolDef[];
361
144
  tests?: TestDef[];
362
- /** Client-authoritative actions that bypass the tool gate. */
363
- ephemeralActions?: EphemeralActionDef[];
364
- /** State migrations for version upgrades. */
365
- migrations?: StateMigration[];
366
- /**
367
- * Zod schema for the shared state shape. Provides:
368
- * - Type safety: ctx.state and sharedState are typed throughout
369
- * - Runtime validation: tool mutations are validated against the schema
370
- * - Auto-generated initialState: defaults from the schema populate initial state
371
- * - Agent legibility: agents can inspect the schema to understand state shape
372
- *
373
- * Usage:
374
- * stateSchema: z.object({
375
- * count: z.number().default(0).describe("Current counter value"),
376
- * players: z.array(z.object({
377
- * name: z.string(),
378
- * score: z.number().default(0),
379
- * })).default([]).describe("Active players"),
380
- * phase: z.enum(["setup", "playing", "finished"]).default("setup"),
381
- * })
382
- *
383
- * If both stateSchema and initialState are provided, initialState takes
384
- * precedence but is validated against the schema at startup.
385
- */
386
145
  stateSchema?: z.ZodTypeAny;
387
- /**
388
- * Room configuration schema.
389
- * Declares what values each room instance accepts at spawn time.
390
- * Turns your experience into a configurable engine:
391
- * experience = engine, roomConfig = level/mode parameters.
392
- *
393
- * Example: A dungeon crawler where each room is a different biome:
394
- * roomConfig: defineRoomConfig({
395
- * schema: z.object({
396
- * biome: z.enum(["forest", "cave", "desert"]),
397
- * enemyDensity: z.number().min(0).max(1).default(0.5),
398
- * }),
399
- * presets: {
400
- * "dark-cave": { biome: "cave", enemyDensity: 0.8 },
401
- * "peaceful-forest": { biome: "forest", enemyDensity: 0.1 },
402
- * },
403
- * })
404
- */
405
- roomConfig?: RoomConfigDef;
406
- /** Stream definitions for high-frequency continuous state updates (brush strokes, sliders, dragging).
407
- * Bypasses the full tool handler pipeline but still validates and persists to state. */
408
146
  streams?: StreamDef[];
409
- /** Agent observation function. Computes a curated view of state for MCP agents.
410
- * Called after each tool execution. If not defined, agents see the full state. */
411
147
  observe?: (state: Record<string, any>, event: ToolEvent | null, actorId: string) => Record<string, any>;
412
148
  };
413
149
 
@@ -423,94 +159,6 @@ declare function defineTest(config: {
423
159
  name: string;
424
160
  run: TestDef["run"];
425
161
  }): TestDef;
426
- declare function defineEphemeralAction(config: {
427
- name: string;
428
- description: string;
429
- input_schema: z.ZodTypeAny;
430
- }): EphemeralActionDef;
431
- /**
432
- * Reduced-boilerplate tool definition.
433
- * Auto-derives defaults: risk="low", capabilities=["state.write"],
434
- * and spreads input into state if no handler is provided.
435
- *
436
- * Usage:
437
- * quickTool("counter.increment", "Add 1 to count", z.object({}), async (ctx) => {
438
- * ctx.setState({ ...ctx.state, count: (ctx.state.count ?? 0) + 1 });
439
- * })
440
- */
441
- declare function quickTool<TInput>(name: string, description: string, input_schema: z.ZodType<TInput>, handler: ToolDef<TInput, any>["handler"]): ToolDef<TInput, any>;
442
- /**
443
- * Pre-built tool that restores shared state to a previous snapshot.
444
- * Required for useUndo/useRedo to work. Add it to your tools array:
445
- *
446
- * tools: [...yourTools, undoTool(z)]
447
- */
448
- declare function undoTool(zod: any): ToolDef<{
449
- state: Record<string, any>;
450
- }, {
451
- restored: boolean;
452
- }>;
453
- /**
454
- * Pre-built tool for phase transitions. Required for usePhase to work.
455
- * Add it to your tools array:
456
- *
457
- * tools: [...yourTools, phaseTool(z)]
458
- *
459
- * Optionally pass the list of valid phases for validation:
460
- * phaseTool(z, ["setup", "playing", "scoring", "finished"])
461
- */
462
- declare function phaseTool(zod: any, validPhases?: readonly string[]): ToolDef<{
463
- phase: string;
464
- }, {
465
- phase: string;
466
- }>;
467
- /**
468
- * Define a room configuration schema.
469
- * Rooms spawned with this experience will be validated against this schema.
470
- *
471
- * Usage:
472
- * import { defineRoomConfig } from "@vibevibes/sdk";
473
- * import { z } from "zod";
474
- *
475
- * const roomConfig = defineRoomConfig({
476
- * schema: z.object({
477
- * mode: z.enum(["combat", "explore", "dialogue"]),
478
- * difficulty: z.number().min(1).max(10).default(5),
479
- * }),
480
- * defaults: { mode: "explore", difficulty: 5 },
481
- * presets: {
482
- * "boss-fight": { mode: "combat", difficulty: 10 },
483
- * "peaceful": { mode: "explore", difficulty: 1 },
484
- * },
485
- * description: "Configure the room's game mode and difficulty",
486
- * });
487
- */
488
- declare function defineRoomConfig<TConfig extends Record<string, any>>(config: RoomConfigDef<TConfig>): RoomConfigDef<TConfig>;
489
- /**
490
- * Define a continuous state stream for high-frequency human input.
491
- * Streams bypass the full tool handler pipeline but still validate input
492
- * and persist to shared state via a pure merge function.
493
- *
494
- * Usage:
495
- * import { defineStream } from "@vibevibes/sdk";
496
- * import { z } from "zod";
497
- *
498
- * const brushStream = defineStream({
499
- * name: "brush.stroke",
500
- * description: "Continuous brush stroke data",
501
- * input_schema: z.object({
502
- * x: z.number(),
503
- * y: z.number(),
504
- * pressure: z.number().min(0).max(1),
505
- * color: z.string(),
506
- * }),
507
- * merge: (state, input, actorId) => ({
508
- * ...state,
509
- * strokes: [...(state.strokes || []), { ...input, actorId, ts: Date.now() }],
510
- * }),
511
- * rateLimit: 60, // max 60 inputs/sec/actor
512
- * });
513
- */
514
162
  declare function defineStream<TInput>(config: {
515
163
  name: string;
516
164
  description?: string;
@@ -519,10 +167,7 @@ declare function defineStream<TInput>(config: {
519
167
  rateLimit?: number;
520
168
  }): StreamDef<TInput>;
521
169
  declare function defineExperience(module: ExperienceModule & {
522
- /** Initial state for the experience. If stateSchema is provided and initialState is not,
523
- * defaults are extracted from the schema automatically. */
524
170
  initialState?: Record<string, any>;
525
- /** Agent slot configurations. */
526
171
  agents?: Array<{
527
172
  role: string;
528
173
  systemPrompt: string;
@@ -530,1192 +175,23 @@ declare function defineExperience(module: ExperienceModule & {
530
175
  autoSpawn?: boolean;
531
176
  maxInstances?: number;
532
177
  }>;
533
- /** Display name (convenience, copied to manifest.title if manifest.title is missing). */
178
+ participants?: ParticipantSlot[];
534
179
  name?: string;
535
180
  }): ExperienceModule & {
536
181
  initialState?: Record<string, any>;
537
182
  };
538
- declare function validateExperience(module: ExperienceModule & {
539
- initialState?: Record<string, any>;
540
- }): {
541
- valid: boolean;
542
- errors: string[];
543
- warnings: string[];
544
- };
545
-
546
- /**
547
- * React hooks for experience authors.
548
- *
549
- * These hooks simplify common patterns in experience Canvas components:
550
- * - useToolCall: wraps callTool with loading/error state
551
- * - useSharedState: typed accessor for a specific state key
552
- * - useOptimisticTool: optimistic updates with rollback on error
553
- * - useParticipants: parsed participant list with structured data
554
- *
555
- * Hooks rely on React being available as a global (provided by the bundler runtime).
556
- */
557
- type CallToolFn$3 = (name: string, input: any) => Promise<any>;
558
- type UseToolCallReturn = {
559
- call: (name: string, input: any) => Promise<any>;
560
- loading: boolean;
561
- error: string | null;
562
- };
563
- /**
564
- * Wraps callTool with loading and error tracking.
565
- *
566
- * Usage:
567
- * const { call, loading, error } = useToolCall(callTool);
568
- * <button onClick={() => call('counter.increment', {})} disabled={loading}>
569
- */
570
- declare function useToolCall(callTool: CallToolFn$3): UseToolCallReturn;
571
- /**
572
- * Typed accessor for a specific key in shared state.
573
- *
574
- * Usage:
575
- * const count = useSharedState<number>(sharedState, 'count', 0);
576
- */
577
- declare function useSharedState<T>(sharedState: Record<string, any>, key: string, defaultValue?: T): T;
578
- type UseOptimisticToolReturn = {
579
- call: (name: string, input: any, optimisticState: Record<string, any>) => Promise<any>;
580
- state: Record<string, any>;
581
- pending: boolean;
582
- };
583
- /**
584
- * Applies an optimistic state update immediately, then reverts on error.
585
- *
586
- * Usage:
587
- * const { call, state, pending } = useOptimisticTool(callTool, sharedState);
588
- * call('counter.increment', {}, { count: sharedState.count + 1 });
589
- */
590
- declare function useOptimisticTool(callTool: CallToolFn$3, sharedState: Record<string, any>): UseOptimisticToolReturn;
591
- /**
592
- * Decouples render frequency from state sync frequency.
593
- * State updates are buffered and applied at most once per animation frame.
594
- * Optional interpolation function smooths transitions between states.
595
- *
596
- * Usage:
597
- * const displayState = useAnimationFrame(sharedState);
598
- * // OR with interpolation:
599
- * const displayState = useAnimationFrame(sharedState, (prev, next, t) => ({
600
- * ...next,
601
- * x: prev.x + (next.x - prev.x) * t,
602
- * }));
603
- */
604
- declare function useAnimationFrame(sharedState: Record<string, any>, interpolate?: (prev: Record<string, any>, next: Record<string, any>, t: number) => Record<string, any>): Record<string, any>;
605
- type ParsedParticipant = {
606
- id: string;
607
- username: string;
608
- type: 'human' | 'ai' | 'unknown';
609
- index: number;
610
- };
611
- /**
612
- * Parses the participant ID list into structured objects.
613
- *
614
- * Participant IDs follow the format: {username}-{type}-{N}
615
- * e.g., "alice-human-1", "claude-ai-2"
616
- */
617
- declare function useParticipants(participants: string[]): ParsedParticipant[];
618
- type FollowMode = 'viewport' | 'actions' | 'both';
619
- type FollowData = {
620
- targetActorId: string;
621
- mode: FollowMode;
622
- since: number;
623
- };
624
- type EphemeralAction = {
625
- name: string;
626
- input: any;
627
- actorId: string;
628
- ts: number;
629
- };
630
- type DispatchEphemeralActionFn = (name: string, input: any) => void;
631
- type OnEphemeralActionFn = (handler: (action: EphemeralAction) => void) => () => void;
632
- type SetEphemeralFn = (data: Record<string, any>) => void;
633
- type UseFollowReturn = {
634
- /** Start following a target participant. */
635
- follow: (targetActorId: string, mode: FollowMode) => void;
636
- /** Stop following. */
637
- unfollow: () => void;
638
- /** Who you are currently following, or null. */
639
- following: FollowData | null;
640
- /** List of actor IDs that are following you. */
641
- followers: Array<{
642
- actorId: string;
643
- mode: FollowMode;
644
- since: number;
645
- }>;
646
- };
647
- /**
648
- * Manages follow-mode state via ephemeral presence.
649
- *
650
- * Stores follow intent in ephemeral state under `_follow` key and dispatches
651
- * `follow.started` / `follow.stopped` ephemeral actions to notify participants.
652
- *
653
- * Usage:
654
- * const { follow, unfollow, following, followers } = useFollow(
655
- * actorId, participants, ephemeralState, setEphemeral,
656
- * onEphemeralAction, dispatchEphemeralAction
657
- * );
658
- * follow('alice-human-1', 'viewport');
659
- */
660
- declare function useFollow(actorId: string, participants: string[], ephemeralState: Record<string, Record<string, any>>, setEphemeral: SetEphemeralFn, _onEphemeralAction?: OnEphemeralActionFn, dispatchEphemeralAction?: DispatchEphemeralActionFn): UseFollowReturn;
661
- /**
662
- * Manages typing/activity indicators via ephemeral state.
663
- *
664
- * Usage:
665
- * const { setTyping, typingUsers } = useTypingIndicator(actorId, ephemeralState, setEphemeral);
666
- *
667
- * // Call setTyping(true) when the user starts typing
668
- * // Call setTyping(false) when they stop (auto-clears after 3s)
669
- * // typingUsers is an array of actor IDs currently typing
670
- */
671
- declare function useTypingIndicator(actorId: string, ephemeralState: Record<string, Record<string, any>>, setEphemeral: (data: Record<string, any>) => void, timeoutMs?: number): {
672
- setTyping: (isTyping: boolean) => void;
673
- typingUsers: string[];
674
- };
675
- type UseUndoReturn = {
676
- /** Undo the last state change. No-op if nothing to undo. */
677
- undo: () => void;
678
- /** Redo the last undone state change. No-op if nothing to redo. */
679
- redo: () => void;
680
- /** Whether undo is available. */
681
- canUndo: boolean;
682
- /** Whether redo is available. */
683
- canRedo: boolean;
684
- /** Number of states in the undo stack. */
685
- undoCount: number;
686
- /** Number of states in the redo stack. */
687
- redoCount: number;
688
- };
689
- /**
690
- * Undo/redo for shared state via tool calls.
691
- *
692
- * Tracks state snapshots as sharedState changes. Undo/redo restore
693
- * previous/next snapshots by calling a tool (default: "_state.restore").
694
- *
695
- * The server needs a `_state.restore` tool registered (or pass a custom
696
- * restoreTool name). If the tool doesn't exist, undo triggers callTool
697
- * which will return an error — but it won't crash.
698
- *
699
- * Usage:
700
- * const { undo, redo, canUndo, canRedo } = useUndo(sharedState, callTool);
701
- * <button onClick={undo} disabled={!canUndo}>Undo</button>
702
- * <button onClick={redo} disabled={!canRedo}>Redo</button>
703
- */
704
- declare function useUndo(sharedState: Record<string, any>, callTool: CallToolFn$3, opts?: {
705
- maxHistory?: number;
706
- restoreTool?: string;
707
- }): UseUndoReturn;
708
- /**
709
- * Returns a debounced version of callTool. Calls are delayed by `delayMs`
710
- * and collapsed — only the last call within the window fires.
711
- *
712
- * Perfect for search inputs, text fields, sliders.
713
- *
714
- * Usage:
715
- * const debouncedCall = useDebounce(callTool, 300);
716
- * <input onChange={(e) => debouncedCall('search.update', { query: e.target.value })} />
717
- */
718
- declare function useDebounce(callTool: CallToolFn$3, delayMs?: number): CallToolFn$3;
719
- /**
720
- * Returns a throttled version of callTool. At most one call fires per
721
- * `intervalMs`. Trailing calls are queued and fire after the interval.
722
- *
723
- * Perfect for cursor positions, brush strokes, drag events.
724
- *
725
- * Usage:
726
- * const throttledCall = useThrottle(callTool, 50);
727
- * onMouseMove={(e) => throttledCall('cursor.move', { x: e.clientX, y: e.clientY })}
728
- */
729
- declare function useThrottle(callTool: CallToolFn$3, intervalMs?: number): CallToolFn$3;
730
- type PhaseConfig<TPhase extends string = string> = {
731
- /** Ordered list of phase names. */
732
- phases: readonly TPhase[];
733
- /** The state key that stores the current phase. Default: "phase". */
734
- stateKey?: string;
735
- /** Tool name for phase transitions. Default: "_phase.set". */
736
- toolName?: string;
737
- };
738
- type UsePhaseReturn<TPhase extends string = string> = {
739
- /** Current phase name. */
740
- current: TPhase;
741
- /** Index of current phase (0-based). */
742
- index: number;
743
- /** Whether current phase is the first. */
744
- isFirst: boolean;
745
- /** Whether current phase is the last. */
746
- isLast: boolean;
747
- /** Advance to the next phase. No-op if already last. */
748
- next: () => void;
749
- /** Go back to the previous phase. No-op if already first. */
750
- prev: () => void;
751
- /** Jump to a specific phase by name. */
752
- goTo: (phase: TPhase) => void;
753
- /** Check if the current phase matches. */
754
- is: (phase: TPhase) => boolean;
755
- };
756
- /**
757
- * Manages a linear phase/stage machine via shared state.
758
- *
759
- * Almost every experience has phases: setup → active → review,
760
- * ideate → cluster → prioritize, listen → improvise → refine.
761
- * This hook compresses that pattern into a one-liner.
762
- *
763
- * Usage:
764
- * const phase = usePhase(sharedState, callTool, {
765
- * phases: ["setup", "playing", "scoring", "finished"] as const,
766
- * });
767
- *
768
- * if (phase.is("setup")) return <SetupScreen />;
769
- * if (phase.is("playing")) return <GameBoard />;
770
- *
771
- * <button onClick={phase.next} disabled={phase.isLast}>Next Phase</button>
772
- *
773
- * Requires a tool to be registered (or use the built-in phaseTool):
774
- * tools: [...yourTools, phaseTool(z)]
775
- */
776
- declare function usePhase<TPhase extends string>(sharedState: Record<string, any>, callTool: CallToolFn$3, config: PhaseConfig<TPhase>): UsePhaseReturn<TPhase>;
777
- /**
778
- * Fetches and caches a binary blob from the server.
779
- * Returns the ArrayBuffer when loaded, null while loading.
780
- *
781
- * Usage:
782
- * const pixels = useBlob(sharedState.canvasBlobId);
783
- * if (pixels) { // render pixels }
784
- */
785
- declare function useBlob(blobKey: string | null | undefined, serverUrl?: string): ArrayBuffer | null;
786
-
787
- /**
788
- * Pre-built UI components for experiences.
789
- *
790
- * These components use inline styles (no Tailwind dependency) so they work
791
- * reliably inside bundled experience canvases. They provide sensible defaults
792
- * and can be overridden via the `style` prop.
793
- *
794
- * Usage in experiences:
795
- * import { Button, Card, Input, Badge, Stack, Grid } from "@vibevibes/experience-sdk";
796
- */
797
- type ButtonProps = {
798
- children?: any;
799
- onClick?: () => void;
800
- disabled?: boolean;
801
- variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
802
- size?: 'sm' | 'md' | 'lg';
803
- style?: Record<string, any>;
804
- };
805
- declare function Button({ children, onClick, disabled, variant, size, style }: ButtonProps): any;
806
- type CardProps = {
807
- children?: any;
808
- title?: string;
809
- style?: Record<string, any>;
810
- };
811
- declare function Card({ children, title, style }: CardProps): any;
812
- type InputProps = {
813
- value?: string;
814
- onChange?: (value: string) => void;
815
- placeholder?: string;
816
- type?: string;
817
- disabled?: boolean;
818
- style?: Record<string, any>;
819
- };
820
- declare function Input({ value, onChange, placeholder, type, disabled, style }: InputProps): any;
821
- type BadgeProps = {
822
- children?: any;
823
- color?: 'gray' | 'blue' | 'green' | 'red' | 'yellow' | 'purple';
824
- style?: Record<string, any>;
825
- };
826
- declare function Badge({ children, color, style }: BadgeProps): any;
827
- type StackProps = {
828
- children?: any;
829
- direction?: 'row' | 'column';
830
- gap?: string | number;
831
- align?: string;
832
- justify?: string;
833
- style?: Record<string, any>;
834
- };
835
- declare function Stack({ children, direction, gap, align, justify, style }: StackProps): any;
836
- type GridProps = {
837
- children?: any;
838
- columns?: number | string;
839
- gap?: string | number;
840
- style?: Record<string, any>;
841
- };
842
- declare function Grid({ children, columns, gap, style }: GridProps): any;
843
- type SliderProps = {
844
- value?: number;
845
- onChange?: (value: number) => void;
846
- min?: number;
847
- max?: number;
848
- step?: number;
849
- disabled?: boolean;
850
- label?: string;
851
- style?: Record<string, any>;
852
- };
853
- declare function Slider({ value, onChange, min, max, step, disabled, label, style }: SliderProps): any;
854
- type TextareaProps = {
855
- value?: string;
856
- onChange?: (value: string) => void;
857
- placeholder?: string;
858
- rows?: number;
859
- disabled?: boolean;
860
- style?: Record<string, any>;
861
- };
862
- declare function Textarea({ value, onChange, placeholder, rows, disabled, style }: TextareaProps): any;
863
- type ModalProps = {
864
- children?: any;
865
- open?: boolean;
866
- onClose?: () => void;
867
- title?: string;
868
- style?: Record<string, any>;
869
- };
870
- declare function Modal({ children, open, onClose, title, style }: ModalProps): any;
871
- type ColorPickerProps = {
872
- value?: string;
873
- onChange?: (color: string) => void;
874
- presets?: string[];
875
- disabled?: boolean;
876
- style?: Record<string, any>;
877
- };
878
- declare function ColorPicker({ value, onChange, presets, disabled, style }: ColorPickerProps): any;
879
- type DropdownProps = {
880
- value?: string;
881
- onChange?: (value: string) => void;
882
- options: Array<{
883
- value: string;
884
- label: string;
885
- }>;
886
- placeholder?: string;
887
- disabled?: boolean;
888
- style?: Record<string, any>;
889
- };
890
- declare function Dropdown({ value, onChange, options, placeholder, disabled, style }: DropdownProps): any;
891
- type TabsProps = {
892
- tabs: Array<{
893
- id: string;
894
- label: string;
895
- }>;
896
- activeTab?: string;
897
- onTabChange?: (id: string) => void;
898
- children?: any;
899
- style?: Record<string, any>;
900
- };
901
- declare function Tabs({ tabs, activeTab, onTabChange, children, style }: TabsProps): any;
902
-
903
- /**
904
- * Multi-agent negotiation protocol.
905
- * Provides pre-built tools for agent-to-agent communication.
906
- */
907
-
908
- declare function createAgentProtocolTools(namespace: string, z: any): ToolDef[];
909
-
910
- /**
911
- * State migration runner for experience versioning.
912
- *
913
- * Pure functions (no side effects, no async) so they can run in Edge Functions,
914
- * Node.js, or the browser.
915
- */
916
-
917
- interface MigrationResult {
918
- migrated: boolean;
919
- fromVersion: string;
920
- toVersion: string;
921
- state: Record<string, any>;
922
- }
923
- /**
924
- * Get the state version from a state object.
925
- * Stored in state._version, defaults to "0.0.0" if absent.
926
- */
927
- declare function getStateVersion(state: Record<string, any>): string;
928
- /**
929
- * Compare two semver strings.
930
- * Returns -1 if a < b, 0 if equal, 1 if a > b.
931
- *
932
- * Handles standard major.minor.patch format. Missing segments default to 0.
933
- */
934
- declare function compareSemver(a: string, b: string): number;
935
- /**
936
- * Run all applicable migrations on a state object.
937
- *
938
- * - Reads state._version (default "0.0.0") as the starting version
939
- * - Sorts migrations by their to version (ascending semver)
940
- * - Applies each migration where migration.to > stateVersion and migration.to <= currentVersion
941
- * - Sets state._version = currentVersion after all migrations
942
- * - Returns a MigrationResult indicating whether any migrations were applied
943
- *
944
- * The migration runner is pure: it does not mutate the input state object.
945
- * It returns a new state object with migrations applied.
946
- */
947
- declare function migrateState(state: Record<string, any>, migrations: StateMigration[], currentVersion: string): MigrationResult;
948
-
949
- /**
950
- * Storage adapter interface for vibe vibes
951
- * Allows multiple storage backends: in-memory, Supabase, GitHub, etc.
952
- */
953
- interface ExperienceListing {
954
- id: string;
955
- title: string;
956
- description: string;
957
- version: string;
958
- source: 'builtin' | 'github' | 'supabase';
959
- github_repo?: string;
960
- github_url?: string;
961
- }
962
- interface RoomState {
963
- roomId: string;
964
- experienceId: string;
965
- sharedState: Record<string, any>;
966
- updatedAt: number;
967
- }
968
- interface StorageToolEvent {
969
- id: string;
970
- ts: number;
971
- actor_id: string;
972
- tool: string;
973
- input: unknown;
974
- output: unknown;
975
- }
976
- /**
977
- * Storage adapter interface
978
- * All methods are async to support both local and remote storage
979
- */
980
- interface StorageAdapter {
981
- saveRoomState(roomId: string, state: RoomState): Promise<void>;
982
- loadRoomState(roomId: string): Promise<RoomState | null>;
983
- appendEvent(roomId: string, event: StorageToolEvent): Promise<void>;
984
- loadEvents(roomId: string, limit?: number): Promise<StorageToolEvent[]>;
985
- listExperiences(userId?: string): Promise<ExperienceListing[]>;
986
- saveUserProfile?(userId: string, profile: any): Promise<void>;
987
- loadUserProfile?(userId: string): Promise<any | null>;
988
- }
989
- /**
990
- * In-memory storage adapter
991
- * No persistence - data lost on restart
992
- * Perfect for local development and demos
993
- */
994
- declare class InMemoryAdapter implements StorageAdapter {
995
- private roomStates;
996
- private events;
997
- private profiles;
998
- saveRoomState(roomId: string, state: RoomState): Promise<void>;
999
- loadRoomState(roomId: string): Promise<RoomState | null>;
1000
- appendEvent(roomId: string, event: StorageToolEvent): Promise<void>;
1001
- loadEvents(roomId: string, limit?: number): Promise<StorageToolEvent[]>;
1002
- listExperiences(_userId?: string): Promise<ExperienceListing[]>;
1003
- saveUserProfile(userId: string, profile: any): Promise<void>;
1004
- loadUserProfile(userId: string): Promise<any | null>;
1005
- }
1006
183
 
1007
184
  /**
1008
- * Scene Graph Type Definitions
1009
- *
1010
- * The scene graph is a serializable JSON structure that lives in sharedState._scene.
1011
- * Both humans (via Canvas UI) and agents (via MCP tools) read and write this structure.
1012
- * The renderer reads it and produces SVG output.
1013
- *
1014
- * Every type here MUST be JSON-serializable (no functions, no class instances, no circular refs).
1015
- */
1016
- type Vec2 = {
1017
- x: number;
1018
- y: number;
1019
- };
1020
- type Transform = {
1021
- x?: number;
1022
- y?: number;
1023
- rotation?: number;
1024
- scaleX?: number;
1025
- scaleY?: number;
1026
- originX?: number;
1027
- originY?: number;
1028
- };
1029
- type GradientStop = {
1030
- offset: number;
1031
- color: string;
1032
- };
1033
- type LinearGradient = {
1034
- type: 'linear';
1035
- id: string;
1036
- x1: number;
1037
- y1: number;
1038
- x2: number;
1039
- y2: number;
1040
- stops: GradientStop[];
1041
- };
1042
- type RadialGradient = {
1043
- type: 'radial';
1044
- id: string;
1045
- cx: number;
1046
- cy: number;
1047
- r: number;
1048
- fx?: number;
1049
- fy?: number;
1050
- stops: GradientStop[];
1051
- };
1052
- type Gradient = LinearGradient | RadialGradient;
1053
- type FilterType = 'blur' | 'shadow' | 'glow' | 'brightness' | 'contrast' | 'saturate' | 'hue-rotate';
1054
- type FilterDef = {
1055
- id: string;
1056
- type: FilterType;
1057
- params: Record<string, number | string>;
1058
- };
1059
- type Style = {
1060
- fill?: string;
1061
- stroke?: string;
1062
- strokeWidth?: number;
1063
- strokeDasharray?: string;
1064
- strokeLinecap?: 'butt' | 'round' | 'square';
1065
- strokeLinejoin?: 'miter' | 'round' | 'bevel';
1066
- opacity?: number;
1067
- fillOpacity?: number;
1068
- strokeOpacity?: number;
1069
- filter?: string;
1070
- cursor?: string;
1071
- pointerEvents?: 'auto' | 'none';
1072
- visible?: boolean;
1073
- };
1074
- type TextStyle = Style & {
1075
- fontSize?: number;
1076
- fontFamily?: string;
1077
- fontWeight?: number | string;
1078
- textAnchor?: 'start' | 'middle' | 'end';
1079
- dominantBaseline?: 'auto' | 'middle' | 'hanging' | 'text-top';
1080
- letterSpacing?: number;
1081
- };
1082
- type SceneNodeBase = {
1083
- id: string;
1084
- name?: string;
1085
- transform?: Transform;
1086
- style?: Style;
1087
- interactive?: boolean;
1088
- data?: Record<string, any>;
1089
- tween?: TweenDef;
1090
- };
1091
- type RectNode = SceneNodeBase & {
1092
- type: 'rect';
1093
- width: number;
1094
- height: number;
1095
- rx?: number;
1096
- ry?: number;
1097
- };
1098
- type CircleNode = SceneNodeBase & {
1099
- type: 'circle';
1100
- radius: number;
1101
- };
1102
- type EllipseNode = SceneNodeBase & {
1103
- type: 'ellipse';
1104
- rx: number;
1105
- ry: number;
1106
- };
1107
- type LineNode = SceneNodeBase & {
1108
- type: 'line';
1109
- x2: number;
1110
- y2: number;
1111
- };
1112
- type PolylineNode = SceneNodeBase & {
1113
- type: 'polyline';
1114
- points: Vec2[];
1115
- };
1116
- type PolygonNode = SceneNodeBase & {
1117
- type: 'polygon';
1118
- points: Vec2[];
1119
- };
1120
- type PathNode = SceneNodeBase & {
1121
- type: 'path';
1122
- d: string;
1123
- };
1124
- type TextNode = SceneNodeBase & {
1125
- type: 'text';
1126
- text: string;
1127
- style?: TextStyle;
1128
- };
1129
- type ImageNode = SceneNodeBase & {
1130
- type: 'image';
1131
- href: string;
1132
- width: number;
1133
- height: number;
1134
- preserveAspectRatio?: string;
1135
- };
1136
- type GroupNode = SceneNodeBase & {
1137
- type: 'group';
1138
- children: SceneNode[];
1139
- clipPath?: string;
1140
- };
1141
- type SpriteAnimation = {
1142
- frames: number[];
1143
- fps: number;
1144
- loop?: boolean;
1145
- playing?: boolean;
1146
- };
1147
- type SpriteNode = SceneNodeBase & {
1148
- type: 'sprite';
1149
- href: string;
1150
- frameWidth: number;
1151
- frameHeight: number;
1152
- frame: number;
1153
- columns?: number;
1154
- animation?: SpriteAnimation;
1155
- };
1156
- type TilemapNode = SceneNodeBase & {
1157
- type: 'tilemap';
1158
- href: string;
1159
- tileWidth: number;
1160
- tileHeight: number;
1161
- columns: number;
1162
- data: number[][];
1163
- width: number;
1164
- height: number;
1165
- };
1166
- type ParticleEmitter = {
1167
- x: number;
1168
- y: number;
1169
- rate: number;
1170
- lifetime: number;
1171
- speed: {
1172
- min: number;
1173
- max: number;
1174
- };
1175
- direction: {
1176
- min: number;
1177
- max: number;
1178
- };
1179
- gravity?: number;
1180
- color?: string | string[];
1181
- size?: {
1182
- min: number;
1183
- max: number;
1184
- };
1185
- fadeOut?: boolean;
1186
- shape?: 'circle' | 'square';
1187
- };
1188
- type Particle = {
1189
- x: number;
1190
- y: number;
1191
- vx: number;
1192
- vy: number;
1193
- age: number;
1194
- lifetime: number;
1195
- size: number;
1196
- color: string;
1197
- };
1198
- type ParticlesNode = SceneNodeBase & {
1199
- type: 'particles';
1200
- emitters: ParticleEmitter[];
1201
- maxParticles?: number;
1202
- _particles?: Particle[];
1203
- };
1204
- type SceneNode = RectNode | CircleNode | EllipseNode | LineNode | PolylineNode | PolygonNode | PathNode | TextNode | ImageNode | GroupNode | SpriteNode | TilemapNode | ParticlesNode;
1205
- type SceneNodeType = SceneNode['type'];
1206
- type EasingType = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'ease-in-quad' | 'ease-out-quad' | 'ease-in-out-quad' | 'ease-in-cubic' | 'ease-out-cubic' | 'ease-in-out-cubic' | 'ease-in-elastic' | 'ease-out-elastic' | 'ease-in-bounce' | 'ease-out-bounce';
1207
- type TweenDef = {
1208
- property: string;
1209
- from: number;
1210
- to: number;
1211
- duration: number;
1212
- easing?: EasingType;
1213
- delay?: number;
1214
- repeat?: number;
1215
- yoyo?: boolean;
1216
- startedAt?: number;
1217
- };
1218
- type Camera = {
1219
- x: number;
1220
- y: number;
1221
- zoom: number;
1222
- rotation?: number;
1223
- bounds?: {
1224
- minX: number;
1225
- minY: number;
1226
- maxX: number;
1227
- maxY: number;
1228
- };
1229
- };
1230
- type SceneGraph = {
1231
- _sceneVersion?: number;
1232
- root: GroupNode;
1233
- camera?: Camera;
1234
- background?: string;
1235
- gradients?: Gradient[];
1236
- filters?: FilterDef[];
1237
- width?: number;
1238
- height?: number;
1239
- };
1240
- type SceneRendererProps = {
1241
- scene: SceneGraph;
1242
- width?: number;
1243
- height?: number;
1244
- className?: string;
1245
- style?: Record<string, any>;
1246
- onNodeClick?: (nodeId: string, event: {
1247
- x: number;
1248
- y: number;
1249
- }) => void;
1250
- onNodeHover?: (nodeId: string | null) => void;
1251
- onNodeDragStart?: (nodeId: string, pos: Vec2) => void;
1252
- onNodeDrag?: (nodeId: string, pos: Vec2) => void;
1253
- onNodeDragEnd?: (nodeId: string, pos: Vec2) => void;
1254
- onViewportClick?: (pos: Vec2) => void;
1255
- onViewportPan?: (delta: Vec2) => void;
1256
- onViewportZoom?: (zoom: number, center: Vec2) => void;
1257
- selectedNodeIds?: string[];
1258
- debug?: boolean;
1259
- };
1260
- type SceneHitEvent = {
1261
- nodeId: string;
1262
- x: number;
1263
- y: number;
1264
- screenX: number;
1265
- screenY: number;
1266
- };
1267
-
1268
- /**
1269
- * Unified SceneRenderer component.
1270
- * Defaults to PixiJS (WebGL) renderer. Falls back to SVG if pixi.js is not available.
1271
- */
1272
-
1273
- /**
1274
- * Auto-selecting SceneRenderer.
1275
- * Uses PixiJS (WebGL) when available, falls back to SVG.
1276
- * Experience authors can also import PixiSceneRenderer or SvgSceneRenderer directly.
1277
- */
1278
- declare function SceneRenderer(props: SceneRendererProps): any;
1279
-
1280
- /**
1281
- * SVG Scene Renderer.
1282
- *
1283
- * Takes a SceneGraph and renders it as SVG using React createElement calls.
1284
- * Uses the same getReact()/h() pattern as components.ts — no JSX, no import.
1285
- */
1286
-
1287
- declare function SvgSceneRenderer(props: SceneRendererProps): any;
1288
-
1289
- /**
1290
- * PixiJS WebGL Scene Renderer.
1291
- *
1292
- * Takes a SceneGraph and renders it to a WebGL canvas using PixiJS v8.
1293
- * Uses retained-mode rendering: on scene change, diffs and updates Pixi display objects
1294
- * rather than recreating the tree. Implements the same SceneRendererProps interface
1295
- * as SvgSceneRenderer.
1296
- *
1297
- * PixiJS is an optional dependency. If not available, the component renders a fallback
1298
- * message instructing the user to install pixi.js.
1299
- *
1300
- * Uses the getReact()/h() pattern — no JSX, no import React.
1301
- */
1302
-
1303
- declare function PixiSceneRenderer(props: SceneRendererProps): any;
1304
-
1305
- /**
1306
- * Pre-built scene manipulation tools.
1307
- *
1308
- * Factory function createSceneTools(namespace, z) returns ToolDef[] ready to
1309
- * spread into defineExperience({ tools: [...sceneTools(z)] }).
1310
- *
1311
- * Follows the same pattern as createAgentProtocolTools in agent-protocol.ts.
1312
- *
1313
- * 5 tools total — minimal surface area, maximum expressiveness:
1314
- * scene.add — add nodes
1315
- * scene.update — update any node (props, transform, style, tween)
1316
- * scene.remove — remove nodes
1317
- * scene.set — scene-level settings (camera, background, gradients, clear)
1318
- * scene.batch — multiple operations in one state update
1319
- */
1320
-
1321
- declare function createSceneTools(namespace: string, z: any): ToolDef[];
1322
-
1323
- /**
1324
- * Scene-specific React hooks.
1325
- *
1326
- * These hooks handle client-side concerns: interaction tracking, drag,
1327
- * selection, viewport pan/zoom, tween interpolation, and particle simulation.
1328
- *
1329
- * Uses the same lazy React access pattern as sdk/src/hooks.ts.
1330
- */
1331
-
1332
- type CallToolFn$2 = (name: string, input: any) => Promise<any>;
1333
- type SceneInteractionEvent = {
1334
- type: 'click' | 'hover' | 'hoverEnd';
1335
- nodeId: string;
1336
- x: number;
1337
- y: number;
1338
- };
1339
- type UseSceneInteractionReturn = {
1340
- lastEvent: SceneInteractionEvent | null;
1341
- hoveredNodeId: string | null;
1342
- onNodeClick: (nodeId: string, event: {
1343
- x: number;
1344
- y: number;
1345
- }) => void;
1346
- onNodeHover: (nodeId: string | null) => void;
1347
- };
1348
- /**
1349
- * Track click/hover events on scene nodes.
1350
- * Returns callbacks to wire into SceneRenderer props.
1351
- */
1352
- declare function useSceneInteraction(): UseSceneInteractionReturn;
1353
- type UseSceneDragReturn = {
1354
- dragging: string | null;
1355
- dragOffset: Vec2 | null;
1356
- onNodeDragStart: (nodeId: string, pos: Vec2) => void;
1357
- onNodeDrag: (nodeId: string, pos: Vec2) => void;
1358
- onNodeDragEnd: (nodeId: string, pos: Vec2) => void;
1359
- };
1360
- /**
1361
- * Drag scene nodes. On drag end, commits position via scene.transform tool call.
1362
- */
1363
- declare function useSceneDrag(callTool: CallToolFn$2, toolNamespace?: string): UseSceneDragReturn;
1364
- type UseSceneSelectionReturn = {
1365
- selectedIds: string[];
1366
- select: (nodeId: string) => void;
1367
- deselect: (nodeId: string) => void;
1368
- toggle: (nodeId: string) => void;
1369
- clear: () => void;
1370
- isSelected: (nodeId: string) => boolean;
1371
- };
1372
- /**
1373
- * Local multi-select state for scene nodes.
1374
- */
1375
- declare function useSceneSelection(): UseSceneSelectionReturn;
1376
- type UseSceneViewportReturn = {
1377
- camera: Camera;
1378
- onViewportPan: (delta: Vec2) => void;
1379
- onViewportZoom: (newZoom: number, center: Vec2) => void;
1380
- };
1381
- /**
1382
- * Pan/zoom the scene camera. Debounces tool calls to persist camera changes.
1383
- */
1384
- declare function useSceneViewport(callTool: CallToolFn$2, scene: SceneGraph, toolNamespace?: string): UseSceneViewportReturn;
1385
- /**
1386
- * Client-side tween interpolation at 60fps.
1387
- * Walks the scene graph, finds nodes with active tweens, interpolates
1388
- * their values, and returns a new SceneGraph with interpolated properties.
1389
- *
1390
- * Does NOT modify shared state — purely display-side.
1391
- */
1392
- declare function useSceneTweens(scene: SceneGraph): SceneGraph;
1393
- /**
1394
- * Client-side particle simulation at 60fps.
1395
- * Finds ParticlesNode nodes, spawns and ticks particles, returns scene
1396
- * with updated _particles arrays.
1397
- *
1398
- * Does NOT modify shared state — purely display-side.
1399
- */
1400
- declare function useParticleTick(scene: SceneGraph): SceneGraph;
1401
-
1402
- /**
1403
- * Scene graph utility functions.
1404
- *
1405
- * These are pure functions that operate on the SceneGraph type.
1406
- * Used by tool handlers, experience authors, and hooks.
1407
- */
1408
-
1409
- /**
1410
- * Create an empty scene graph with sensible defaults.
1411
- */
1412
- declare function createScene(opts?: {
1413
- width?: number;
1414
- height?: number;
1415
- background?: string;
1416
- }): SceneGraph;
1417
- /**
1418
- * Create a new scene node with an auto-generated ID.
1419
- *
1420
- * Usage:
1421
- * createNode('rect', { width: 100, height: 50, style: { fill: '#f00' } })
1422
- * createNode('circle', { radius: 30 })
1423
- * createNode('text', { text: 'Hello' })
1424
- */
1425
- declare function createNode(type: SceneNodeType, props: Omit<any, 'id' | 'type'> & {
1426
- id?: string;
1427
- }): SceneNode;
1428
- /**
1429
- * Find a node by ID anywhere in the scene graph.
1430
- * Returns null if not found.
1431
- */
1432
- declare function nodeById(scene: SceneGraph, id: string): SceneNode | null;
1433
- /**
1434
- * Find all nodes matching a predicate.
1435
- */
1436
- declare function findNodes(scene: SceneGraph, predicate: (node: SceneNode) => boolean): SceneNode[];
1437
- /**
1438
- * Walk all nodes in the scene graph, calling the visitor for each.
1439
- */
1440
- declare function walkNodes(node: SceneNode, visitor: (node: SceneNode) => void): void;
1441
- /**
1442
- * Get a flat list of all node IDs in the scene.
1443
- */
1444
- declare function allNodeIds(scene: SceneGraph): string[];
1445
- /**
1446
- * Count total nodes in the scene graph.
1447
- */
1448
- declare function nodeCount(scene: SceneGraph): number;
1449
- /**
1450
- * Deep clone a scene graph (JSON round-trip).
1451
- */
1452
- declare function cloneScene(scene: SceneGraph): SceneGraph;
1453
- /**
1454
- * Remove a node from the scene graph by ID. Returns true if found and removed.
1455
- */
1456
- declare function removeNodeById(root: GroupNode, id: string): boolean;
1457
- /**
1458
- * Find a node's parent group. Returns null if node is the root or not found.
1459
- */
1460
- declare function findParent(root: GroupNode, nodeId: string): GroupNode | null;
1461
- /**
1462
- * Return all pre-built scene tools ready to spread into defineExperience.
1463
- *
1464
- * Usage:
1465
- * import { sceneTools } from "@vibevibes/sdk";
1466
- * export default defineExperience({
1467
- * tools: [...myTools, ...sceneTools(z)],
1468
- * });
1469
- */
1470
- declare function sceneTools(z: any, namespace?: string): ToolDef[];
1471
-
1472
- /**
1473
- * Fluent API for building SVG path `d` strings.
1474
- *
1475
- * Agents can also construct d strings directly, but this gives experience
1476
- * authors a programmatic API for generating complex paths in tool handlers
1477
- * or Canvas components.
1478
- *
1479
- * Usage:
1480
- * const d = PathBuilder.from()
1481
- * .moveTo(0, 0)
1482
- * .lineTo(100, 0)
1483
- * .lineTo(100, 100)
1484
- * .close()
1485
- * .build();
1486
- * // "M 0 0 L 100 0 L 100 100 Z"
1487
- */
1488
- declare class PathBuilder {
1489
- private commands;
1490
- moveTo(x: number, y: number): this;
1491
- lineTo(x: number, y: number): this;
1492
- horizontalTo(x: number): this;
1493
- verticalTo(y: number): this;
1494
- quadTo(cx: number, cy: number, x: number, y: number): this;
1495
- cubicTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): this;
1496
- arcTo(rx: number, ry: number, rotation: number, largeArc: boolean, sweep: boolean, x: number, y: number): this;
1497
- close(): this;
1498
- rect(x: number, y: number, w: number, h: number): this;
1499
- roundedRect(x: number, y: number, w: number, h: number, rx: number, ry?: number): this;
1500
- circle(cx: number, cy: number, r: number): this;
1501
- ellipse(cx: number, cy: number, rx: number, ry: number): this;
1502
- star(cx: number, cy: number, points: number, outerR: number, innerR: number): this;
1503
- arrow(x1: number, y1: number, x2: number, y2: number, headSize?: number): this;
1504
- build(): string;
1505
- static from(): PathBuilder;
1506
- }
1507
-
1508
- /**
1509
- * Easing functions and tween interpolation logic.
1510
- *
1511
- * All easing functions take t (0-1) and return a value (0-1).
1512
- * Used by the renderer for client-side animation interpolation.
1513
- */
1514
-
1515
- type EasingFn = (t: number) => number;
1516
- declare const easingFunctions: Record<EasingType, EasingFn>;
1517
- /**
1518
- * Get the value at a given dot-path on an object.
1519
- * e.g. getPath({ transform: { x: 10 } }, 'transform.x') => 10
1520
- */
1521
- declare function getPath(obj: any, path: string): any;
1522
- /**
1523
- * Set a value at a given dot-path on an object (immutable - returns new object).
1524
- * e.g. setPath({ transform: { x: 10 } }, 'transform.x', 20) => { transform: { x: 20 } }
1525
- */
1526
- declare function setPath(obj: any, path: string, value: any): any;
1527
- /**
1528
- * Compute the interpolated value for a tween at a given timestamp.
1529
- * Returns null if the tween hasn't started yet or has completed (non-repeating).
1530
- */
1531
- declare function interpolateTween(tween: {
1532
- from: number;
1533
- to: number;
1534
- duration: number;
1535
- easing?: EasingType;
1536
- delay?: number;
1537
- repeat?: number;
1538
- yoyo?: boolean;
1539
- startedAt?: number;
1540
- }, now: number): number | null;
1541
-
1542
- /**
1543
- * Particle system tick logic.
1544
- *
1545
- * Pure functions for simulating particles. Used by useParticleTick hook
1546
- * for client-side particle simulation at 60fps.
1547
- */
1548
-
1549
- /**
1550
- * Spawn new particles from an emitter based on elapsed time.
1551
- */
1552
- declare function spawnParticles(emitter: ParticleEmitter, dt: number): Particle[];
1553
- /**
1554
- * Tick all particles: update positions, apply gravity, age.
1555
- * Returns the surviving particles (age < lifetime).
1556
- */
1557
- declare function tickParticles(particles: Particle[], emitters: ParticleEmitter[], dt: number): Particle[];
1558
- /**
1559
- * Full particle system tick for a ParticlesNode.
1560
- * Spawns new particles, ticks existing ones, caps at maxParticles.
1561
- */
1562
- declare function tickParticleNode(node: ParticlesNode, dt: number): Particle[];
1563
-
1564
- /**
1565
- * Zod schemas for scene graph validation.
1566
- *
1567
- * These schemas are used by scene tools to validate agent input.
1568
- * They accept `z` as a parameter (same pattern as agent-protocol.ts)
1569
- * so we don't import zod directly — it's provided by the experience.
1570
- */
1571
- declare function createSceneSchemas(z: any): {
1572
- vec2: any;
1573
- transform: any;
1574
- style: any;
1575
- textStyle: any;
1576
- gradientStop: any;
1577
- linearGradient: any;
1578
- radialGradient: any;
1579
- gradient: any;
1580
- particleEmitter: any;
1581
- spriteAnimation: any;
1582
- nodeSchema: any;
1583
- };
1584
-
1585
- /**
1586
- * Rule Engine for declarative client-side simulation.
1587
- *
1588
- * The agent writes rules as JSON via tool calls. The client evaluates them
1589
- * at ~10 ticks/sec via useRuleTick. Rules are a delegation mechanism — the
1590
- * agent teaches the client how to run parts of the simulation at tick speed
1591
- * so the agent can focus on high-level world design and evolution.
1592
- *
1593
- * Exports:
1594
- * Types: Rule, WorldMeta, RuleStats
1595
- * Hook: useRuleTick(scene, rules, worldMeta, callTool)
1596
- * Matching: nodeMatchesSelector(node, selector)
1597
- * Tools: createRuleTools(z) → ToolDef[]
1598
- * Shorthand: ruleTools(z) → ToolDef[]
1599
- */
1600
-
1601
- type Rule = {
1602
- id: string;
1603
- name: string;
1604
- description: string;
1605
- enabled: boolean;
1606
- trigger: "tick" | "interaction" | "proximity" | "timer";
1607
- condition: {
1608
- selector: string;
1609
- proximity?: {
1610
- target: string;
1611
- distance: number;
1612
- };
1613
- state?: Record<string, any>;
1614
- cooldownMs?: number;
1615
- probability?: number;
1616
- };
1617
- effect: {
1618
- type: "transform" | "style" | "data" | "counter" | "spawn" | "remove" | "tween";
1619
- dx?: number;
1620
- dy?: number;
1621
- dRotation?: number;
1622
- styleUpdates?: Record<string, any>;
1623
- dataUpdates?: Record<string, any>;
1624
- field?: string;
1625
- delta?: number;
1626
- spawnNode?: any;
1627
- spawnOffset?: {
1628
- x: number;
1629
- y: number;
1630
- };
1631
- tween?: {
1632
- property: string;
1633
- from: number;
1634
- to: number;
1635
- duration: number;
1636
- easing?: string;
1637
- repeat?: number;
1638
- yoyo?: boolean;
1639
- };
1640
- variance?: number;
1641
- probability?: number;
1642
- };
1643
- };
1644
- type WorldMeta = {
1645
- name: string;
1646
- description: string;
1647
- paused: boolean;
1648
- tickSpeed: number;
1649
- };
1650
- type RuleStats = {
1651
- rulesEvaluated: number;
1652
- rulesFired: number;
1653
- nodesAffected: number;
1654
- ticksElapsed: number;
1655
- };
1656
- /**
1657
- * Check if a scene node matches a selector string.
1658
- *
1659
- * Selector syntax:
1660
- * "*" — any node with data.entityType
1661
- * "entityType:fish" — data.entityType === "fish"
1662
- * "tag:swimming" — data.tags includes "swimming"
1663
- * "name:hero" — node.name === "hero"
1664
- * "type:circle" — node.type === "circle"
1665
- */
1666
- declare function nodeMatchesSelector(node: any, selector: string): boolean;
1667
- type CallToolFn$1 = (name: string, input: any) => Promise<any>;
1668
- /**
1669
- * Client-side tick engine. Evaluates enabled tick rules against the scene
1670
- * graph at ~tickSpeed ms intervals using requestAnimationFrame.
1671
- *
1672
- * Transform/style/data/counter/tween effects are applied locally for instant
1673
- * visual feedback. Spawn/remove effects are batched and flushed through
1674
- * scene.batch tool calls (debounced 300ms) so they persist in shared state.
1675
- */
1676
- declare function useRuleTick(scene: SceneGraph, rules: Rule[], worldMeta: WorldMeta, callTool: CallToolFn$1): {
1677
- simulatedScene: SceneGraph;
1678
- stats: RuleStats;
1679
- };
1680
- /**
1681
- * Create rule management tools for an experience.
1682
- *
1683
- * Returns 3 tools:
1684
- * _rules.set — create or update a rule
1685
- * _rules.remove — delete a rule by ID
1686
- * _rules.world — set world metadata (name, description, paused, tickSpeed)
1687
- */
1688
- declare function createRuleTools(z: any): ToolDef[];
1689
- /**
1690
- * Return all pre-built rule tools ready to spread into defineExperience.
1691
- *
1692
- * Usage:
1693
- * import { ruleTools } from "@vibevibes/sdk";
1694
- * export default defineExperience({
1695
- * tools: [...sceneTools(z), ...ruleTools(z)],
1696
- * });
1697
- */
1698
- declare function ruleTools(z: any): ToolDef[];
1699
-
1700
- /**
1701
- * Standardized chat for experiences.
1702
- *
1703
- * Provides a collapsible ChatPanel component, a useChat hook,
1704
- * and tool factories for agent participation.
185
+ * Chat tool factory for experiences.
1705
186
  *
1706
187
  * Messages are stored in shared state under `_chat` so agents
1707
188
  * see them via the stop hook's /agent-context endpoint.
1708
189
  *
1709
190
  * Usage:
1710
- * import { ChatPanel, createChatTools } from "@vibevibes/sdk";
1711
- *
191
+ * import { createChatTools } from "@vibevibes/sdk";
1712
192
  * const tools = [...myTools, ...createChatTools(z)];
1713
193
  *
1714
- * function Canvas(props) {
1715
- * return <div>
1716
- * <ChatPanel {...props} />
1717
- * </div>;
1718
- * }
194
+ * // In Canvas: read sharedState._chat, send via callTool('_chat.send', { message })
1719
195
  */
1720
196
 
1721
197
  type ChatMessage = {
@@ -1725,152 +201,6 @@ type ChatMessage = {
1725
201
  replyTo?: string;
1726
202
  ts: number;
1727
203
  };
1728
- type CallToolFn = (name: string, input: any) => Promise<any>;
1729
- type UseChatReturn = {
1730
- messages: ChatMessage[];
1731
- sendMessage: (message: string, replyTo?: string) => Promise<void>;
1732
- clearChat: () => Promise<void>;
1733
- setTyping: (isTyping: boolean) => void;
1734
- typingUsers: string[];
1735
- };
1736
- declare function createChatTools(z: any): ToolDef[];
1737
- declare function useChat(sharedState: Record<string, any>, callTool: CallToolFn, actorId: string, ephemeralState: Record<string, Record<string, any>>, setEphemeral: (data: Record<string, any>) => void): UseChatReturn;
1738
- type ChatPanelProps = {
1739
- sharedState: Record<string, any>;
1740
- callTool: (name: string, input: any) => Promise<any>;
1741
- actorId: string;
1742
- ephemeralState: Record<string, Record<string, any>>;
1743
- setEphemeral: (data: Record<string, any>) => void;
1744
- participants: string[];
1745
- style?: Record<string, any>;
1746
- /** When true, renders inline (flex column, 100% height) instead of fixed-position floating panel. No toggle button. */
1747
- embedded?: boolean;
1748
- };
1749
- declare function ChatPanel({ sharedState, callTool, actorId, ephemeralState, setEphemeral, style, embedded, }: ChatPanelProps): any;
1750
-
1751
- /**
1752
- * Standardized bug reporting for experiences.
1753
- *
1754
- * Provides a collapsible ReportBug button that captures a screenshot,
1755
- * shows a form for an optional description, and submits the report
1756
- * as a tool call stored in shared state.
1757
- *
1758
- * Bug reports are stored in shared state under `_bugReports`,
1759
- * so agents see them via the stop hook's /agent-context endpoint.
1760
- *
1761
- * Usage:
1762
- * import { ReportBug, createBugReportTools } from "@vibevibes/sdk";
1763
- *
1764
- * const tools = [...myTools, ...createBugReportTools(z)];
1765
- *
1766
- * function Canvas(props) {
1767
- * return <div>
1768
- * <ReportBug callTool={props.callTool} actorId={props.actorId} />
1769
- * </div>;
1770
- * }
1771
- */
1772
-
1773
- type BugReport = {
1774
- id: string;
1775
- actorId: string;
1776
- description: string;
1777
- screenshot?: string;
1778
- metadata?: Record<string, any>;
1779
- ts: number;
1780
- status: 'open' | 'resolved';
1781
- };
1782
- declare function createBugReportTools(z: any): ToolDef[];
1783
- type ReportBugProps = {
1784
- callTool: (name: string, input: any) => Promise<any>;
1785
- actorId: string;
1786
- style?: Record<string, any>;
1787
- };
1788
- declare function ReportBug({ callTool, actorId, style }: ReportBugProps): any;
1789
-
1790
- /**
1791
- * Inter-Experience Composability
1792
- *
1793
- * Level 1: importTools — Import tools from another experience's npm package
1794
- * Level 2: EmbeddedExperience — Embed another experience's Canvas with scoped state
1795
- */
1796
-
1797
- /**
1798
- * Import tools from another experience module.
1799
- *
1800
- * Usage:
1801
- * import chatExp from "@vibevibes/chat";
1802
- * const chatTools = importTools(chatExp, ["chat.send", "chat.clear"]);
1803
- * export default defineExperience({ tools: [...myTools, ...chatTools], ... });
1804
- *
1805
- * Or import all tools:
1806
- * const allChatTools = importTools(chatExp, "*");
1807
- *
1808
- * Optional prefix to namespace imported tools:
1809
- * const chatTools = importTools(chatExp, "*", "chat");
1810
- * // "send" becomes "chat.send"
1811
- */
1812
- declare function importTools(experienceModule: {
1813
- tools: ToolDef[];
1814
- }, toolNames: string[] | '*', prefix?: string): ToolDef[];
1815
- /**
1816
- * Props for the EmbeddedExperience component.
1817
- */
1818
- type EmbeddedExperienceProps = {
1819
- /** The child experience module to embed. */
1820
- experience: {
1821
- Canvas: React.FC<CanvasProps>;
1822
- tools: ToolDef[];
1823
- };
1824
- /** Key in parent state where child experience state lives. */
1825
- stateKey: string;
1826
- /** Parent's shared state. */
1827
- sharedState: Record<string, any>;
1828
- /** Parent's callTool function. */
1829
- callTool: (name: string, input: any) => Promise<any>;
1830
- /** Parent's room ID. */
1831
- roomId: string;
1832
- /** Parent's actor ID. */
1833
- actorId: string;
1834
- /** Parent's participants. */
1835
- participants: string[];
1836
- /** Parent's ephemeral state. */
1837
- ephemeralState: Record<string, Record<string, any>>;
1838
- /** Parent's setEphemeral. */
1839
- setEphemeral: (data: Record<string, any>) => void;
1840
- /** Parent's room config. */
1841
- roomConfig?: Record<string, any>;
1842
- /** Container style. */
1843
- style?: Record<string, any>;
1844
- /** Container className. */
1845
- className?: string;
1846
- };
1847
- /**
1848
- * Embeds another experience's Canvas as a sub-component with scoped state.
1849
- *
1850
- * The child experience reads/writes state under `sharedState[stateKey]` instead
1851
- * of the root state. Tool calls from the child are namespaced and scoped.
1852
- *
1853
- * Usage:
1854
- * import chatExp from "@vibevibes/chat";
1855
- *
1856
- * function Canvas(props) {
1857
- * return h('div', {},
1858
- * h(MyGameUI, props),
1859
- * h(EmbeddedExperience, {
1860
- * experience: chatExp,
1861
- * stateKey: "_chat",
1862
- * sharedState: props.sharedState,
1863
- * callTool: props.callTool,
1864
- * roomId: props.roomId,
1865
- * actorId: props.actorId,
1866
- * participants: props.participants,
1867
- * ephemeralState: props.ephemeralState,
1868
- * setEphemeral: props.setEphemeral,
1869
- * style: { position: 'absolute', bottom: 0, right: 0, width: 300, height: 400 },
1870
- * }),
1871
- * );
1872
- * }
1873
- */
1874
- declare function EmbeddedExperience(props: EmbeddedExperienceProps): any;
204
+ declare function createChatTools(z: ZodFactory): ToolDef[];
1875
205
 
1876
- export { type AgentContext, type AgentMessage, type AgentSlot, Badge, type BugReport, Button, type Camera, type CanvasProps, Card, type ChatMessage, ChatPanel, type CircleNode, ColorPicker, Dropdown, type EasingType, type EllipseNode, EmbeddedExperience, type EmbeddedExperienceProps, type EphemeralActionDef, type ExpectChain, type ExperienceImport, type ExperienceListing, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type FilterDef, type FilterType, type FollowState, type Gradient, type GradientStop, Grid, type GroupNode, type ImageNode, InMemoryAdapter, Input, type JsonPatchOp, type LineNode, type LinearGradient, type MigrationResult, Modal, type NetcodeMode, type ParsedParticipant, type Particle, type ParticleEmitter, type ParticlesNode, PathBuilder, type PathNode, type PerfMetrics, type PhaseConfig, PixiSceneRenderer, type PolygonNode, type PolylineNode, type RadialGradient, type RectNode, type RegistryEntry, ReportBug, type RoomConfigDef, type RoomLink, type RoomState, type Rule, type RuleStats, type SceneGraph, type SceneHitEvent, type SceneInteractionEvent, type SceneNode, type SceneNodeBase, type SceneNodeType, SceneRenderer, type SceneRendererProps, Slider, type SpawnRoomOpts, type SpawnRoomResult, type SpriteAnimation, type SpriteNode, Stack, type StateMigration, type StorageAdapter, type StorageToolEvent, type StreamDef, type Style, SvgSceneRenderer, Tabs, type TestDef, type TestHelpers, type TextNode, type TextStyle, Textarea, type TilemapNode, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type Transform, type TweenDef, type UseChatReturn, type UseFollowReturn, type UseOptimisticToolReturn, type UsePhaseReturn, type UseSceneDragReturn, type UseSceneInteractionReturn, type UseSceneSelectionReturn, type UseSceneViewportReturn, type UseToolCallReturn, type UseUndoReturn, type Vec2, type WebhookEventType, type WorldMeta, allNodeIds, cloneScene, compareSemver, createAgentProtocolTools, createBugReportTools, createChatTools, createNode, createRuleTools, createScene, createSceneSchemas, createSceneTools, defineEphemeralAction, defineExperience, defineRoomConfig, defineStream, defineTest, defineTool, easingFunctions, findNodes, findParent, getPath, getStateVersion, importTools, interpolateTween, migrateState, nodeById, nodeCount, nodeMatchesSelector, phaseTool, quickTool, removeNodeById, ruleTools, sceneTools, setPath, spawnParticles, tickParticleNode, tickParticles, undoTool, useAnimationFrame, useBlob, useChat, useDebounce, useFollow, useOptimisticTool, useParticipants, useParticleTick, usePhase, useRuleTick, useSceneDrag, useSceneInteraction, useSceneSelection, useSceneTweens, useSceneViewport, useSharedState, useThrottle, useToolCall, useTypingIndicator, useUndo, validateExperience, walkNodes };
206
+ export { type AgentSlot, type CallToolFn, type CanvasProps, type ChatMessage, type ExpectChain, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type ParticipantDetail, type ParticipantSlot, type RegistryEntry, type StreamDef, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type ZodFactory, createChatTools, defineExperience, defineStream, defineTest, defineTool };