@vibevibes/sdk 0.1.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
@@ -2,45 +2,22 @@ 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,31 +25,41 @@ 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
- * Simplified Tool Context (no yjs, no events array)
70
- *
71
- * Use the generic parameter for typed state:
72
- * handler: async (ctx: ToolCtx<{ count: number }>, input) => {
73
- * const current = ctx.state.count; // typed
74
- * }
75
- */
56
+ type StreamDef<TInput = any> = {
57
+ name: string;
58
+ description?: string;
59
+ input_schema: z.ZodTypeAny;
60
+ merge: (state: Record<string, any>, input: TInput, actorId: string) => Record<string, any>;
61
+ rateLimit?: number;
62
+ };
76
63
  type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
77
64
  roomId: string;
78
65
  actorId: string;
@@ -82,12 +69,6 @@ type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
82
69
  timestamp: number;
83
70
  memory: Record<string, any>;
84
71
  setMemory: (updates: Record<string, any>) => void;
85
- /**
86
- * Spawn a child room with a specified experience.
87
- * Only available when manifest declares "room.spawn" in requested_capabilities.
88
- * Rate limited to 5 spawns per room per 5 minutes.
89
- */
90
- spawnRoom?: (opts: SpawnRoomOpts) => Promise<SpawnRoomResult>;
91
72
  };
92
73
  type ToolDef<TInput = any, TOutput = any> = {
93
74
  name: string;
@@ -98,66 +79,34 @@ type ToolDef<TInput = any, TOutput = any> = {
98
79
  handler: (ctx: ToolCtx, input: TInput) => Promise<TOutput>;
99
80
  emits?: string[];
100
81
  on?: Record<string, (ctx: ToolCtx, event: ToolEvent) => Promise<void>>;
101
- /**
102
- * If false, skip persisting state + event to DB after execution.
103
- * State is still broadcast to clients. Use for high-frequency tools
104
- * like cursor moves, animations, etc. Default: true.
105
- */
106
82
  persist?: boolean;
107
83
  };
108
- /**
109
- * Simplified Canvas Props - Hybrid State Model
110
- *
111
- * Use the generic parameter for typed sharedState:
112
- * const Canvas: React.FC<CanvasProps<{ count: number }>> = ({ sharedState }) => {
113
- * const count = sharedState.count; // fully typed
114
- * };
115
- */
116
84
  type CanvasProps<TState extends Record<string, any> = Record<string, any>> = {
117
- roomId: string;
118
85
  actorId: string;
119
86
  sharedState: TState;
120
- callTool: (name: string, input: any, predictFn?: (state: TState) => TState) => Promise<any>;
121
- /** Batch multiple tool calls in a single round-trip. */
87
+ callTool: (name: string, input: Record<string, unknown>, predictFn?: (state: TState) => TState) => Promise<unknown>;
122
88
  callTools?: (calls: Array<{
123
89
  name: string;
124
- input: any;
125
- }>) => Promise<any[]>;
90
+ input: Record<string, unknown>;
91
+ }>) => Promise<unknown[]>;
126
92
  ephemeralState: Record<string, Record<string, any>>;
127
93
  setEphemeral: (data: Record<string, any>) => void;
128
- /** Fire a client-authoritative action via Broadcast (no tool gate, no persistence). */
129
- dispatchEphemeralAction?: (name: string, input: any) => void;
130
- /** Subscribe to ephemeral actions from other participants. */
131
- onEphemeralAction?: (handler: (action: {
132
- name: string;
133
- input: any;
134
- actorId: string;
135
- ts: number;
136
- }) => void) => () => void;
94
+ stream?: (name: string, input: Record<string, unknown>) => void;
137
95
  participants: string[];
96
+ participantDetails?: ParticipantDetail[];
97
+ role?: "spectator" | "player";
138
98
  };
139
- /**
140
- * Assertion chain returned by `expect()` in test helpers.
141
- */
142
99
  type ExpectChain<T> = {
143
100
  toBe: (expected: T) => void;
144
- toEqual: (expected: any) => void;
101
+ toEqual: (expected: unknown) => void;
145
102
  toBeTruthy: () => void;
146
103
  toBeFalsy: () => void;
147
- toContain: (item: any) => void;
148
- 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;
149
108
  not: ExpectChain<T>;
150
109
  };
