@cf-vibesdk/sdk 0.0.4 → 0.0.5

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,140 +1,354 @@
1
1
  # @cf-vibesdk/sdk
2
2
 
3
- Client SDK for the VibeSDK platform.
3
+ Official TypeScript SDK for the VibeSDK platform - build and deploy fullstack apps with AI.
4
4
 
5
- ## Install
5
+ ## Compatibility
6
+
7
+ Works in any JavaScript runtime with native WebSocket support:
8
+
9
+ | Runtime | Support |
10
+ |---------|---------|
11
+ | Cloudflare Workers | Native WebSocket |
12
+ | Browsers | Native WebSocket |
13
+ | Bun | Native WebSocket |
14
+ | Node.js 22+ | Native WebSocket |
15
+
16
+ ## Installation
6
17
 
7
18
  ```bash
8
19
  npm install @cf-vibesdk/sdk
9
20
  ```
10
21
 
11
- ## Quickstart (Bun)
22
+ ## Quick Start
12
23
 
13
24
  ```ts
14
25
  import { PhasicClient } from '@cf-vibesdk/sdk';
15
26
 
16
27
  const client = new PhasicClient({
17
- baseUrl: 'http://localhost:5173',
28
+ baseUrl: 'https://build.cloudflare.dev',
18
29
  apiKey: process.env.VIBESDK_API_KEY!,
19
30
  });
20
31
 
21
- const session = await client.build('Build a simple hello world page.', {
22
- projectType: 'app',
23
- autoGenerate: true,
24
- });
32
+ // Build a new app
33
+ const session = await client.build('Build a todo app with React');
25
34
 
26
- // High-level lifecycle waits
27
- await session.wait.generationStarted();
35
+ // Wait until deployable and deploy
28
36
  await session.wait.deployable();
29
-
30
- // Preview deployment (command + awaitable)
31
- const previewWait = session.wait.previewDeployed();
32
37
  session.deployPreview();
33
- const deployed = await previewWait;
38
+ const preview = await session.wait.previewDeployed();
34
39
 
35
- console.log('Preview URL:', deployed.previewURL);
36
-
37
- // Workspace is always kept in sync from agent state + WS events
38
- console.log(session.files.listPaths());
39
- console.log(session.files.read('README.md'));
40
+ console.log('Preview URL:', preview.previewURL);
41
+ console.log('Files:', session.files.listPaths());
40
42
 
41
43
  session.close();
42
44
  ```
43
45
 
44
- ## Quickstart (Node)
46
+ ## Authentication
45
47
 
46
- Node requires a WebSocket factory (the browser `WebSocket` global is not available):
48
+ | Method | Use Case |
49
+ |--------|----------|
50
+ | `apiKey` | Recommended. Automatically exchanged for a short-lived JWT. |
51
+ | `token` | Use when you already have a JWT access token. |
47
52
 
48
53
  ```ts
49
- import { PhasicClient } from '@cf-vibesdk/sdk';
50
- import { createNodeWebSocketFactory } from '@cf-vibesdk/sdk/node';
54
+ // Using API key (recommended)
55
+ const client = new PhasicClient({
56
+ baseUrl: 'https://build.cloudflare.dev',
57
+ apiKey: 'vibe_xxxxxxxxxxxx',
58
+ });
51
59
 
60
+ // Using pre-minted JWT
52
61
  const client = new PhasicClient({
53
- baseUrl: 'http://localhost:5173',
54
- apiKey: process.env.VIBESDK_API_KEY!,
55
- webSocketFactory: createNodeWebSocketFactory(),
62
+ baseUrl: 'https://build.cloudflare.dev',
63
+ token: 'eyJhbGciOiJIUzI1NiIs...',
56
64
  });
65
+ ```
66
+
67
+ ## Clients
68
+
69
+ | Client | Default Behavior |
70
+ |--------|------------------|
71
+ | `VibeClient` | No default - specify `behaviorType` in build options |
72
+ | `PhasicClient` | `behaviorType: 'phasic'` (phase-based generation) |
73
+ | `AgenticClient` | `behaviorType: 'agentic'` (autonomous agent) |
74
+
75
+ All clients share the same API. The specialized clients simply set a default `behaviorType`.
57
76
 
