@vibevibes/sdk 0.1.0 → 0.2.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/LICENSE +21 -0
- package/README.md +263 -0
- package/dist/index.cjs +4893 -46
- package/dist/index.d.cts +1284 -30
- package/dist/index.d.ts +1284 -30
- package/dist/index.js +4826 -44
- package/package.json +6 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React$1 from 'react';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -65,6 +65,48 @@ type ExperienceManifest = {
|
|
|
65
65
|
/** State keys routed through fast ephemeral channel (no tool gate). */
|
|
66
66
|
hotKeys?: string[];
|
|
67
67
|
};
|
|
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
|
+
type StreamDef<TInput = any> = {
|
|
102
|
+
name: string;
|
|
103
|
+
description?: string;
|
|
104
|
+
input_schema: z.ZodTypeAny;
|
|
105
|
+
/** Pure merge function: takes current state, stream input, and actorId, returns new state. */
|
|
106
|
+
merge: (state: Record<string, any>, input: TInput, actorId: string) => Record<string, any>;
|
|
107
|
+
/** Max inputs per second per actor (server-enforced). Default: 60. */
|
|
108
|
+
rateLimit?: number;
|
|
109
|
+
};
|
|
68
110
|
/**
|
|
69
111
|
* Simplified Tool Context (no yjs, no events array)
|
|
70
112
|
*
|
|
@@ -73,7 +115,7 @@ type ExperienceManifest = {
|
|
|
73
115
|
* const current = ctx.state.count; // typed
|
|
74
116
|
* }
|
|
75
117
|
*/
|
|
76
|
-
type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
|
|
118
|
+
type ToolCtx<TState extends Record<string, any> = Record<string, any>, TConfig extends Record<string, any> = Record<string, any>> = {
|
|
77
119
|
roomId: string;
|
|
78
120
|
actorId: string;
|
|
79
121
|
owner?: string;
|
|
@@ -82,12 +124,22 @@ type ToolCtx<TState extends Record<string, any> = Record<string, any>> = {
|
|
|
82
124
|
timestamp: number;
|
|
83
125
|
memory: Record<string, any>;
|
|
84
126
|
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;
|
|
85
133
|
/**
|
|
86
134
|
* Spawn a child room with a specified experience.
|
|
87
135
|
* Only available when manifest declares "room.spawn" in requested_capabilities.
|
|
88
136
|
* Rate limited to 5 spawns per room per 5 minutes.
|
|
89
137
|
*/
|
|
90
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;
|
|
91
143
|
};
|
|
92
144
|
type ToolDef<TInput = any, TOutput = any> = {
|
|
93
145
|
name: string;
|
|
@@ -113,7 +165,7 @@ type ToolDef<TInput = any, TOutput = any> = {
|
|
|
113
165
|
* const count = sharedState.count; // fully typed
|
|
114
166
|
* };
|
|
115
167
|
*/
|
|
116
|
-
type CanvasProps<TState extends Record<string, any> = Record<string, any>> = {
|
|
168
|
+
type CanvasProps<TState extends Record<string, any> = Record<string, any>, TConfig extends Record<string, any> = Record<string, any>> = {
|
|
117
169
|
roomId: string;
|
|
118
170
|
actorId: string;
|
|
119
171
|
sharedState: TState;
|
|
@@ -134,7 +186,15 @@ type CanvasProps<TState extends Record<string, any> = Record<string, any>> = {
|
|
|
134
186
|
actorId: string;
|
|
135
187
|
ts: number;
|
|
136
188
|
}) => void) => () => void;
|
|
189
|
+
/** Send high-frequency continuous input via WebSocket stream. Bypasses tool gate. */
|
|
190
|
+
stream?: (name: string, input: any) => void;
|
|
137
191
|
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;
|
|
138
198
|
};
|
|
139
199
|
/**
|
|
140
200
|
* Assertion chain returned by `expect()` in test helpers.
|
|
@@ -165,6 +225,7 @@ type TestHelpers = {
|
|
|
165
225
|
actorId?: string;
|
|
166
226
|
roomId?: string;
|
|
167
227
|
owner?: string;
|
|
228
|
+
roomConfig?: Record<string, any>;
|
|
168
229
|
}) => ToolCtx & {
|
|
169
230
|
getState: () => Record<string, any>;
|
|
170
231
|
};
|
|
@@ -180,20 +241,15 @@ type TestDef = {
|
|
|
180
241
|
run: (helpers: TestHelpers) => Promise<void>;
|
|
181
242
|
};
|
|
182
243
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
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.
|
|
185
247
|
*/
|
|
186
|
-
type
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
};
|
|
248
|
+
type AgentContext = {
|
|
249
|
+
events: ToolEvent[];
|
|
250
|
+
observation: Record<string, any>;
|
|
251
|
+
participants: string[];
|
|
252
|
+
sharedState: Record<string, any>;
|
|
197
253
|
};
|
|
198
254
|
/**
|
|
199
255
|
* Client-authoritative action that bypasses the tool gate entirely.
|
|
@@ -261,10 +317,18 @@ type SpawnRoomOpts = {
|
|
|
261
317
|
initialState?: Record<string, any>;
|
|
262
318
|
/** If true, store parent roomId in child state as _parentRoom */
|
|
263
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;
|
|
264
326
|
};
|
|
265
327
|
type SpawnRoomResult = {
|
|
266
328
|
roomId: string;
|
|
267
329
|
url: string;
|
|
330
|
+
/** The resolved config applied to the spawned room. */
|
|
331
|
+
config: Record<string, any>;
|
|
268
332
|
};
|
|
269
333
|
/**
|
|
270
334
|
* A link between two rooms (parent/child relationship).
|
|
@@ -276,16 +340,75 @@ type RoomLink = {
|
|
|
276
340
|
metadata?: Record<string, any>;
|
|
277
341
|
createdAt: string;
|
|
278
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
|
+
type RegistryEntry = {
|
|
348
|
+
path: string;
|
|
349
|
+
};
|
|
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
|
+
type ExperienceRegistry = {
|
|
355
|
+
experiences: Record<string, RegistryEntry>;
|
|
356
|
+
};
|
|
279
357
|
type ExperienceModule = {
|
|
280
358
|
manifest: ExperienceManifest;
|
|
281
|
-
Canvas: React.FC<CanvasProps>;
|
|
359
|
+
Canvas: React$1.FC<CanvasProps>;
|
|
282
360
|
tools: ToolDef[];
|
|
283
361
|
tests?: TestDef[];
|
|
284
|
-
agentHints?: AgentHint[];
|
|
285
362
|
/** Client-authoritative actions that bypass the tool gate. */
|
|
286
363
|
ephemeralActions?: EphemeralActionDef[];
|
|
287
364
|
/** State migrations for version upgrades. */
|
|
288
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
|
+
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
|
+
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
|
+
observe?: (state: Record<string, any>, event: ToolEvent | null, actorId: string) => Record<string, any>;
|
|
289
412
|
};
|
|
290
413
|
|
|
291
414
|
declare function defineTool<TInput, TOutput>(config: {
|
|
@@ -316,10 +439,108 @@ declare function defineEphemeralAction(config: {
|
|
|
316
439
|
* })
|
|
317
440
|
*/
|
|
318
441
|
declare function quickTool<TInput>(name: string, description: string, input_schema: z.ZodType<TInput>, handler: ToolDef<TInput, any>["handler"]): ToolDef<TInput, any>;
|
|
319
|
-
|
|
320
|
-
|
|
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
|
+
declare function defineStream<TInput>(config: {
|
|
515
|
+
name: string;
|
|
516
|
+
description?: string;
|
|
517
|
+
input_schema: z.ZodType<TInput>;
|
|
518
|
+
merge: (state: Record<string, any>, input: TInput, actorId: string) => Record<string, any>;
|
|
519
|
+
rateLimit?: number;
|
|
520
|
+
}): StreamDef<TInput>;
|
|
521
|
+
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
|
+
initialState?: Record<string, any>;
|
|
525
|
+
/** Agent slot configurations. */
|
|
526
|
+
agents?: Array<{
|
|
527
|
+
role: string;
|
|
528
|
+
systemPrompt: string;
|
|
529
|
+
allowedTools?: string[];
|
|
530
|
+
autoSpawn?: boolean;
|
|
531
|
+
maxInstances?: number;
|
|
532
|
+
}>;
|
|
533
|
+
/** Display name (convenience, copied to manifest.title if manifest.title is missing). */
|
|
534
|
+
name?: string;
|
|
535
|
+
}): ExperienceModule & {
|
|
536
|
+
initialState?: Record<string, any>;
|
|
537
|
+
};
|
|
538
|
+
declare function validateExperience(module: ExperienceModule & {
|
|
539
|
+
initialState?: Record<string, any>;
|
|
540
|
+
}): {
|
|
321
541
|
valid: boolean;
|
|
322
542
|
errors: string[];
|
|
543
|
+
warnings: string[];
|
|
323
544
|
};
|
|
324
545
|
|
|
325
546
|
/**
|
|
@@ -333,7 +554,7 @@ declare function validateExperience(module: ExperienceModule): {
|
|
|
333
554
|
*
|
|
334
555
|
* Hooks rely on React being available as a global (provided by the bundler runtime).
|
|
335
556
|
*/
|
|
336
|
-
type CallToolFn = (name: string, input: any) => Promise<any>;
|
|
557
|
+
type CallToolFn$3 = (name: string, input: any) => Promise<any>;
|
|
337
558
|
type UseToolCallReturn = {
|
|
338
559
|
call: (name: string, input: any) => Promise<any>;
|
|
339
560
|
loading: boolean;
|
|
@@ -346,7 +567,7 @@ type UseToolCallReturn = {
|
|
|
346
567
|
* const { call, loading, error } = useToolCall(callTool);
|
|
347
568
|
* <button onClick={() => call('counter.increment', {})} disabled={loading}>
|
|
348
569
|
*/
|
|
349
|
-
declare function useToolCall(callTool: CallToolFn): UseToolCallReturn;
|
|
570
|
+
declare function useToolCall(callTool: CallToolFn$3): UseToolCallReturn;
|
|
350
571
|
/**
|
|
351
572
|
* Typed accessor for a specific key in shared state.
|
|
352
573
|
*
|
|
@@ -366,7 +587,7 @@ type UseOptimisticToolReturn = {
|
|
|
366
587
|
* const { call, state, pending } = useOptimisticTool(callTool, sharedState);
|
|
367
588
|
* call('counter.increment', {}, { count: sharedState.count + 1 });
|
|
368
589
|
*/
|
|
369
|
-
declare function useOptimisticTool(callTool: CallToolFn, sharedState: Record<string, any>): UseOptimisticToolReturn;
|
|
590
|
+
declare function useOptimisticTool(callTool: CallToolFn$3, sharedState: Record<string, any>): UseOptimisticToolReturn;
|
|
370
591
|
/**
|
|
371
592
|
* Decouples render frequency from state sync frequency.
|
|
372
593
|
* State updates are buffered and applied at most once per animation frame.
|
|
@@ -451,6 +672,117 @@ declare function useTypingIndicator(actorId: string, ephemeralState: Record<stri
|
|
|
451
672
|
setTyping: (isTyping: boolean) => void;
|
|
452
673
|
typingUsers: string[];
|
|
453
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;
|
|
454
786
|
|
|
455
787
|
/**
|
|
456
788
|
* Pre-built UI components for experiences.
|
|
@@ -508,6 +840,65 @@ type GridProps = {
|
|
|
508
840
|
style?: Record<string, any>;
|
|
509
841
|
};
|
|
510
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;
|
|
511
902
|
|
|
512
903
|
/**
|
|
513
904
|
* Multi-agent negotiation protocol.
|
|
@@ -516,12 +907,6 @@ declare function Grid({ children, columns, gap, style }: GridProps): any;
|
|
|
516
907
|
|
|
517
908
|
declare function createAgentProtocolTools(namespace: string, z: any): ToolDef[];
|
|
518
909
|
|
|
519
|
-
/**
|
|
520
|
-
* Pre-built agent hints for the negotiation protocol.
|
|
521
|
-
*/
|
|
522
|
-
|
|
523
|
-
declare function createAgentProtocolHints(namespace: string): AgentHint[];
|
|
524
|
-
|
|
525
910
|
/**
|
|
526
911
|
* State migration runner for experience versioning.
|
|
527
912
|
*
|
|
@@ -619,4 +1004,873 @@ declare class InMemoryAdapter implements StorageAdapter {
|
|
|
619
1004
|
loadUserProfile(userId: string): Promise<any | null>;
|
|
620
1005
|
}
|
|
621
1006
|
|
|
622
|
-
|
|
1007
|
+
/**
|
|
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.
|
|
1705
|
+
*
|
|
1706
|
+
* Messages are stored in shared state under `_chat` so agents
|
|
1707
|
+
* see them via the stop hook's /agent-context endpoint.
|
|
1708
|
+
*
|
|
1709
|
+
* Usage:
|
|
1710
|
+
* import { ChatPanel, createChatTools } from "@vibevibes/sdk";
|
|
1711
|
+
*
|
|
1712
|
+
* const tools = [...myTools, ...createChatTools(z)];
|
|
1713
|
+
*
|
|
1714
|
+
* function Canvas(props) {
|
|
1715
|
+
* return <div>
|
|
1716
|
+
* <ChatPanel {...props} />
|
|
1717
|
+
* </div>;
|
|
1718
|
+
* }
|
|
1719
|
+
*/
|
|
1720
|
+
|
|
1721
|
+
type ChatMessage = {
|
|
1722
|
+
id: string;
|
|
1723
|
+
actorId: string;
|
|
1724
|
+
message: string;
|
|
1725
|
+
replyTo?: string;
|
|
1726
|
+
ts: number;
|
|
1727
|
+
};
|
|
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;
|
|
1875
|
+
|
|
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 };
|