151
- /**
152
- * Helpers injected into each test's `run` function.
153
- *
154
- * - `tool(name)` looks up a tool from the experience's tools array
155
- * - `ctx(opts?)` creates a mock ToolCtx; call `getState()` after mutations
156
- * - `expect(actual)` returns an assertion chain for type-safe assertions
157
- * - `snapshot(label, value)` stores/compares values within a test session
158
- *
159
- * Tests signal failure by throwing. If `run` resolves, the test passed.
160
- */
161
110
  type TestHelpers = {
162
111
  tool: (name: string) => ToolDef;
163
112
  ctx: (opts?: {
@@ -169,123 +118,33 @@ type TestHelpers = {
169
118
  getState: () => Record<string, any>;
170
119
  };
171
120
  expect: <T>(actual: T) => ExpectChain<T>;
172
- 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
+ }>;
173
129
  };
174
- /**
175
- * Inline test for experience tool handlers.
176
- * Throw to fail; resolve to pass.
177
- */
178
130
  type TestDef = {
179
131
  name: string;
180
132
  run: (helpers: TestHelpers) => Promise<void>;
181
133
  };
182
- /**
183
- * Declarative hint for agents about when to act.
184
- * Experience authors include these to guide agent behavior.
185
- */
186
- type AgentHint = {
187
- trigger: string;
188
- condition?: string;
189
- suggestedTools: string[];
190
- priority?: 'low' | 'medium' | 'high';
191
- cooldownMs?: number;
192
- /** Cross-room agent coordination: follow linked rooms and react to activity there. */
193
- crossRoom?: {
194
- linkTypes?: string[];
195
- watchFor?: string[];
196
- };
197
- };
198
- /**
199
- * Client-authoritative action that bypasses the tool gate entirely.
200
- * Goes through Supabase Broadcast directly — no persistence, no server validation.
201
- * Use for cursor positions, hover states, drag previews, etc.
202
- */
203
- type EphemeralActionDef = {
204
- name: string;
205
- description: string;
206
- input_schema: z.ZodTypeAny;
207
- };
208
- /**
209
- * Performance metrics exposed by the room sync system.
210
- */
211
- type PerfMetrics = {
212
- toolCallRtts: number[];
213
- broadcastLatencies: number[];
214
- stateSize: number;
215
- rendersPerSecond: number;
216
- pendingOptimistic: number;
217
- };
218
- /**
219
- * Follow protocol: allows participants to "follow" another user's viewport/actions.
220
- * Stored in ephemeral state under the `_follow` key.
221
- */
222
- type FollowState = {
223
- targetActorId: string;
224
- mode: 'viewport' | 'actions' | 'both';
225
- since: number;
226
- };
227
- /**
228
- * Multi-agent message for negotiation protocol.
229
- * Agents communicate through shared state under the `_agentMessages` key.
230
- */
231
- type AgentMessage = {
232
- id: string;
233
- from: string;
234
- to: string | '*';
235
- type: 'proposal' | 'vote' | 'delegate' | 'inform' | 'request';
236
- content: string;
237
- data?: Record<string, any>;
238
- ts: number;
239
- ttl?: number;
240
- };
241
- /**
242
- * State migration function for experience versioning.
243
- * Called when a room's experience version changes.
244
- */
245
- type StateMigration = {
246
- from: string;
247
- to: string;
248
- migrate: (oldState: Record<string, any>) => Record<string, any>;
249
- };
250
- /**
251
- * Webhook event types that can be filtered.
252
- */
253
- type WebhookEventType = 'tool.executed' | 'tool.error' | 'participant.joined' | 'participant.left' | 'state.changed' | 'room.created' | 'room.reset';
254
- /**
255
- * Options for spawning a child room from a tool handler.
256
- * Requires "room.spawn" in manifest.requested_capabilities.
257
- */
258
- type SpawnRoomOpts = {
259
- experienceId: string;
260
- name?: string;
261
- initialState?: Record<string, any>;
262
- /** If true, store parent roomId in child state as _parentRoom */
263
- linkBack?: boolean;
264
- };
265
- type SpawnRoomResult = {
266
- roomId: string;
267
- url: string;
134
+ type RegistryEntry = {
135
+ path: string;
268
136
  };
269
- /**
270
- * A link between two rooms (parent/child relationship).
271
- */
272
- type RoomLink = {
273
- parentRoomId: string;
274
- childRoomId: string;
275
- linkType: 'spawned' | 'referenced' | 'forked';
276
- metadata?: Record<string, any>;
277
- createdAt: string;
137
+ type ExperienceRegistry = {
138
+ experiences: Record<string, RegistryEntry>;
278
139
  };
279
140
  type ExperienceModule = {
280
141
  manifest: ExperienceManifest;
281
142
  Canvas: React.FC<CanvasProps>;
282
143
  tools: ToolDef[];
283
144
  tests?: TestDef[];
284
- agentHints?: AgentHint[];
285
- /** Client-authoritative actions that bypass the tool gate. */
286
- ephemeralActions?: EphemeralActionDef[];
287
- /** State migrations for version upgrades. */
288
- migrations?: StateMigration[];
145
+ stateSchema?: z.ZodTypeAny;
146
+ streams?: StreamDef[];
147
+ observe?: (state: Record<string, any>, event: ToolEvent | null, actorId: string) => Record<string, any>;
289
148
  };
290
149
 
291
150
  declare function defineTool<TInput, TOutput>(config: {
@@ -300,323 +159,48 @@ declare function defineTest(config: {
300
159
  name: string;
301
160
  run: TestDef["run"];
302
161
  }): TestDef;
303
- declare function defineEphemeralAction(config: {
162
+ declare function defineStream<TInput>(config: {
304
163
  name: string;
305
- description: string;
306
- input_schema: z.ZodTypeAny;
307
- }): EphemeralActionDef;
308
- /**
309
- * Reduced-boilerplate tool definition.
310
- * Auto-derives defaults: risk="low", capabilities=["state.write"],
311
- * and spreads input into state if no handler is provided.
312
- *
313
- * Usage:
314
- * quickTool("counter.increment", "Add 1 to count", z.object({}), async (ctx) => {
315
- * ctx.setState({ ...ctx.state, count: (ctx.state.count ?? 0) + 1 });
316
- * })
317
- */
318
- declare function quickTool<TInput>(name: string, description: string, input_schema: z.ZodType<TInput>, handler: ToolDef<TInput, any>["handler"]): ToolDef<TInput, any>;
319
- declare function defineExperience(module: ExperienceModule): ExperienceModule;
320
- declare function validateExperience(module: ExperienceModule): {
321
- valid: boolean;
322
- errors: string[];
164
+ description?: string;
165
+ input_schema: z.ZodType<TInput>;
166
+ merge: (state: Record<string, any>, input: TInput, actorId: string) => Record<string, any>;
167
+ rateLimit?: number;
168
+ }): StreamDef<TInput>;
169
+ declare function defineExperience(module: ExperienceModule & {
170
+ initialState?: Record<string, any>;
171
+ agents?: Array<{
172
+ role: string;
173
+ systemPrompt: string;
174
+ allowedTools?: string[];
175
+ autoSpawn?: boolean;
176
+ maxInstances?: number;
177
+ }>;
178
+ participants?: ParticipantSlot[];
179
+ name?: string;
180
+ }): ExperienceModule & {
181
+ initialState?: Record<string, any>;
323
182
  };
324
183
 
325
184
  /**
326
- * React hooks for experience authors.
185
+ * Chat tool factory for experiences.
327
186
  *
328
- * These hooks simplify common patterns in experience Canvas components:
329
- * - useToolCall: wraps callTool with loading/error state
330
- * - useSharedState: typed accessor for a specific state key
331
- * - useOptimisticTool: optimistic updates with rollback on error
332
- * - useParticipants: parsed participant list with structured data
333
- *
334
- * Hooks rely on React being available as a global (provided by the bundler runtime).
335
- */
336
- type CallToolFn = (name: string, input: any) => Promise<any>;
337
- type UseToolCallReturn = {
338
- call: (name: string, input: any) => Promise<any>;
339
- loading: boolean;
340
- error: string | null;
341
- };
342
- /**
343
- * Wraps callTool with loading and error tracking.
187
+ * Messages are stored in shared state under `_chat` so agents
188
+ * see them via the stop hook's /agent-context endpoint.
344
189
  *
345
190
  * Usage:
346
- * const { call, loading, error } = useToolCall(callTool);
347
- * <button onClick={() => call('counter.increment', {})} disabled={loading}>
348
- */
349
- declare function useToolCall(callTool: CallToolFn): UseToolCallReturn;
350
- /**
351
- * Typed accessor for a specific key in shared state.
191
+ * import { createChatTools } from "@vibevibes/sdk";
192
+ * const tools = [...myTools, ...createChatTools(z)];
352
193
  *
353
- * Usage:
354
- * const count = useSharedState<number>(sharedState, 'count', 0);
194
+ * // In Canvas: read sharedState._chat, send via callTool('_chat.send', { message })
355
195
  */
356
- declare function useSharedState<T>(sharedState: Record<string, any>, key: string, defaultValue?: T): T;
357
- type UseOptimisticToolReturn = {
358
- call: (name: string, input: any, optimisticState: Record<string, any>) => Promise<any>;
359
- state: Record<string, any>;
360
- pending: boolean;
361
- };
362
- /**
363
- * Applies an optimistic state update immediately, then reverts on error.
364
- *
365
- * Usage:
366
- * const { call, state, pending } = useOptimisticTool(callTool, sharedState);
367
- * call('counter.increment', {}, { count: sharedState.count + 1 });
368
- */
369
- declare function useOptimisticTool(callTool: CallToolFn, sharedState: Record<string, any>): UseOptimisticToolReturn;
370
- /**
371
- * Decouples render frequency from state sync frequency.
372
- * State updates are buffered and applied at most once per animation frame.
373
- * Optional interpolation function smooths transitions between states.
374
- *
375
- * Usage:
376
- * const displayState = useAnimationFrame(sharedState);
377
- * // OR with interpolation:
378
- * const displayState = useAnimationFrame(sharedState, (prev, next, t) => ({
379
- * ...next,
380
- * x: prev.x + (next.x - prev.x) * t,
381
- * }));
382
- */
383
- declare function useAnimationFrame(sharedState: Record<string, any>, interpolate?: (prev: Record<string, any>, next: Record<string, any>, t: number) => Record<string, any>): Record<string, any>;
384
- type ParsedParticipant = {
196
+
197
+ type ChatMessage = {
385
198
  id: string;
386
- username: string;
387
- type: 'human' | 'ai' | 'unknown';
388
- index: number;
389
- };
390
- /**
391
- * Parses the participant ID list into structured objects.
392
- *
393
- * Participant IDs follow the format: {username}-{type}-{N}
394
- * e.g., "alice-human-1", "claude-ai-2"
395
- */
396
- declare function useParticipants(participants: string[]): ParsedParticipant[];
397
- type FollowMode = 'viewport' | 'actions' | 'both';
398
- type FollowData = {
399
- targetActorId: string;
400
- mode: FollowMode;
401
- since: number;
402
- };
403
- type EphemeralAction = {
404
- name: string;
405
- input: any;
406
199
  actorId: string;
200
+ message: string;
201
+ replyTo?: string;
407
202
  ts: number;
408
203
  };
409
- type DispatchEphemeralActionFn = (name: string, input: any) => void;
410
- type OnEphemeralActionFn = (handler: (action: EphemeralAction) => void) => () => void;
411
- type SetEphemeralFn = (data: Record<string, any>) => void;
412
- type UseFollowReturn = {
413
- /** Start following a target participant. */
414
- follow: (targetActorId: string, mode: FollowMode) => void;
415
- /** Stop following. */
416
- unfollow: () => void;
417
- /** Who you are currently following, or null. */
418
- following: FollowData | null;
419
- /** List of actor IDs that are following you. */
420
- followers: Array<{
421
- actorId: string;
422
- mode: FollowMode;
423
- since: number;
424
- }>;
425
- };
426
- /**
427
- * Manages follow-mode state via ephemeral presence.
428
- *
429
- * Stores follow intent in ephemeral state under `_follow` key and dispatches
430
- * `follow.started` / `follow.stopped` ephemeral actions to notify participants.
431
- *
432
- * Usage:
433
- * const { follow, unfollow, following, followers } = useFollow(
434
- * actorId, participants, ephemeralState, setEphemeral,
435
- * onEphemeralAction, dispatchEphemeralAction
436
- * );
437
- * follow('alice-human-1', 'viewport');
438
- */
439
- declare function useFollow(actorId: string, participants: string[], ephemeralState: Record<string, Record<string, any>>, setEphemeral: SetEphemeralFn, _onEphemeralAction?: OnEphemeralActionFn, dispatchEphemeralAction?: DispatchEphemeralActionFn): UseFollowReturn;
440
- /**
441
- * Manages typing/activity indicators via ephemeral state.
442
- *
443
- * Usage:
444
- * const { setTyping, typingUsers } = useTypingIndicator(actorId, ephemeralState, setEphemeral);
445
- *
446
- * // Call setTyping(true) when the user starts typing
447
- * // Call setTyping(false) when they stop (auto-clears after 3s)
448
- * // typingUsers is an array of actor IDs currently typing
449
- */
450
- declare function useTypingIndicator(actorId: string, ephemeralState: Record<string, Record<string, any>>, setEphemeral: (data: Record<string, any>) => void, timeoutMs?: number): {
451
- setTyping: (isTyping: boolean) => void;
452
- typingUsers: string[];
453
- };
454
-
455
- /**
456
- * Pre-built UI components for experiences.
457
- *
458
- * These components use inline styles (no Tailwind dependency) so they work
459
- * reliably inside bundled experience canvases. They provide sensible defaults
460
- * and can be overridden via the `style` prop.
461
- *
462
- * Usage in experiences:
463
- * import { Button, Card, Input, Badge, Stack, Grid } from "@vibevibes/experience-sdk";
464
- */
465
- type ButtonProps = {
466
- children?: any;
467
- onClick?: () => void;
468
- disabled?: boolean;
469
- variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
470
- size?: 'sm' | 'md' | 'lg';
471
- style?: Record<string, any>;
472
- };
473
- declare function Button({ children, onClick, disabled, variant, size, style }: ButtonProps): any;
474
- type CardProps = {
475
- children?: any;
476
- title?: string;
477
- style?: Record<string, any>;
478
- };
479
- declare function Card({ children, title, style }: CardProps): any;
480
- type InputProps = {
481
- value?: string;
482
- onChange?: (value: string) => void;
483
- placeholder?: string;
484
- type?: string;
485
- disabled?: boolean;
486
- style?: Record<string, any>;
487
- };
488
- declare function Input({ value, onChange, placeholder, type, disabled, style }: InputProps): any;
489
- type BadgeProps = {
490
- children?: any;
491
- color?: 'gray' | 'blue' | 'green' | 'red' | 'yellow' | 'purple';
492
- style?: Record<string, any>;
493
- };
494
- declare function Badge({ children, color, style }: BadgeProps): any;
495
- type StackProps = {
496
- children?: any;
497
- direction?: 'row' | 'column';
498
- gap?: string | number;
499
- align?: string;
500
- justify?: string;
501
- style?: Record<string, any>;
502
- };
503
- declare function Stack({ children, direction, gap, align, justify, style }: StackProps): any;
504
- type GridProps = {
505
- children?: any;
506
- columns?: number | string;
507
- gap?: string | number;
508
- style?: Record<string, any>;
509
- };
510
- declare function Grid({ children, columns, gap, style }: GridProps): any;
511
-
512
- /**
513
- * Multi-agent negotiation protocol.
514
- * Provides pre-built tools for agent-to-agent communication.
515
- */
516
-
517
- declare function createAgentProtocolTools(namespace: string, z: any): ToolDef[];
518
-
519
- /**
520
- * Pre-built agent hints for the negotiation protocol.
521
- */
522
-
523
- declare function createAgentProtocolHints(namespace: string): AgentHint[];
524
-
525
- /**
526
- * State migration runner for experience versioning.
527
- *
528
- * Pure functions (no side effects, no async) so they can run in Edge Functions,
529
- * Node.js, or the browser.
530
- */
531
-
532
- interface MigrationResult {
533
- migrated: boolean;
534
- fromVersion: string;
535
- toVersion: string;
536
- state: Record<string, any>;
537
- }
538
- /**
539
- * Get the state version from a state object.
540
- * Stored in state._version, defaults to "0.0.0" if absent.
541
- */
542
- declare function getStateVersion(state: Record<string, any>): string;
543
- /**
544
- * Compare two semver strings.
545
- * Returns -1 if a < b, 0 if equal, 1 if a > b.
546
- *
547
- * Handles standard major.minor.patch format. Missing segments default to 0.
548
- */
549
- declare function compareSemver(a: string, b: string): number;
550
- /**
551
- * Run all applicable migrations on a state object.
552
- *
553
- * - Reads state._version (default "0.0.0") as the starting version
554
- * - Sorts migrations by their to version (ascending semver)
555
- * - Applies each migration where migration.to > stateVersion and migration.to <= currentVersion
556
- * - Sets state._version = currentVersion after all migrations
557
- * - Returns a MigrationResult indicating whether any migrations were applied
558
- *
559
- * The migration runner is pure: it does not mutate the input state object.
560
- * It returns a new state object with migrations applied.
561
- */
562
- declare function migrateState(state: Record<string, any>, migrations: StateMigration[], currentVersion: string): MigrationResult;
563
-
564
- /**
565
- * Storage adapter interface for vibe vibes
566
- * Allows multiple storage backends: in-memory, Supabase, GitHub, etc.
567
- */
568
- interface ExperienceListing {
569
- id: string;
570
- title: string;
571
- description: string;
572
- version: string;
573
- source: 'builtin' | 'github' | 'supabase';
574
- github_repo?: string;
575
- github_url?: string;
576
- }
577
- interface RoomState {
578
- roomId: string;
579
- experienceId: string;
580
- sharedState: Record<string, any>;
581
- updatedAt: number;
582
- }
583
- interface StorageToolEvent {
584
- id: string;
585
- ts: number;
586
- actor_id: string;
587
- tool: string;
588
- input: unknown;
589
- output: unknown;
590
- }
591
- /**
592
- * Storage adapter interface
593
- * All methods are async to support both local and remote storage
594
- */
595
- interface StorageAdapter {
596
- saveRoomState(roomId: string, state: RoomState): Promise<void>;
597
- loadRoomState(roomId: string): Promise<RoomState | null>;
598
- appendEvent(roomId: string, event: StorageToolEvent): Promise<void>;
599
- loadEvents(roomId: string, limit?: number): Promise<StorageToolEvent[]>;
600
- listExperiences(userId?: string): Promise<ExperienceListing[]>;
601
- saveUserProfile?(userId: string, profile: any): Promise<void>;
602
- loadUserProfile?(userId: string): Promise<any | null>;
603
- }
604
- /**
605
- * In-memory storage adapter
606
- * No persistence - data lost on restart
607
- * Perfect for local development and demos
608
- */
609
- declare class InMemoryAdapter implements StorageAdapter {
610
- private roomStates;
611
- private events;
612
- private profiles;
613
- saveRoomState(roomId: string, state: RoomState): Promise<void>;
614
- loadRoomState(roomId: string): Promise<RoomState | null>;
615
- appendEvent(roomId: string, event: StorageToolEvent): Promise<void>;
616
- loadEvents(roomId: string, limit?: number): Promise<StorageToolEvent[]>;
617
- listExperiences(_userId?: string): Promise<ExperienceListing[]>;
618
- saveUserProfile(userId: string, profile: any): Promise<void>;
619
- loadUserProfile(userId: string): Promise<any | null>;
620
- }
204
+ declare function createChatTools(z: ZodFactory): ToolDef[];
621
205
 
622
- export { type AgentHint, type AgentMessage, type AgentSlot, Badge, Button, type CanvasProps, Card, type EphemeralActionDef, type ExpectChain, type ExperienceImport, type ExperienceListing, type ExperienceManifest, type ExperienceModule, type FollowState, Grid, InMemoryAdapter, Input, type JsonPatchOp, type MigrationResult, type NetcodeMode, type ParsedParticipant, type PerfMetrics, type RoomLink, type RoomState, type SpawnRoomOpts, type SpawnRoomResult, Stack, type StateMigration, type StorageAdapter, type StorageToolEvent, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type UseFollowReturn, type UseOptimisticToolReturn, type UseToolCallReturn, type WebhookEventType, compareSemver, createAgentProtocolHints, createAgentProtocolTools, defineEphemeralAction, defineExperience, defineTest, defineTool, getStateVersion, migrateState, quickTool, useAnimationFrame, useFollow, useOptimisticTool, useParticipants, useSharedState, useToolCall, useTypingIndicator, validateExperience };
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 };