@cf-vibesdk/sdk 0.0.3 → 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 +287 -73
- package/dist/index.d.ts +176 -59
- package/dist/index.js +261 -95
- package/package.json +12 -14
- package/dist/node.d.ts +0 -77
- package/dist/node.js +0 -12
package/README.md
CHANGED
|
@@ -1,140 +1,354 @@
|
|
|
1
1
|
# @cf-vibesdk/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Official TypeScript SDK for the VibeSDK platform - build and deploy fullstack apps with AI.
|
|
4
4
|
|
|
5
|
-
##
|
|
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
|
-
##
|
|
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: '
|
|
28
|
+
baseUrl: 'https://build.cloudflare.dev',
|
|
18
29
|
apiKey: process.env.VIBESDK_API_KEY!,
|
|
19
30
|
});
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
autoGenerate: true,
|
|
24
|
-
});
|
|
32
|
+
// Build a new app
|
|
33
|
+
const session = await client.build('Build a todo app with React');
|
|
25
34
|
|
|
26
|
-
//
|
|
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
|
|
38
|
+
const preview = await session.wait.previewDeployed();
|
|
34
39
|
|
|
35
|
-
console.log('Preview URL:',
|
|
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
|
-
##
|
|
46
|
+
## Authentication
|
|
45
47
|
|
|
46
|
-
|
|
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
|
-
|
|
50
|
-
|
|
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: '
|
|
54
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
session.
|
|
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
|
-
##
|
|
108
|
+
## App Management
|
|
69
109
|
|
|
70
|
-
|
|
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
|
-
|
|
73
|
-
- `token`: an already-minted JWT access token
|
|
130
|
+
## BuildSession
|
|
74
131
|
|
|
75
|
-
|
|
132
|
+
The `BuildSession` object provides real-time interaction with code generation.
|
|
76
133
|
|
|
77
|
-
|
|
134
|
+
### Properties
|
|
78
135
|
|
|
79
|
-
|
|
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
|
-
|
|
82
|
-
- `cf_agent_state.state.generatedFilesMap`
|
|
83
|
-
- incremental `file_*` messages
|
|
142
|
+
### Commands
|
|
84
143
|
|
|
85
|
-
|
|
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
|
-
|
|
88
|
-
- `session.files.read(path)`
|
|
89
|
-
- `session.files.snapshot()`
|
|
90
|
-
- `session.files.tree()`
|
|
159
|
+
### Wait Helpers
|
|
91
160
|
|
|
92
|
-
|
|
161
|
+
High-level async waits for generation milestones:
|
|
93
162
|
|
|
94
|
-
|
|
163
|
+
```ts
|
|
164
|
+
// Generation lifecycle
|
|
165
|
+
await session.wait.generationStarted({ timeoutMs: 60_000 });
|
|
166
|
+
await session.wait.generationComplete({ timeoutMs: 600_000 });
|
|
95
167
|
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
209
|
+
### File Access
|
|
109
210
|
|
|
110
|
-
|
|
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
|
-
|
|
278
|
+
### Blueprint Parsing
|
|
113
279
|
|
|
114
|
-
|
|
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
|
-
|
|
289
|
+
// Convert blueprint object to markdown
|
|
290
|
+
const md = blueprintToMarkdown(blueprint);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Timeout Helper
|
|
117
294
|
|
|
118
295
|
```ts
|
|
119
|
-
|
|
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
|
-
##
|
|
307
|
+
## Error Handling
|
|
123
308
|
|
|
124
|
-
|
|
309
|
+
All API methods return an `ApiResponse<T>` discriminated union:
|
|
125
310
|
|
|
126
|
-
|
|
311
|
+
```ts
|
|
312
|
+
const result = await client.apps.get('app-id');
|
|
127
313
|
|
|
128
|
-
|
|
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
|
-
|
|
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
|
-
|
|
340
|
+
## Testing
|
|
133
341
|
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
352
|
+
## License
|
|
138
353
|
|
|
139
|
-
|
|
140
|
-
- optional `VIBESDK_INTEGRATION_BASE_URL` (default `http://localhost:5173`)
|
|
354
|
+
MIT
|