@vibevibes/sdk 0.3.0 → 0.4.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/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # @vibevibes/sdk
2
2
 
3
- The primitives for building agent-native experiences — shared interactive apps where humans and AI collaborate in real-time through a shared state, shared tools, and a shared canvas.
3
+ Primitives for building shared human-AI experiences — interactive apps where humans and AI agents collaborate in real-time through shared state, shared tools, and a shared canvas.
4
+
5
+ [![npm](https://img.shields.io/npm/v/@vibevibes/sdk)](https://www.npmjs.com/package/@vibevibes/sdk)
6
+ [![license](https://img.shields.io/npm/l/@vibevibes/sdk)](./LICENSE)
4
7
 
5
8
  ## Install
6
9
 
@@ -21,7 +24,7 @@ const tools = [
21
24
  name: "counter.increment",
22
25
  description: "Add to the counter",
23
26
  input_schema: z.object({
24
- amount: z.number().default(1).describe("Amount to add"),
27
+ amount: z.number().default(1),
25
28
  }),
26
29
  handler: async (ctx, input) => {
27
30
  const count = (ctx.state.count || 0) + input.amount;
@@ -59,44 +62,24 @@ That's a complete experience. Humans click the button. Agents call the same tool
59
62
 
60
63
  ## Core Concepts
61
64
 
62
- **Tools are the only way to mutate state.** Every tool has a Zod schema for validation and a handler that calls `ctx.setState()`. Humans use tools via the Canvas. Agents use the same tools via MCP. No backdoors.
65
+ **Tools are the only way to mutate state.** Every tool has a Zod schema and a handler that calls `ctx.setState()`. Humans use tools via the Canvas. Agents use the same tools via MCP. No backdoors.
63
66
 
64
- **Canvas is a React component.** It receives the current shared state and a `callTool` function. It re-renders on every state change.
67
+ **Canvas is a React component.** It receives current shared state and a `callTool` function. Re-renders on every state change.
65
68
 
66
69
  **Agents are actors, not assistants.** They join rooms, watch for events, react with tools, and persist memory. Same participation model as humans.
67
70
 
68
- ## Defining Tools
69
-
70
- ```tsx
71
- defineTool({
72
- name: "board.place",
73
- description: "Place a piece on the board",
74
- input_schema: z.object({
75
- x: z.number(),
76
- y: z.number(),
77
- piece: z.string(),
78
- }),
79
- handler: async (ctx, input) => {
80
- const board = { ...ctx.state.board };
81
- board[`${input.x},${input.y}`] = input.piece;
82
- ctx.setState({ ...ctx.state, board });
83
- return { placed: true };
84
- },
85
- });
86
- ```
87
-
88
- ### Tool Handler Context
71
+ ## Tool Handler Context
89
72
 
90
73
  ```tsx
91
74
  type ToolCtx = {
92
75
  roomId: string;
93
- actorId: string; // Who called this tool
94
- owner?: string; // Owner extracted from actorId
95
- state: Record<string, any>; // Current shared state (read)
96
- setState: (s: Record<string, any>) => void; // Set new state (write)
76
+ actorId: string; // Who called this tool
77
+ owner?: string; // Owner extracted from actorId
78
+ state: Record<string, any>; // Current shared state (read)
79
+ setState: (s) => void; // Set new state (write)
97
80
  timestamp: number;
98
- memory: Record<string, any>; // Agent's persistent memory
99
- setMemory: (updates: Record<string, any>) => void;
81
+ memory: Record<string, any>; // Agent's persistent memory
82
+ setMemory: (updates) => void;
100
83
  };
101
84
  ```
102
85
 
@@ -116,28 +99,36 @@ type CanvasProps = {
116
99
  };
117
100
  ```
118
101
 
119
- ## Agent Slots
102
+ ## Hooks
103
+
104
+ | Hook | Returns | Purpose |
105
+ |------|---------|---------|
106
+ | `useToolCall(callTool)` | `{ call, loading, error }` | Loading/error tracking |
107
+ | `useSharedState(state, key, default?)` | `value` | Typed state accessor |
108
+ | `useOptimisticTool(callTool, state)` | `{ call, state, pending }` | Optimistic updates with rollback |
109
+ | `useParticipants(participants)` | `ParsedParticipant[]` | Parse actor IDs |
110
+ | `useAnimationFrame(state, interpolate?)` | `displayState` | Frame-rate buffering |
111
+
112
+ ## Components
120
113
 
121
- Define named agent roles for multi-agent experiences:
114
+ Inline-styled (no Tailwind needed): `Button`, `Card`, `Input`, `Badge`, `Stack`, `Grid`
115
+
116
+ ## Agent Slots
122
117
 
123
118
  ```tsx
124
119
  manifest: {
125
- agentSlots: [
126
- {
127
- role: "game-master",
128
- systemPrompt: "You are the game master.",
129
- allowedTools: ["world.narrate", "npc.speak"],
130
- autoSpawn: true,
131
- maxInstances: 1,
132
- },
133
- ],
120
+ agentSlots: [{
121
+ role: "game-master",
122
+ systemPrompt: "You are the game master.",
123
+ allowedTools: ["world.narrate"],
124
+ autoSpawn: true,
125
+ maxInstances: 1,
126
+ }],
134
127
  }
135
128
  ```
136
129
 
137
130
  ## Tests
138
131
 
139
- Inline tests for tool handlers:
140
-
141
132
  ```tsx
142
133
  import { defineTest } from "@vibevibes/sdk";
143
134
 
@@ -154,26 +145,7 @@ tests: [
154
145
  ]
155
146
  ```
156
147
 
157
- ## Manifest
158
-
159
- ```tsx
160
- type ExperienceManifest = {
161
- id: string;
162
- version: string;
163
- title: string;
164
- description: string;
165
- requested_capabilities: string[];
166
- agentSlots?: AgentSlot[];
167
- participantSlots?: ParticipantSlot[];
168
- category?: string;
169
- tags?: string[];
170
- netcode?: "default" | "tick" | "p2p-ephemeral";
171
- tickRateMs?: number;
172
- hotKeys?: string[];
173
- };
174
- ```
175
-
176
- ## How It Works
148
+ ## Architecture
177
149
 
178
150
  ```
179
151
  Browser (Canvas) <--WebSocket--> Server <--HTTP--> MCP (Agent)
@@ -184,15 +156,13 @@ Browser (Canvas) <--WebSocket--> Server <--HTTP--> MCP (Agent)
184
156
  broadcasts to all clients
185
157
  ```
186
158
 
187
- All state lives on the server. The Canvas renders it. Tools are the only mutation path. Both humans and agents use the same tools.
188
-
189
159
  ## Ecosystem
190
160
 
191
161
  | Package | Description |
192
162
  |---------|-------------|
193
- | **@vibevibes/sdk** (this) | Define experiences — tools, canvas, state |
194
- | [@vibevibes/mcp](https://github.com/vibevibes/mcp) | Runtime server — MCP + WebSocket + browser viewer |
195
- | [create-vibevibes](https://github.com/vibevibes/create) | `npx create-vibevibes my-exp` — scaffold in seconds |
163
+ | **@vibevibes/sdk** | Define experiences — tools, canvas, state |
164
+ | [@vibevibes/mcp](https://github.com/vibevibes/mcp) | Runtime engine — MCP server + WebSocket + viewer |
165
+ | [@vibevibes/create](https://github.com/vibevibes/create) | `npx @vibevibes/create` — scaffold in seconds |
196
166
  | [experiences](https://github.com/vibevibes/experiences) | Example experiences — fork and remix |
197
167
 
198
168
  ## License
package/dist/index.cjs CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- createChatTools: () => createChatTools,
24
23
  defineExperience: () => defineExperience,
25
24
  defineStream: () => defineStream,
26
25
  defineTest: () => defineTest,
@@ -92,57 +91,8 @@ function defineExperience(module2) {
92
91
  }
93
92
  };
94
93
  }
95
-
96
- // src/chat.ts
97
- function uid() {
98
- return Math.random().toString(36).slice(2, 10) + Date.now().toString(36);
99
- }
100
- function capMessages(msgs, max = 200) {
101
- return msgs.length > max ? msgs.slice(-max) : msgs;
102
- }
103
- function createChatTools(z) {
104
- return [
105
- {
106
- name: "_chat.send",
107
- description: "Send a chat message",
108
- input_schema: z.object({
109
- message: z.string().min(1).max(2e3),
110
- replyTo: z.string().optional()
111
- }),
112
- risk: "low",
113
- capabilities_required: ["state.write"],
114
- handler: async (ctx, input) => {
115
- const cleanMessage = input.message.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
116
- const messages = capMessages([
117
- ...ctx.state._chat || [],
118
- {
119
- id: uid(),
120
- actorId: ctx.actorId,
121
- message: cleanMessage,
122
- replyTo: input.replyTo,
123
- ts: ctx.timestamp
124
- }
125
- ]);
126
- ctx.setState({ ...ctx.state, _chat: messages });
127
- return { sent: true, messageCount: messages.length };
128
- }
129
- },
130
- {
131
- name: "_chat.clear",
132
- description: "Clear all chat messages",
133
- input_schema: z.object({}),
134
- risk: "medium",
135
- capabilities_required: ["state.write"],
136
- handler: async (ctx) => {
137
- ctx.setState({ ...ctx.state, _chat: [] });
138
- return { cleared: true };
139
- }
140
- }
141
- ];
142
- }
143
94
  // Annotate the CommonJS export names for ESM import in node:
144
95
  0 && (module.exports = {
145
- createChatTools,
146
96
  defineExperience,
147
97
  defineStream,
148
98
  defineTest,
package/dist/index.d.cts CHANGED
@@ -181,26 +181,4 @@ declare function defineExperience(module: ExperienceModule & {
181
181
  initialState?: Record<string, any>;
182
182
  };
183
183
 
184
- /**
185
- * Chat tool factory for experiences.
186
- *
187
- * Messages are stored in shared state under `_chat` so agents
188
- * see them via the stop hook's /agent-context endpoint.
189
- *
190
- * Usage:
191
- * import { createChatTools } from "@vibevibes/sdk";
192
- * const tools = [...myTools, ...createChatTools(z)];
193
- *
194
- * // In Canvas: read sharedState._chat, send via callTool('_chat.send', { message })
195
- */
196
-
197
- type ChatMessage = {
198
- id: string;
199
- actorId: string;
200
- message: string;
201
- replyTo?: string;
202
- ts: number;
203
- };
204
- declare function createChatTools(z: ZodFactory): ToolDef[];
205
-
206
- export { type AgentSlot, type CallToolFn, type CanvasProps, type ChatMessage, type ExpectChain, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type ParticipantDetail, type ParticipantSlot, type RegistryEntry, type StreamDef, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type ZodFactory, createChatTools, defineExperience, defineStream, defineTest, defineTool };
184
+ export { type AgentSlot, type CallToolFn, type CanvasProps, type ExpectChain, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type ParticipantDetail, type ParticipantSlot, type RegistryEntry, type StreamDef, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type ZodFactory, defineExperience, defineStream, defineTest, defineTool };
package/dist/index.d.ts CHANGED
@@ -181,26 +181,4 @@ declare function defineExperience(module: ExperienceModule & {
181
181
  initialState?: Record<string, any>;
182
182
  };
183
183
 
184
- /**
185
- * Chat tool factory for experiences.
186
- *
187
- * Messages are stored in shared state under `_chat` so agents
188
- * see them via the stop hook's /agent-context endpoint.
189
- *
190
- * Usage:
191
- * import { createChatTools } from "@vibevibes/sdk";
192
- * const tools = [...myTools, ...createChatTools(z)];
193
- *
194
- * // In Canvas: read sharedState._chat, send via callTool('_chat.send', { message })
195
- */
196
-
197
- type ChatMessage = {
198
- id: string;
199
- actorId: string;
200
- message: string;
201
- replyTo?: string;
202
- ts: number;
203
- };
204
- declare function createChatTools(z: ZodFactory): ToolDef[];
205
-
206
- export { type AgentSlot, type CallToolFn, type CanvasProps, type ChatMessage, type ExpectChain, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type ParticipantDetail, type ParticipantSlot, type RegistryEntry, type StreamDef, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type ZodFactory, createChatTools, defineExperience, defineStream, defineTest, defineTool };
184
+ export { type AgentSlot, type CallToolFn, type CanvasProps, type ExpectChain, type ExperienceManifest, type ExperienceModule, type ExperienceRegistry, type ParticipantDetail, type ParticipantSlot, type RegistryEntry, type StreamDef, type TestDef, type TestHelpers, type ToolCtx, type ToolDef, type ToolEvent, type ToolRisk, type ZodFactory, defineExperience, defineStream, defineTest, defineTool };
package/dist/index.js CHANGED
@@ -62,56 +62,7 @@ function defineExperience(module) {
62
62
  }
63
63
  };
64
64
  }
65
-
66
- // src/chat.ts
67
- function uid() {
68
- return Math.random().toString(36).slice(2, 10) + Date.now().toString(36);
69
- }
70
- function capMessages(msgs, max = 200) {
71
- return msgs.length > max ? msgs.slice(-max) : msgs;
72
- }
73
- function createChatTools(z) {
74
- return [
75
- {
76
- name: "_chat.send",
77
- description: "Send a chat message",
78
- input_schema: z.object({
79
- message: z.string().min(1).max(2e3),
80
- replyTo: z.string().optional()
81
- }),
82
- risk: "low",
83
- capabilities_required: ["state.write"],
84
- handler: async (ctx, input) => {
85
- const cleanMessage = input.message.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g, "");
86
- const messages = capMessages([
87
- ...ctx.state._chat || [],
88
- {
89
- id: uid(),
90
- actorId: ctx.actorId,
91
- message: cleanMessage,
92
- replyTo: input.replyTo,
93
- ts: ctx.timestamp
94
- }
95
- ]);
96
- ctx.setState({ ...ctx.state, _chat: messages });
97
- return { sent: true, messageCount: messages.length };
98
- }
99
- },
100
- {
101
- name: "_chat.clear",
102
- description: "Clear all chat messages",
103
- input_schema: z.object({}),
104
- risk: "medium",
105
- capabilities_required: ["state.write"],
106
- handler: async (ctx) => {
107
- ctx.setState({ ...ctx.state, _chat: [] });
108
- return { cleared: true };
109
- }
110
- }
111
- ];
112
- }
113
65
  export {
114
- createChatTools,
115
66
  defineExperience,
116
67
  defineStream,
117
68
  defineTest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibevibes/sdk",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Define shared human-AI experiences — tools, canvas, state",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",