@cf-vibesdk/sdk 0.0.6 → 0.0.8
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 +78 -1
- package/dist/index.d.ts +335 -37
- package/dist/index.js +155 -11
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -96,13 +96,21 @@ const session = await client.build('Build a weather dashboard', {
|
|
|
96
96
|
|
|
97
97
|
### `client.connect(agentId)`
|
|
98
98
|
|
|
99
|
-
Connect to an existing app session.
|
|
99
|
+
Connect to an existing app session. State is automatically restored from the agent, including:
|
|
100
|
+
- Phase timeline with completion status
|
|
101
|
+
- Generated files
|
|
102
|
+
- Agent metadata (query, projectName, behaviorType, etc.)
|
|
100
103
|
|
|
101
104
|
```ts
|
|
102
105
|
const session = await client.connect('agent-id-here', {
|
|
103
106
|
credentials: { ... }, // Optional
|
|
104
107
|
});
|
|
105
108
|
await session.connect();
|
|
109
|
+
|
|
110
|
+
// State is now seeded from the agent
|
|
111
|
+
console.log('Original query:', session.state.get().query);
|
|
112
|
+
console.log('Phases:', session.phases.list());
|
|
113
|
+
console.log('Files:', session.files.listPaths());
|
|
106
114
|
```
|
|
107
115
|
|
|
108
116
|
## App Management
|
|
@@ -215,6 +223,53 @@ const snapshot = session.files.snapshot(); // { 'src/App.tsx': '...', ... }
|
|
|
215
223
|
const tree = session.files.tree(); // Nested file tree structure
|
|
216
224
|
```
|
|
217
225
|
|
|
226
|
+
### Phase Timeline
|
|
227
|
+
|
|
228
|
+
Access the full phase timeline for phasic builds. The timeline is automatically seeded when connecting to an existing agent and updated as phases progress.
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
// Get all phases
|
|
232
|
+
const phases = session.phases.list();
|
|
233
|
+
// [{ id: 'phase-0', name: 'Core Setup', status: 'completed', files: [...] }, ...]
|
|
234
|
+
|
|
235
|
+
// Get current active phase
|
|
236
|
+
const current = session.phases.current();
|
|
237
|
+
if (current) {
|
|
238
|
+
console.log(`Working on: ${current.name}`);
|
|
239
|
+
console.log(`Status: ${current.status}`); // 'generating' | 'implementing' | 'validating'
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Get completed phases
|
|
243
|
+
const done = session.phases.completed();
|
|
244
|
+
console.log(`Progress: ${done.length}/${session.phases.count()}`);
|
|
245
|
+
|
|
246
|
+
// Check if all phases are done
|
|
247
|
+
if (session.phases.allCompleted()) {
|
|
248
|
+
console.log('Build complete!');
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// Get phase by ID
|
|
252
|
+
const phase = session.phases.get('phase-0');
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Each phase contains:
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
type PhaseInfo = {
|
|
259
|
+
id: string; // 'phase-0', 'phase-1', etc.
|
|
260
|
+
name: string; // 'Core Setup', 'Authentication', etc.
|
|
261
|
+
description: string; // What the phase accomplishes
|
|
262
|
+
status: PhaseStatus; // 'pending' | 'generating' | 'implementing' | 'validating' | 'completed' | 'cancelled'
|
|
263
|
+
files: PhaseFile[]; // Files in this phase
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
type PhaseFile = {
|
|
267
|
+
path: string; // 'src/App.tsx'
|
|
268
|
+
purpose: string; // 'Main application component'
|
|
269
|
+
status: PhaseFileStatus; // 'pending' | 'generating' | 'completed' | 'cancelled'
|
|
270
|
+
};
|
|
271
|
+
```
|
|
272
|
+
|
|
218
273
|
### State
|
|
219
274
|
|
|
220
275
|
```ts
|
|
@@ -226,6 +281,16 @@ console.log(state.phase); // { status: 'idle' | 'generating' | ... }
|
|
|
226
281
|
console.log(state.preview); // Preview deployment state
|
|
227
282
|
console.log(state.cloudflare); // Cloudflare deployment state
|
|
228
283
|
|
|
284
|
+
// Phase timeline (array of all phases)
|
|
285
|
+
console.log(state.phases); // [{ id, name, status, files }, ...]
|
|
286
|
+
|
|
287
|
+
// Agent metadata (seeded from agent_connected)
|
|
288
|
+
console.log(state.behaviorType); // 'phasic' | 'agentic'
|
|
289
|
+
console.log(state.projectType); // 'app' | 'workflow' | etc.
|
|
290
|
+
console.log(state.query); // Original user prompt
|
|
291
|
+
console.log(state.projectName); // Project name from blueprint
|
|
292
|
+
console.log(state.shouldBeGenerating); // Whether agent is actively generating
|
|
293
|
+
|
|
229
294
|
// Subscribe to changes
|
|
230
295
|
session.state.onChange((next, prev) => {
|
|
231
296
|
console.log('State changed:', next);
|
|
@@ -324,10 +389,22 @@ All types are exported:
|
|
|
324
389
|
|
|
325
390
|
```ts
|
|
326
391
|
import type {
|
|
392
|
+
// Client & Session
|
|
327
393
|
VibeClientOptions,
|
|
328
394
|
BuildOptions,
|
|
329
395
|
BuildSession,
|
|
330
396
|
SessionState,
|
|
397
|
+
SessionFiles,
|
|
398
|
+
SessionPhases,
|
|
399
|
+
|
|
400
|
+
// Phase Timeline
|
|
401
|
+
PhaseInfo,
|
|
402
|
+
PhaseFile,
|
|
403
|
+
PhaseStatus,
|
|
404
|
+
PhaseFileStatus,
|
|
405
|
+
PhaseEventType,
|
|
406
|
+
|
|
407
|
+
// API
|
|
331
408
|
ApiResponse,
|
|
332
409
|
AppDetails,
|
|
333
410
|
Credentials,
|
package/dist/index.d.ts
CHANGED
|
@@ -5107,42 +5107,234 @@ declare const systemSettings: import("drizzle-orm/sqlite-core").SQLiteTableWithC
|
|
|
5107
5107
|
};
|
|
5108
5108
|
dialect: "sqlite";
|
|
5109
5109
|
}>;
|
|
5110
|
-
type User =
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
type
|
|
5135
|
-
type
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5110
|
+
type User = {
|
|
5111
|
+
id: string;
|
|
5112
|
+
email: string;
|
|
5113
|
+
username: string | null;
|
|
5114
|
+
displayName: string;
|
|
5115
|
+
avatarUrl: string | null;
|
|
5116
|
+
bio: string | null;
|
|
5117
|
+
provider: string;
|
|
5118
|
+
providerId: string;
|
|
5119
|
+
emailVerified: boolean | null;
|
|
5120
|
+
passwordHash: string | null;
|
|
5121
|
+
failedLoginAttempts: number | null;
|
|
5122
|
+
lockedUntil: Date | null;
|
|
5123
|
+
passwordChangedAt: Date | null;
|
|
5124
|
+
preferences: unknown | null;
|
|
5125
|
+
theme: "system" | "light" | "dark" | null;
|
|
5126
|
+
timezone: string | null;
|
|
5127
|
+
isActive: boolean | null;
|
|
5128
|
+
isSuspended: boolean | null;
|
|
5129
|
+
createdAt: Date | null;
|
|
5130
|
+
updatedAt: Date | null;
|
|
5131
|
+
lastActiveAt: Date | null;
|
|
5132
|
+
deletedAt: Date | null;
|
|
5133
|
+
}
|
|
5134
|
+
type NewUser = Record<string, unknown>;
|
|
5135
|
+
type Session = {
|
|
5136
|
+
id: string;
|
|
5137
|
+
userId: string;
|
|
5138
|
+
deviceInfo: string | null;
|
|
5139
|
+
userAgent: string | null;
|
|
5140
|
+
ipAddress: string | null;
|
|
5141
|
+
isRevoked: boolean | null;
|
|
5142
|
+
revokedAt: Date | null;
|
|
5143
|
+
revokedReason: string | null;
|
|
5144
|
+
accessTokenHash: string;
|
|
5145
|
+
refreshTokenHash: string;
|
|
5146
|
+
expiresAt: Date;
|
|
5147
|
+
createdAt: Date | null;
|
|
5148
|
+
lastActivity: Date | null;
|
|
5149
|
+
}
|
|
5150
|
+
type NewSession = Record<string, unknown>;
|
|
5151
|
+
type ApiKey = {
|
|
5152
|
+
id: string;
|
|
5153
|
+
userId: string;
|
|
5154
|
+
name: string;
|
|
5155
|
+
keyHash: string;
|
|
5156
|
+
keyPreview: string;
|
|
5157
|
+
scopes: string;
|
|
5158
|
+
isActive: boolean | null;
|
|
5159
|
+
lastUsed: Date | null;
|
|
5160
|
+
requestCount: number | null;
|
|
5161
|
+
expiresAt: Date | null;
|
|
5162
|
+
createdAt: Date | null;
|
|
5163
|
+
updatedAt: Date | null;
|
|
5164
|
+
}
|
|
5165
|
+
type NewApiKey = Record<string, unknown>;
|
|
5166
|
+
type App = {
|
|
5167
|
+
id: string;
|
|
5168
|
+
title: string;
|
|
5169
|
+
description: string | null;
|
|
5170
|
+
iconUrl: string | null;
|
|
5171
|
+
originalPrompt: string;
|
|
5172
|
+
finalPrompt: string | null;
|
|
5173
|
+
framework: string | null;
|
|
5174
|
+
userId: string | null;
|
|
5175
|
+
sessionToken: string | null;
|
|
5176
|
+
visibility: "private" | "public";
|
|
5177
|
+
status: "completed" | "generating";
|
|
5178
|
+
deploymentId: string | null;
|
|
5179
|
+
githubRepositoryUrl: string | null;
|
|
5180
|
+
githubRepositoryVisibility: "private" | "public" | null;
|
|
5181
|
+
isArchived: boolean | null;
|
|
5182
|
+
isFeatured: boolean | null;
|
|
5183
|
+
version: number | null;
|
|
5184
|
+
parentAppId: string | null;
|
|
5185
|
+
screenshotUrl: string | null;
|
|
5186
|
+
screenshotCapturedAt: Date | null;
|
|
5187
|
+
createdAt: Date | null;
|
|
5188
|
+
updatedAt: Date | null;
|
|
5189
|
+
lastDeployedAt: Date | null;
|
|
5190
|
+
}
|
|
5191
|
+
type NewApp = Record<string, unknown>;
|
|
5192
|
+
type AppLike = {
|
|
5193
|
+
id: string;
|
|
5194
|
+
appId: string;
|
|
5195
|
+
userId: string;
|
|
5196
|
+
reactionType: string;
|
|
5197
|
+
createdAt: Date | null;
|
|
5198
|
+
}
|
|
5199
|
+
type NewAppLike = Record<string, unknown>;
|
|
5200
|
+
type CommentLike = {
|
|
5201
|
+
id: string;
|
|
5202
|
+
commentId: string;
|
|
5203
|
+
userId: string;
|
|
5204
|
+
reactionType: string;
|
|
5205
|
+
createdAt: Date | null;
|
|
5206
|
+
}
|
|
5207
|
+
type NewCommentLike = Record<string, unknown>;
|
|
5208
|
+
type AppComment = {
|
|
5209
|
+
id: string;
|
|
5210
|
+
appId: string;
|
|
5211
|
+
userId: string;
|
|
5212
|
+
content: string;
|
|
5213
|
+
parentCommentId: string | null;
|
|
5214
|
+
isEdited: boolean | null;
|
|
5215
|
+
isDeleted: boolean | null;
|
|
5216
|
+
createdAt: Date | null;
|
|
5217
|
+
updatedAt: Date | null;
|
|
5218
|
+
}
|
|
5219
|
+
type NewAppComment = Record<string, unknown>;
|
|
5220
|
+
type AppView = {
|
|
5221
|
+
id: string;
|
|
5222
|
+
appId: string;
|
|
5223
|
+
userId: string | null;
|
|
5224
|
+
sessionToken: string | null;
|
|
5225
|
+
ipAddressHash: string | null;
|
|
5226
|
+
referrer: string | null;
|
|
5227
|
+
userAgent: string | null;
|
|
5228
|
+
deviceType: string | null;
|
|
5229
|
+
viewedAt: Date | null;
|
|
5230
|
+
durationSeconds: number | null;
|
|
5231
|
+
}
|
|
5232
|
+
type NewAppView = Record<string, unknown>;
|
|
5233
|
+
type OAuthState = {
|
|
5234
|
+
id: string;
|
|
5235
|
+
state: string;
|
|
5236
|
+
provider: string;
|
|
5237
|
+
redirectUri: string | null;
|
|
5238
|
+
scopes: unknown | null;
|
|
5239
|
+
userId: string | null;
|
|
5240
|
+
codeVerifier: string | null;
|
|
5241
|
+
nonce: string | null;
|
|
5242
|
+
createdAt: Date | null;
|
|
5243
|
+
expiresAt: Date;
|
|
5244
|
+
isUsed: boolean | null;
|
|
5245
|
+
}
|
|
5246
|
+
type NewOAuthState = Record<string, unknown>;
|
|
5247
|
+
type SystemSetting = {
|
|
5248
|
+
id: string;
|
|
5249
|
+
key: string;
|
|
5250
|
+
value: unknown | null;
|
|
5251
|
+
description: string | null;
|
|
5252
|
+
updatedAt: Date | null;
|
|
5253
|
+
updatedBy: string | null;
|
|
5254
|
+
}
|
|
5255
|
+
type NewSystemSetting = Record<string, unknown>;
|
|
5256
|
+
type Favorite = {
|
|
5257
|
+
id: string;
|
|
5258
|
+
userId: string;
|
|
5259
|
+
appId: string;
|
|
5260
|
+
createdAt: Date | null;
|
|
5261
|
+
}
|
|
5262
|
+
type NewFavorite = Record<string, unknown>;
|
|
5263
|
+
type AuthAttempt = {
|
|
5264
|
+
id: number;
|
|
5265
|
+
identifier: string;
|
|
5266
|
+
attemptType: "login" | "register" | "oauth_google" | "oauth_github" | "refresh" | "reset_password";
|
|
5267
|
+
success: boolean;
|
|
5268
|
+
ipAddress: string;
|
|
5269
|
+
userAgent: string | null;
|
|
5270
|
+
attemptedAt: Date | null;
|
|
5271
|
+
}
|
|
5272
|
+
type NewAuthAttempt = Record<string, unknown>;
|
|
5273
|
+
type PasswordResetToken = {
|
|
5274
|
+
id: string;
|
|
5275
|
+
userId: string;
|
|
5276
|
+
tokenHash: string;
|
|
5277
|
+
expiresAt: Date;
|
|
5278
|
+
used: boolean | null;
|
|
5279
|
+
createdAt: Date | null;
|
|
5280
|
+
}
|
|
5281
|
+
type NewPasswordResetToken = Record<string, unknown>;
|
|
5282
|
+
type EmailVerificationToken = {
|
|
5283
|
+
id: string;
|
|
5284
|
+
userId: string;
|
|
5285
|
+
tokenHash: string;
|
|
5286
|
+
email: string;
|
|
5287
|
+
expiresAt: Date;
|
|
5288
|
+
used: boolean | null;
|
|
5289
|
+
createdAt: Date | null;
|
|
5290
|
+
}
|
|
5291
|
+
type NewEmailVerificationToken = Record<string, unknown>;
|
|
5292
|
+
type AuditLog = {
|
|
5293
|
+
id: string;
|
|
5294
|
+
userId: string | null;
|
|
5295
|
+
entityType: string;
|
|
5296
|
+
entityId: string;
|
|
5297
|
+
action: string;
|
|
5298
|
+
oldValues: unknown | null;
|
|
5299
|
+
newValues: unknown | null;
|
|
5300
|
+
ipAddress: string | null;
|
|
5301
|
+
userAgent: string | null;
|
|
5302
|
+
createdAt: Date | null;
|
|
5303
|
+
}
|
|
5304
|
+
type NewAuditLog = Record<string, unknown>;
|
|
5305
|
+
type UserModelConfig = {
|
|
5306
|
+
id: string;
|
|
5307
|
+
userId: string;
|
|
5308
|
+
agentActionName: string;
|
|
5309
|
+
modelName: string | null;
|
|
5310
|
+
maxTokens: number | null;
|
|
5311
|
+
temperature: number | null;
|
|
5312
|
+
reasoningEffort: "high" | "medium" | "low" | null;
|
|
5313
|
+
providerOverride: "cloudflare" | "direct" | null;
|
|
5314
|
+
fallbackModel: string | null;
|
|
5315
|
+
isActive: boolean | null;
|
|
5316
|
+
createdAt: Date | null;
|
|
5317
|
+
updatedAt: Date | null;
|
|
5318
|
+
}
|
|
5319
|
+
type NewUserModelConfig = Record<string, unknown>;
|
|
5320
|
+
type UserModelProvider = {
|
|
5321
|
+
id: string;
|
|
5322
|
+
userId: string;
|
|
5323
|
+
name: string;
|
|
5324
|
+
baseUrl: string;
|
|
5325
|
+
secretId: string | null;
|
|
5326
|
+
isActive: boolean | null;
|
|
5327
|
+
createdAt: Date | null;
|
|
5328
|
+
updatedAt: Date | null;
|
|
5329
|
+
}
|
|
5330
|
+
type NewUserModelProvider = Record<string, unknown>;
|
|
5331
|
+
type Star = {
|
|
5332
|
+
id: string;
|
|
5333
|
+
userId: string;
|
|
5334
|
+
appId: string;
|
|
5335
|
+
starredAt: Date | null;
|
|
5336
|
+
}
|
|
5337
|
+
type NewStar = Record<string, unknown>;
|
|
5146
5338
|
type Visibility = "private" | "public";
|
|
5147
5339
|
/**
|
|
5148
5340
|
* Standard pagination interface used across all services
|
|
@@ -5278,7 +5470,31 @@ export type BuildStartEvent = {
|
|
|
5278
5470
|
};
|
|
5279
5471
|
export type ApiResponse<T> = BaseApiResponse<T>;
|
|
5280
5472
|
/** Base App type with all fields (serialized for JSON) */
|
|
5281
|
-
type App$1 =
|
|
5473
|
+
type App$1 = {
|
|
5474
|
+
id: string;
|
|
5475
|
+
title: string;
|
|
5476
|
+
description: string | null;
|
|
5477
|
+
iconUrl: string | null;
|
|
5478
|
+
originalPrompt: string;
|
|
5479
|
+
finalPrompt: string | null;
|
|
5480
|
+
framework: string | null;
|
|
5481
|
+
userId: string | null;
|
|
5482
|
+
sessionToken: string | null;
|
|
5483
|
+
visibility: "private" | "public";
|
|
5484
|
+
status: "completed" | "generating";
|
|
5485
|
+
deploymentId: string | null;
|
|
5486
|
+
githubRepositoryUrl: string | null;
|
|
5487
|
+
githubRepositoryVisibility: "private" | "public" | null;
|
|
5488
|
+
isArchived: boolean | null;
|
|
5489
|
+
isFeatured: boolean | null;
|
|
5490
|
+
version: number | null;
|
|
5491
|
+
parentAppId: string | null;
|
|
5492
|
+
screenshotUrl: string | null;
|
|
5493
|
+
screenshotCapturedAt: string | null;
|
|
5494
|
+
createdAt: string | null;
|
|
5495
|
+
updatedAt: string | null;
|
|
5496
|
+
lastDeployedAt: string | null;
|
|
5497
|
+
};
|
|
5282
5498
|
/** App visibility setting */
|
|
5283
5499
|
export type AppVisibility = Visibility;
|
|
5284
5500
|
/** App with favorite status for user-specific queries */
|
|
@@ -5397,6 +5613,50 @@ export type PhaseEventType = "phase_generating" | "phase_generated" | "phase_imp
|
|
|
5397
5613
|
export type WaitForPhaseOptions = WaitOptions & {
|
|
5398
5614
|
type: PhaseEventType;
|
|
5399
5615
|
};
|
|
5616
|
+
/**
|
|
5617
|
+
* Status of a file within a phase.
|
|
5618
|
+
*/
|
|
5619
|
+
export type PhaseFileStatus = "pending" | "generating" | "completed" | "cancelled";
|
|
5620
|
+
/**
|
|
5621
|
+
* A file concept within a phase, with its generation status.
|
|
5622
|
+
* Extends platform's FileConceptType with status tracking.
|
|
5623
|
+
*/
|
|
5624
|
+
export type PhaseFile = Pick<FileConceptType, "path" | "purpose"> & {
|
|
5625
|
+
status: PhaseFileStatus;
|
|
5626
|
+
};
|
|
5627
|
+
/**
|
|
5628
|
+
* Status of a phase in the timeline.
|
|
5629
|
+
*/
|
|
5630
|
+
export type PhaseStatus = "pending" | "generating" | "implementing" | "validating" | "completed" | "cancelled";
|
|
5631
|
+
/**
|
|
5632
|
+
* A phase in the build timeline with its files and status.
|
|
5633
|
+
* Extends platform's PhaseConceptType with SDK-specific fields.
|
|
5634
|
+
*/
|
|
5635
|
+
export type PhaseInfo = Pick<PhaseConceptType, "name" | "description"> & {
|
|
5636
|
+
/** Unique identifier for this phase (e.g., "phase-0", "phase-1"). */
|
|
5637
|
+
id: string;
|
|
5638
|
+
/** Current status of the phase. */
|
|
5639
|
+
status: PhaseStatus;
|
|
5640
|
+
/** Files in this phase with their generation status. */
|
|
5641
|
+
files: PhaseFile[];
|
|
5642
|
+
};
|
|
5643
|
+
/**
|
|
5644
|
+
* High-level API for accessing phase timeline data.
|
|
5645
|
+
*/
|
|
5646
|
+
export type SessionPhases = {
|
|
5647
|
+
/** Get all phases in the timeline. */
|
|
5648
|
+
list: () => PhaseInfo[];
|
|
5649
|
+
/** Get the currently active phase (first non-completed phase), or undefined. */
|
|
5650
|
+
current: () => PhaseInfo | undefined;
|
|
5651
|
+
/** Get all completed phases. */
|
|
5652
|
+
completed: () => PhaseInfo[];
|
|
5653
|
+
/** Get a phase by its id (e.g., "phase-0"). */
|
|
5654
|
+
get: (id: string) => PhaseInfo | undefined;
|
|
5655
|
+
/** Get the total count of phases. */
|
|
5656
|
+
count: () => number;
|
|
5657
|
+
/** Check if all phases are completed. */
|
|
5658
|
+
allCompleted: () => boolean;
|
|
5659
|
+
};
|
|
5400
5660
|
export type SessionDeployable = {
|
|
5401
5661
|
files: number;
|
|
5402
5662
|
reason: "generation_complete" | "phase_validated";
|
|
@@ -5481,6 +5741,18 @@ export type SessionState = {
|
|
|
5481
5741
|
preview: PreviewDeploymentState;
|
|
5482
5742
|
cloudflare: CloudflareDeploymentState;
|
|
5483
5743
|
lastError?: string;
|
|
5744
|
+
/** Full phase timeline with status and files for each phase. */
|
|
5745
|
+
phases: PhaseInfo[];
|
|
5746
|
+
/** Behavior type of the agent (phasic or agentic). */
|
|
5747
|
+
behaviorType?: BehaviorType$1;
|
|
5748
|
+
/** Project type (app, workflow, presentation, general). */
|
|
5749
|
+
projectType?: ProjectType$1;
|
|
5750
|
+
/** Original user query that started this build. */
|
|
5751
|
+
query?: string;
|
|
5752
|
+
/** Whether the agent should be actively generating. */
|
|
5753
|
+
shouldBeGenerating?: boolean;
|
|
5754
|
+
/** Project name from the blueprint. */
|
|
5755
|
+
projectName?: string;
|
|
5484
5756
|
};
|
|
5485
5757
|
export declare class SessionStateStore {
|
|
5486
5758
|
private state;
|
|
@@ -5489,6 +5761,14 @@ export declare class SessionStateStore {
|
|
|
5489
5761
|
onChange(cb: (next: SessionState, prev: SessionState) => void): () => void;
|
|
5490
5762
|
setConnection(state: ConnectionState): void;
|
|
5491
5763
|
applyWsMessage(msg: AgentWsServerMessage): void;
|
|
5764
|
+
/**
|
|
5765
|
+
* Update the status of a file in the phase timeline.
|
|
5766
|
+
*/
|
|
5767
|
+
private updateFileStatus;
|
|
5768
|
+
/**
|
|
5769
|
+
* Update an existing phase or add a new one to the timeline.
|
|
5770
|
+
*/
|
|
5771
|
+
private updateOrAddPhase;
|
|
5492
5772
|
private setState;
|
|
5493
5773
|
clear(): void;
|
|
5494
5774
|
}
|
|
@@ -5559,6 +5839,24 @@ export declare class BuildSession {
|
|
|
5559
5839
|
readonly workspace: WorkspaceStore;
|
|
5560
5840
|
readonly state: SessionStateStore;
|
|
5561
5841
|
readonly files: SessionFiles;
|
|
5842
|
+
/**
|
|
5843
|
+
* High-level API for accessing the phase timeline.
|
|
5844
|
+
* Phases are seeded from agent_connected and updated on phase events.
|
|
5845
|
+
*/
|
|
5846
|
+
readonly phases: {
|
|
5847
|
+
/** Get all phases in the timeline. */
|
|
5848
|
+
list: () => PhaseInfo[];
|
|
5849
|
+
/** Get the currently active phase (first non-completed phase), or undefined. */
|
|
5850
|
+
current: () => PhaseInfo | undefined;
|
|
5851
|
+
/** Get all completed phases. */
|
|
5852
|
+
completed: () => PhaseInfo[];
|
|
5853
|
+
/** Get a phase by its id (e.g., "phase-0"). */
|
|
5854
|
+
get: (id: string) => PhaseInfo | undefined;
|
|
5855
|
+
/** Get the total count of phases. */
|
|
5856
|
+
count: () => number;
|
|
5857
|
+
/** Check if all phases are completed. */
|
|
5858
|
+
allCompleted: () => boolean;
|
|
5859
|
+
};
|
|
5562
5860
|
readonly wait: {
|
|
5563
5861
|
generationStarted: (options?: WaitOptions) => Promise<{
|
|
5564
5862
|
type: "generation_started";
|
package/dist/index.js
CHANGED
|
@@ -227,7 +227,8 @@ var INITIAL_STATE = {
|
|
|
227
227
|
generation: { status: "idle" },
|
|
228
228
|
phase: { status: "idle" },
|
|
229
229
|
preview: { status: "idle" },
|
|
230
|
-
cloudflare: { status: "idle" }
|
|
230
|
+
cloudflare: { status: "idle" },
|
|
231
|
+
phases: []
|
|
231
232
|
};
|
|
232
233
|
function extractPhaseInfo(msg) {
|
|
233
234
|
const phase = msg?.phase;
|
|
@@ -236,6 +237,51 @@ function extractPhaseInfo(msg) {
|
|
|
236
237
|
description: phase?.description
|
|
237
238
|
};
|
|
238
239
|
}
|
|
240
|
+
function extractPhaseFiles(msg) {
|
|
241
|
+
const phase = msg?.phase;
|
|
242
|
+
return phase?.files;
|
|
243
|
+
}
|
|
244
|
+
function isPhasicState(state) {
|
|
245
|
+
return state.behaviorType === "phasic" && "generatedPhases" in state;
|
|
246
|
+
}
|
|
247
|
+
function buildPhaseTimelineFromState(state, generatedFilesMap) {
|
|
248
|
+
if (!isPhasicState(state))
|
|
249
|
+
return [];
|
|
250
|
+
const isActivelyGenerating = state.shouldBeGenerating === true;
|
|
251
|
+
return state.generatedPhases.map((phase, index) => {
|
|
252
|
+
let status;
|
|
253
|
+
if (phase.completed) {
|
|
254
|
+
status = "completed";
|
|
255
|
+
} else if (!isActivelyGenerating) {
|
|
256
|
+
status = "cancelled";
|
|
257
|
+
} else {
|
|
258
|
+
status = "generating";
|
|
259
|
+
}
|
|
260
|
+
const files = phase.files.map((f) => {
|
|
261
|
+
const fileExists = f.path in generatedFilesMap;
|
|
262
|
+
let fileStatus;
|
|
263
|
+
if (fileExists) {
|
|
264
|
+
fileStatus = "completed";
|
|
265
|
+
} else if (!isActivelyGenerating) {
|
|
266
|
+
fileStatus = "cancelled";
|
|
267
|
+
} else {
|
|
268
|
+
fileStatus = "pending";
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
path: f.path,
|
|
272
|
+
purpose: f.purpose,
|
|
273
|
+
status: fileStatus
|
|
274
|
+
};
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
id: `phase-${index}`,
|
|
278
|
+
name: phase.name,
|
|
279
|
+
description: phase.description,
|
|
280
|
+
status,
|
|
281
|
+
files
|
|
282
|
+
};
|
|
283
|
+
});
|
|
284
|
+
}
|
|
239
285
|
|
|
240
286
|
class SessionStateStore {
|
|
241
287
|
state = INITIAL_STATE;
|
|
@@ -303,47 +349,90 @@ class SessionStateStore {
|
|
|
303
349
|
}
|
|
304
350
|
case "file_generating": {
|
|
305
351
|
const m = msg;
|
|
306
|
-
this.
|
|
352
|
+
const phasesWithGenerating = this.updateFileStatus(m.filePath, "generating");
|
|
353
|
+
this.setState({ currentFile: m.filePath, phases: phasesWithGenerating });
|
|
307
354
|
break;
|
|
308
355
|
}
|
|
309
356
|
case "file_generated": {
|
|
357
|
+
const m = msg;
|
|
358
|
+
const filePath = m.file?.filePath;
|
|
310
359
|
const prev = this.state.generation;
|
|
360
|
+
const phasesWithCompleted = filePath ? this.updateFileStatus(filePath, "completed") : this.state.phases;
|
|
311
361
|
if (prev.status === "running" || prev.status === "stopped") {
|
|
312
362
|
this.setState({
|
|
313
363
|
generation: { ...prev, filesGenerated: prev.filesGenerated + 1 },
|
|
314
|
-
currentFile: undefined
|
|
364
|
+
currentFile: undefined,
|
|
365
|
+
phases: phasesWithCompleted
|
|
315
366
|
});
|
|
367
|
+
} else {
|
|
368
|
+
this.setState({ phases: phasesWithCompleted, currentFile: undefined });
|
|
316
369
|
}
|
|
317
370
|
break;
|
|
318
371
|
}
|
|
319
372
|
case "phase_generating": {
|
|
320
373
|
const m = msg;
|
|
321
|
-
|
|
374
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
375
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
376
|
+
const phases = this.updateOrAddPhase(phaseInfo, "generating", phaseFiles);
|
|
377
|
+
this.setState({
|
|
378
|
+
phase: { status: "generating", ...phaseInfo },
|
|
379
|
+
phases
|
|
380
|
+
});
|
|
322
381
|
break;
|
|
323
382
|
}
|
|
324
383
|
case "phase_generated": {
|
|
325
384
|
const m = msg;
|
|
326
|
-
|
|
385
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
386
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
387
|
+
const phases = this.updateOrAddPhase(phaseInfo, "implementing", phaseFiles);
|
|
388
|
+
this.setState({
|
|
389
|
+
phase: { status: "generated", ...phaseInfo },
|
|
390
|
+
phases
|
|
391
|
+
});
|
|
327
392
|
break;
|
|
328
393
|
}
|
|
329
394
|
case "phase_implementing": {
|
|
330
395
|
const m = msg;
|
|
331
|
-
|
|
396
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
397
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
398
|
+
const phases = this.updateOrAddPhase(phaseInfo, "implementing", phaseFiles);
|
|
399
|
+
this.setState({
|
|
400
|
+
phase: { status: "implementing", ...phaseInfo },
|
|
401
|
+
phases
|
|
402
|
+
});
|
|
332
403
|
break;
|
|
333
404
|
}
|
|
334
405
|
case "phase_implemented": {
|
|
335
406
|
const m = msg;
|
|
336
|
-
|
|
407
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
408
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
409
|
+
const phases = this.updateOrAddPhase(phaseInfo, "validating", phaseFiles);
|
|
410
|
+
this.setState({
|
|
411
|
+
phase: { status: "implemented", ...phaseInfo },
|
|
412
|
+
phases
|
|
413
|
+
});
|
|
337
414
|
break;
|
|
338
415
|
}
|
|
339
416
|
case "phase_validating": {
|
|
340
417
|
const m = msg;
|
|
341
|
-
|
|
418
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
419
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
420
|
+
const phases = this.updateOrAddPhase(phaseInfo, "validating", phaseFiles);
|
|
421
|
+
this.setState({
|
|
422
|
+
phase: { status: "validating", ...phaseInfo },
|
|
423
|
+
phases
|
|
424
|
+
});
|
|
342
425
|
break;
|
|
343
426
|
}
|
|
344
427
|
case "phase_validated": {
|
|
345
428
|
const m = msg;
|
|
346
|
-
|
|
429
|
+
const phaseInfo = extractPhaseInfo(m);
|
|
430
|
+
const phaseFiles = extractPhaseFiles(m);
|
|
431
|
+
const phases = this.updateOrAddPhase(phaseInfo, "completed", phaseFiles);
|
|
432
|
+
this.setState({
|
|
433
|
+
phase: { status: "validated", ...phaseInfo },
|
|
434
|
+
phases
|
|
435
|
+
});
|
|
347
436
|
break;
|
|
348
437
|
}
|
|
349
438
|
case "deployment_started": {
|
|
@@ -394,9 +483,24 @@ class SessionStateStore {
|
|
|
394
483
|
}
|
|
395
484
|
case "agent_connected": {
|
|
396
485
|
const m = msg;
|
|
486
|
+
const agentState = m.state;
|
|
397
487
|
const previewUrl = m.previewUrl;
|
|
398
|
-
|
|
399
|
-
|
|
488
|
+
const phases = buildPhaseTimelineFromState(agentState, agentState.generatedFilesMap ?? {});
|
|
489
|
+
let generation = this.state.generation;
|
|
490
|
+
if (agentState.shouldBeGenerating) {
|
|
491
|
+
const filesGenerated = Object.keys(agentState.generatedFilesMap ?? {}).length;
|
|
492
|
+
generation = { status: "running", filesGenerated };
|
|
493
|
+
}
|
|
494
|
+
this.setState({
|
|
495
|
+
previewUrl,
|
|
496
|
+
phases,
|
|
497
|
+
generation,
|
|
498
|
+
behaviorType: agentState.behaviorType,
|
|
499
|
+
projectType: agentState.projectType,
|
|
500
|
+
query: agentState.query,
|
|
501
|
+
shouldBeGenerating: agentState.shouldBeGenerating,
|
|
502
|
+
projectName: agentState.projectName
|
|
503
|
+
});
|
|
400
504
|
break;
|
|
401
505
|
}
|
|
402
506
|
case "error": {
|
|
@@ -408,6 +512,38 @@ class SessionStateStore {
|
|
|
408
512
|
break;
|
|
409
513
|
}
|
|
410
514
|
}
|
|
515
|
+
updateFileStatus(filePath, status) {
|
|
516
|
+
return this.state.phases.map((phase) => ({
|
|
517
|
+
...phase,
|
|
518
|
+
files: phase.files.map((f) => f.path === filePath ? { ...f, status } : f)
|
|
519
|
+
}));
|
|
520
|
+
}
|
|
521
|
+
updateOrAddPhase(phaseInfo, status, phaseFiles) {
|
|
522
|
+
const phases = [...this.state.phases];
|
|
523
|
+
const existingIndex = phases.findIndex((p) => p.name === phaseInfo.name);
|
|
524
|
+
const files = (phaseFiles ?? []).map((f) => ({
|
|
525
|
+
path: f.path,
|
|
526
|
+
purpose: f.purpose,
|
|
527
|
+
status: status === "completed" ? "completed" : "generating"
|
|
528
|
+
}));
|
|
529
|
+
if (existingIndex >= 0) {
|
|
530
|
+
phases[existingIndex] = {
|
|
531
|
+
...phases[existingIndex],
|
|
532
|
+
status,
|
|
533
|
+
description: phaseInfo.description ?? phases[existingIndex].description,
|
|
534
|
+
files: files.length > 0 ? files : phases[existingIndex].files
|
|
535
|
+
};
|
|
536
|
+
} else if (phaseInfo.name) {
|
|
537
|
+
phases.push({
|
|
538
|
+
id: `phase-${phases.length}`,
|
|
539
|
+
name: phaseInfo.name,
|
|
540
|
+
description: phaseInfo.description ?? "",
|
|
541
|
+
status,
|
|
542
|
+
files
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
return phases;
|
|
546
|
+
}
|
|
411
547
|
setState(patch) {
|
|
412
548
|
const prev = this.state;
|
|
413
549
|
const next = { ...prev, ...patch };
|
|
@@ -804,6 +940,14 @@ class BuildSession {
|
|
|
804
940
|
snapshot: () => this.workspace.snapshot(),
|
|
805
941
|
tree: () => buildFileTree(this.workspace.paths())
|
|
806
942
|
};
|
|
943
|
+
phases = {
|
|
944
|
+
list: () => this.state.get().phases,
|
|
945
|
+
current: () => this.state.get().phases.find((p) => p.status !== "completed" && p.status !== "cancelled"),
|
|
946
|
+
completed: () => this.state.get().phases.filter((p) => p.status === "completed"),
|
|
947
|
+
get: (id) => this.state.get().phases.find((p) => p.id === id),
|
|
948
|
+
count: () => this.state.get().phases.length,
|
|
949
|
+
allCompleted: () => this.state.get().phases.length > 0 && this.state.get().phases.every((p) => p.status === "completed")
|
|
950
|
+
};
|
|
807
951
|
wait = {
|
|
808
952
|
generationStarted: (options = {}) => this.waitForGenerationStarted(options),
|
|
809
953
|
generationComplete: (options = {}) => this.waitForGenerationComplete(options),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cf-vibesdk/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -19,10 +19,11 @@
|
|
|
19
19
|
},
|
|
20
20
|
"scripts": {
|
|
21
21
|
"build": "rm -rf ./dist && bun build ./src/index.ts --outdir ./dist --target browser",
|
|
22
|
-
"bundle-types": "dts-bundle-generator --export-referenced-types false --no-check --project ./tsconfig.protocol.json -o ./dist/index.d.ts ./src/index.ts",
|
|
22
|
+
"bundle-types": "dts-bundle-generator --export-referenced-types false --no-check --project ./tsconfig.protocol.json -o ./dist/index.d.ts ./src/index.ts && bun run scripts/expand-drizzle-types.ts",
|
|
23
23
|
"typecheck": "tsc -p ./tsconfig.json --noEmit",
|
|
24
24
|
"test": "bun test test/*.test.ts",
|
|
25
|
-
"test:integration": "bun test --timeout 600000 test/integration/*.test.ts"
|
|
25
|
+
"test:integration": "bun test --timeout 600000 test/integration/*.test.ts",
|
|
26
|
+
"package": "bun run typecheck && bun run test && bun run build && bun run bundle-types"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"@cloudflare/workers-types": "^4.20241218.0",
|