58
- const session = await client.build('Build a simple hello world page.', {
59
- projectType: 'app',
60
- autoGenerate: true,
77
+ ## Building Apps
78
+
79
+ ### `client.build(prompt, options?)`
80
+
81
+ Create a new app from a natural language prompt.
82
+
83
+ ```ts
84
+ const session = await client.build('Build a weather dashboard', {
85
+ projectType: 'app', // 'app' | 'component' | 'api'
86
+ behaviorType: 'phasic', // 'phasic' | 'agentic'
87
+ language: 'typescript', // Optional
88
+ frameworks: ['react'], // Optional
89
+ selectedTemplate: 'vite', // Optional template name
90
+ autoConnect: true, // Auto-connect WebSocket (default: true)
91
+ autoGenerate: true, // Auto-start generation (default: true)
92
+ credentials: { ... }, // Optional provider API keys
93
+ onBlueprintChunk: (chunk) => console.log(chunk),
61
94
  });
95
+ ```
62
96
 
63
- await session.wait.generationStarted();
64
- await session.wait.deployable();
65
- session.close();
97
+ ### `client.connect(agentId)`
98
+
99
+ Connect to an existing app session.
100
+
101
+ ```ts
102
+ const session = await client.connect('agent-id-here', {
103
+ credentials: { ... }, // Optional
104
+ });
105
+ await session.connect();
66
106
  ```
67
107
 
68
- ## Authentication
108
+ ## App Management
69
109
 
70
- Use either:
110
+ ```ts
111
+ // List apps
112
+ const publicApps = await client.apps.listPublic({ limit: 20, sort: 'recent' });
113
+ const myApps = await client.apps.listMine();
114
+ const recent = await client.apps.listRecent();
115
+ const favorites = await client.apps.listFavorites();
116
+
117
+ // Get app details
118
+ const app = await client.apps.get('app-id');
119
+
120
+ // Manage apps
121
+ await client.apps.delete('app-id');
122
+ await client.apps.setVisibility('app-id', 'public'); // 'public' | 'private'
123
+ await client.apps.toggleStar('app-id');
124
+ await client.apps.toggleFavorite('app-id');
125
+
126
+ // Git clone token
127
+ const { cloneUrl, expiresAt } = await client.apps.getGitCloneToken('app-id');
128
+ ```
71
129
 
72
- - `apiKey`: a VibeSDK API key (recommended for CLIs and automation)
73
- - `token`: an already-minted JWT access token
130
+ ## BuildSession
74
131
 
75
- When `apiKey` is provided, the SDK exchanges it for a short-lived access token and caches it.
132
+ The `BuildSession` object provides real-time interaction with code generation.
76
133
 
77
- ## Workspace (no platform file APIs)
134
+ ### Properties
78
135
 
79
- The SDK reconstructs and maintains a local view of the codebase using:
136
+ | Property | Description |
137
+ |----------|-------------|
138
+ | `agentId` | Unique identifier for this session |
139
+ | `behaviorType` | `'phasic'` or `'agentic'` |
140
+ | `projectType` | Type of project being built |
80
141
 
81
- - `agent_connected.state.generatedFilesMap`
82
- - `cf_agent_state.state.generatedFilesMap`
83
- - incremental `file_*` messages
142
+ ### Commands
84
143
 
85
- APIs:
144
+ ```ts
145
+ session.startGeneration(); // Start code generation
146
+ session.stop(); // Stop generation
147
+ session.resume(); // Resume generation
148
+ session.deployPreview(); // Deploy to preview environment
149
+ session.deployCloudflare(); // Deploy to Cloudflare Workers
150
+ session.clearConversation(); // Clear conversation history
151
+ session.close(); // Close the session
152
+
153
+ // Send follow-up message
154
+ session.followUp('Add dark mode support', {
155
+ images: [{ base64: '...', mimeType: 'image/png' }], // Optional
156
+ });
157
+ ```
86
158
 
87
- - `session.files.listPaths()`
88
- - `session.files.read(path)`
89
- - `session.files.snapshot()`
90
- - `session.files.tree()`
159
+ ### Wait Helpers
91
160
 
92
- ## Waiting primitives
161
+ High-level async waits for generation milestones:
93
162
 
94
- Use high-level waits instead of depending on agent-internal message ordering:
163
+ ```ts
164
+ // Generation lifecycle
165
+ await session.wait.generationStarted({ timeoutMs: 60_000 });
166
+ await session.wait.generationComplete({ timeoutMs: 600_000 });
95
167
 
96
- - `session.wait.generationStarted()`
97
- - `session.wait.generationComplete()`
98
- - `session.wait.deployable()` (phasic resolves on `phase_validated`)
99
- - `session.wait.previewDeployed()`
100
- - `session.wait.cloudflareDeployed()`
168
+ // Phase events (phasic mode)
169
+ await session.wait.phase({ type: 'phase_validated' });
101
170
 
102
- All waits default to a long timeout (10 minutes). You can override per call:
171
+ // Deployment readiness
172
+ const { files, reason } = await session.wait.deployable();
173
+
174
+ // Deployment completion
175
+ const preview = await session.wait.previewDeployed();
176
+ console.log(preview.previewURL);
177
+
178
+ const cf = await session.wait.cloudflareDeployed();
179
+ console.log(cf.deploymentUrl);
180
+ ```
181
+
182
+ ### Events
103
183
 
104
184
  ```ts
105
- await session.wait.generationComplete({ timeoutMs: 2 * 60_000 });
185
+ // High-level events
186
+ session.on('connected', (msg) => { ... });
187
+ session.on('generation', (msg) => { ... }); // started, complete, stopped, resumed
188
+ session.on('phase', (msg) => { ... }); // generating, generated, implementing, etc.
189
+ session.on('file', (msg) => { ... }); // generating, generated, regenerated
190
+ session.on('preview', (msg) => { ... }); // started, completed, failed
191
+ session.on('cloudflare', (msg) => { ... }); // started, completed, error
192
+ session.on('error', ({ error }) => { ... });
193
+
194
+ // WebSocket events
195
+ session.on('ws:open', () => { ... });
196
+ session.on('ws:close', ({ code, reason }) => { ... });
197
+ session.on('ws:error', ({ error }) => { ... });
198
+ session.on('ws:reconnecting', ({ attempt, delayMs }) => { ... });
199
+
200
+ // Listen to specific message type
201
+ session.onMessageType('file_generated', (msg) => {
202
+ console.log('Generated:', msg.file.filePath);
203
+ });
204
+
205
+ // Wait for specific message
206
+ const msg = await session.waitForMessageType('generation_complete', 60_000);
106
207
  ```
107
208
 
108
- ## Reliable WebSocket connections
209
+ ### File Access
109
210
 
110
- Connections automatically reconnect with exponential backoff + jitter.
211
+ ```ts
212
+ const paths = session.files.listPaths(); // ['src/App.tsx', ...]
213
+ const content = session.files.read('src/App.tsx');
214
+ const snapshot = session.files.snapshot(); // { 'src/App.tsx': '...', ... }
215
+ const tree = session.files.tree(); // Nested file tree structure
216
+ ```
217
+
218
+ ### State
219
+
220
+ ```ts
221
+ // Current state
222
+ const state = session.state.get();
223
+ console.log(state.connection); // 'disconnected' | 'connecting' | 'connected'
224
+ console.log(state.generation); // { status: 'idle' | 'running' | 'stopped' | 'complete', ... }
225
+ console.log(state.phase); // { status: 'idle' | 'generating' | ... }
226
+ console.log(state.preview); // Preview deployment state
227
+ console.log(state.cloudflare); // Cloudflare deployment state
228
+
229
+ // Subscribe to changes
230
+ session.state.onChange((next, prev) => {
231
+ console.log('State changed:', next);
232
+ });
233
+
234
+ // Workspace file changes
235
+ session.workspace.onChange((change) => {
236
+ console.log(change.type, change.path); // 'upsert' | 'delete' | 'reset'
237
+ });
238
+ ```
239
+
240
+ ## WebSocket Reliability
241
+
242
+ Connections automatically reconnect with exponential backoff.
243
+
244
+ ```ts
245
+ // Custom retry config
246
+ await session.connect({
247
+ retry: {
248
+ enabled: true, // Default: true
249
+ initialDelayMs: 1000, // Default: 1000
250
+ maxDelayMs: 30000, // Default: 30000
251
+ maxRetries: 10, // Default: Infinity
252
+ },
253
+ });
254
+
255
+ // Disable auto-reconnect
256
+ await session.connect({ retry: { enabled: false } });
257
+ ```
258
+
259
+ ## HTTP Retry
260
+
261
+ HTTP requests automatically retry on 5xx errors.
262
+
263
+ ```ts
264
+ const client = new PhasicClient({
265
+ baseUrl: 'https://build.cloudflare.dev',
266
+ apiKey: 'vibe_xxx',
267
+ retry: {
268
+ enabled: true, // Default: true
269
+ initialDelayMs: 1000, // Default: 1000
270
+ maxDelayMs: 10000, // Default: 10000
271
+ maxRetries: 3, // Default: 3
272
+ },
273
+ });
274
+ ```
275
+
276
+ ## Utilities
111
277
 
112
- Events:
278
+ ### Blueprint Parsing
113
279
 
114
- - `session.on('ws:reconnecting', ({ attempt, delayMs, reason }) => { ... })`
280
+ ```ts
281
+ import { BlueprintStreamParser, blueprintToMarkdown } from '@cf-vibesdk/sdk';
282
+
283
+ // Parse streaming blueprint chunks
284
+ const parser = new BlueprintStreamParser();
285
+ parser.append(chunk1);
286
+ parser.append(chunk2);
287
+ const markdown = parser.toMarkdown();
115
288
 
116
- To disable reconnect:
289
+ // Convert blueprint object to markdown
290
+ const md = blueprintToMarkdown(blueprint);
291
+ ```
292
+
293
+ ### Timeout Helper
117
294
 
118
295
  ```ts
119
- session.connect({ retry: { enabled: false } });
296
+ import { withTimeout, TimeoutError } from '@cf-vibesdk/sdk';
297
+
298
+ try {
299
+ const result = await withTimeout(someAsyncOperation(), 30000, 'Operation timed out');
300
+ } catch (e) {
301
+ if (e instanceof TimeoutError) {
302
+ console.log('Timed out!');
303
+ }
304
+ }
120
305
  ```
121
306
 
122
- ## Low-level access
307
+ ## Error Handling
123
308
 
124
- For advanced clients, you can subscribe to the raw typed WS stream:
309
+ All API methods return an `ApiResponse<T>` discriminated union:
125
310
 
126
- - `session.on('ws:message', (msg) => { ... })`
311
+ ```ts
312
+ const result = await client.apps.get('app-id');
127
313
 
128
- The SDK also exposes `ws:raw` when the platform sends malformed/untyped payloads.
314
+ if (result.success) {
315
+ console.log(result.data);
316
+ } else {
317
+ console.error(result.error.message);
318
+ }
319
+ ```
320
+
321
+ ## TypeScript
322
+
323
+ All types are exported:
129
324
 
130
- ## Tests
325
+ ```ts
326
+ import type {
327
+ VibeClientOptions,
328
+ BuildOptions,
329
+ BuildSession,
330
+ SessionState,
331
+ ApiResponse,
332
+ AppDetails,
333
+ Credentials,
334
+ BehaviorType,
335
+ ProjectType,
336
+ // ... and more
337
+ } from '@cf-vibesdk/sdk';
338
+ ```
131
339
 
132
- From `sdk/`:
340
+ ## Testing
133
341
 
134
- - Unit: `bun run test`
135
- - Integration (requires local platform + API key): `bun run test:integration`
342
+ ```bash
343
+ cd sdk
344
+
345
+ # Unit tests
346
+ bun test
347
+
348
+ # Integration tests (requires API key)
349
+ VIBESDK_INTEGRATION_API_KEY=your_key bun run test:integration
350
+ ```
136
351
 
137
- Integration expects:
352
+ ## License
138
353
 
139
- - `VIBESDK_INTEGRATION_API_KEY`
140
- - optional `VIBESDK_INTEGRATION_BASE_URL` (default `http://localhost:5173`)
354
+ MIT