@vibevibes/sdk 0.1.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.cjs +771 -0
- package/dist/index.d.cts +622 -0
- package/dist/index.d.ts +622 -0
- package/dist/index.js +720 -0
- package/package.json +63 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Experience SDK Types - Simplified state sync
|
|
6
|
+
*/
|
|
7
|
+
|
|
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
|
+
*/
|
|
30
|
+
type ToolEvent = {
|
|
31
|
+
id: string;
|
|
32
|
+
ts: number;
|
|
33
|
+
actorId: string;
|
|
34
|
+
owner?: string;
|
|
35
|
+
tool: string;
|
|
36
|
+
input: any;
|
|
37
|
+
output?: any;
|
|
38
|
+
error?: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Agent slot definition for multi-agent rooms.
|
|
42
|
+
* Experience authors define named agent roles with system prompts and tool restrictions.
|
|
43
|
+
*/
|
|
44
|
+
type AgentSlot = {
|
|
45
|
+
role: string;
|
|
46
|
+
systemPrompt: string;
|
|
47
|
+
allowedTools?: string[];
|
|
48
|
+
autoSpawn?: boolean;
|
|
49
|
+
maxInstances?: number;
|
|
50
|
+
};
|
|
51
|
+
type ExperienceManifest = {
|
|
52
|
+
id: string;
|
|
53
|
+
version: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string;
|
|
56
|
+
requested_capabilities: string[];
|
|
57
|
+
imports?: ExperienceImport[];
|
|
58
|
+
agentSlots?: AgentSlot[];
|
|
59
|
+
category?: string;
|
|
60
|
+
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). */
|
|
64
|
+
tickRateMs?: number;
|
|
65
|
+
/** State keys routed through fast ephemeral channel (no tool gate). */
|
|
66
|
+
hotKeys?: string[];
|
|
67
|
+
};
|
|
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
|
+
*/
|
|
76
|
+
type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
|
|
77
|
+
roomId: string;
|
|
78
|
+
actorId: string;
|
|
79
|
+
owner?: string;
|
|
80
|
+
state: TState;
|
|
81
|
+
setState: (newState: TState) => void;
|
|
82
|
+
timestamp: number;
|
|
83
|
+
memory: Record<string, any>;
|
|
84
|
+
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
|
+
};
|
|
92
|
+
type ToolDef<TInput = any, TOutput = any> = {
|
|
93
|
+
name: string;
|
|
94
|
+
description: string;
|
|
95
|
+
input_schema: z.ZodTypeAny;
|
|
96
|
+
risk: ToolRisk;
|
|
97
|
+
capabilities_required: string[];
|
|
98
|
+
handler: (ctx: ToolCtx, input: TInput) => Promise<TOutput>;
|
|
99
|
+
emits?: string[];
|
|
100
|
+
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
|
+
persist?: boolean;
|
|
107
|
+
};
|
|
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
|
+
type CanvasProps<TState extends Record<string, any> = Record<string, any>> = {
|
|
117
|
+
roomId: string;
|
|
118
|
+
actorId: string;
|
|
119
|
+
sharedState: TState;
|
|
120
|
+
callTool: (name: string, input: any, predictFn?: (state: TState) => TState) => Promise<any>;
|
|
121
|
+
/** Batch multiple tool calls in a single round-trip. */
|
|
122
|
+
callTools?: (calls: Array<{
|
|
123
|
+
name: string;
|
|
124
|
+
input: any;
|
|
125
|
+
}>) => Promise<any[]>;
|
|
126
|
+
ephemeralState: Record<string, Record<string, any>>;
|
|
127
|
+
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;
|
|
137
|
+
participants: string[];
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Assertion chain returned by `expect()` in test helpers.
|
|
141
|
+
*/
|
|
142
|
+
type ExpectChain<T> = {
|
|
143
|
+
toBe: (expected: T) => void;
|
|
144
|
+
toEqual: (expected: any) => void;
|
|
145
|
+
toBeTruthy: () => void;
|
|
146
|
+
toBeFalsy: () => void;
|
|
147
|
+
toContain: (item: any) => void;
|
|
148
|
+
toHaveProperty: (key: string, value?: any) => void;
|
|
149
|
+
not: ExpectChain<T>;
|
|
150
|
+
};
|
|
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
|
+
type TestHelpers = {
|
|
162
|
+
tool: (name: string) => ToolDef;
|
|
163
|
+
ctx: (opts?: {
|
|
164
|
+
state?: Record<string, any>;
|
|
165
|
+
actorId?: string;
|
|
166
|
+
roomId?: string;
|
|
167
|
+
owner?: string;
|
|
168
|
+
}) => ToolCtx & {
|
|
169
|
+
getState: () => Record<string, any>;
|
|
170
|
+
};
|
|
171
|
+
expect: <T>(actual: T) => ExpectChain<T>;
|
|
172
|
+
snapshot: (label: string, value: any) => void;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Inline test for experience tool handlers.
|
|
176
|
+
* Throw to fail; resolve to pass.
|
|
177
|
+
*/
|
|
178
|
+
type TestDef = {
|
|
179
|
+
name: string;
|
|
180
|
+
run: (helpers: TestHelpers) => Promise<void>;
|
|
181
|
+
};
|
|
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;
|
|
268
|
+
};
|
|
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;
|
|
278
|
+
};
|
|
279
|
+
type ExperienceModule = {
|
|
280
|
+
manifest: ExperienceManifest;
|
|
281
|
+
Canvas: React.FC<CanvasProps>;
|
|
282
|
+
tools: ToolDef[];
|
|
283
|
+
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[];
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
declare function defineTool<TInput, TOutput>(config: {
|
|
292
|
+
name: string;
|
|
293
|
+
description: string;
|
|
294
|
+
input_schema: z.ZodType<TInput>;
|
|
295
|
+
risk?: ToolRisk;
|
|
296
|
+
capabilities_required?: string[];
|
|
297
|
+
handler: ToolDef<TInput, TOutput>["handler"];
|
|
298
|
+
}): ToolDef<TInput, TOutput>;
|
|
299
|
+
declare function defineTest(config: {
|
|
300
|
+
name: string;
|
|
301
|
+
run: TestDef["run"];
|
|
302
|
+
}): TestDef;
|
|
303
|
+
declare function defineEphemeralAction(config: {
|
|
304
|
+
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[];
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* React hooks for experience authors.
|
|
327
|
+
*
|
|
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.
|
|
344
|
+
*
|
|
345
|
+
* 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.
|
|
352
|
+
*
|
|
353
|
+
* Usage:
|
|
354
|
+
* const count = useSharedState<number>(sharedState, 'count', 0);
|
|
355
|
+
*/
|
|
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 = {
|
|
385
|
+
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
|
+
actorId: string;
|
|
407
|
+
ts: number;
|
|
408
|
+
};
|
|
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
|
+
}
|
|
621
|
+
|
|
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 };
|