@cf-vibesdk/sdk 0.0.8 → 0.0.9
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 +20 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +38 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -250,6 +250,24 @@ if (session.phases.allCompleted()) {
|
|
|
250
250
|
|
|
251
251
|
// Get phase by ID
|
|
252
252
|
const phase = session.phases.get('phase-0');
|
|
253
|
+
|
|
254
|
+
// Subscribe to phase changes
|
|
255
|
+
const unsubscribe = session.phases.onChange((event) => {
|
|
256
|
+
console.log(`Phase ${event.type}:`, event.phase.name);
|
|
257
|
+
console.log(`Status: ${event.phase.status}`);
|
|
258
|
+
console.log(`Total phases: ${event.allPhases.length}`);
|
|
259
|
+
});
|
|
260
|
+
// Later: unsubscribe();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
The `onChange` callback receives a `PhaseTimelineEvent`:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
type PhaseTimelineEvent = {
|
|
267
|
+
type: 'added' | 'updated'; // New phase vs status/file change
|
|
268
|
+
phase: PhaseInfo; // The affected phase
|
|
269
|
+
allPhases: PhaseInfo[]; // All phases after this change
|
|
270
|
+
};
|
|
253
271
|
```
|
|
254
272
|
|
|
255
273
|
Each phase contains:
|
|
@@ -403,6 +421,8 @@ import type {
|
|
|
403
421
|
PhaseStatus,
|
|
404
422
|
PhaseFileStatus,
|
|
405
423
|
PhaseEventType,
|
|
424
|
+
PhaseTimelineEvent,
|
|
425
|
+
PhaseTimelineChangeType,
|
|
406
426
|
|
|
407
427
|
// API
|
|
408
428
|
ApiResponse,
|
package/dist/index.d.ts
CHANGED
|
@@ -5568,6 +5568,8 @@ export type AgentEventMap = {
|
|
|
5568
5568
|
error: {
|
|
5569
5569
|
error: string;
|
|
5570
5570
|
};
|
|
5571
|
+
/** Emitted when the phase timeline changes (phase added or updated). */
|
|
5572
|
+
phases: PhaseTimelineEvent;
|
|
5571
5573
|
};
|
|
5572
5574
|
/**
|
|
5573
5575
|
* URL provider for WebSocket connections.
|
|
@@ -5657,6 +5659,18 @@ export type SessionPhases = {
|
|
|
5657
5659
|
/** Check if all phases are completed. */
|
|
5658
5660
|
allCompleted: () => boolean;
|
|
5659
5661
|
};
|
|
5662
|
+
/**
|
|
5663
|
+
* Event emitted when the phase timeline changes.
|
|
5664
|
+
*/
|
|
5665
|
+
export type PhaseTimelineChangeType = "added" | "updated";
|
|
5666
|
+
export type PhaseTimelineEvent = {
|
|
5667
|
+
/** Type of change: 'added' for new phase, 'updated' for status/file changes. */
|
|
5668
|
+
type: PhaseTimelineChangeType;
|
|
5669
|
+
/** The phase that was added or updated. */
|
|
5670
|
+
phase: PhaseInfo;
|
|
5671
|
+
/** All phases in the timeline after this change. */
|
|
5672
|
+
allPhases: PhaseInfo[];
|
|
5673
|
+
};
|
|
5660
5674
|
export type SessionDeployable = {
|
|
5661
5675
|
files: number;
|
|
5662
5676
|
reason: "generation_complete" | "phase_validated";
|
|
@@ -5759,6 +5773,11 @@ export declare class SessionStateStore {
|
|
|
5759
5773
|
private emitter;
|
|
5760
5774
|
get(): SessionState;
|
|
5761
5775
|
onChange(cb: (next: SessionState, prev: SessionState) => void): () => void;
|
|
5776
|
+
/**
|
|
5777
|
+
* Subscribe to phase timeline changes.
|
|
5778
|
+
* Fires when a phase is added or when a phase's status/files change.
|
|
5779
|
+
*/
|
|
5780
|
+
onPhaseChange(cb: (event: PhaseTimelineEvent) => void): () => void;
|
|
5762
5781
|
setConnection(state: ConnectionState): void;
|
|
5763
5782
|
applyWsMessage(msg: AgentWsServerMessage): void;
|
|
5764
5783
|
/**
|
|
@@ -5770,6 +5789,14 @@ export declare class SessionStateStore {
|
|
|
5770
5789
|
*/
|
|
5771
5790
|
private updateOrAddPhase;
|
|
5772
5791
|
private setState;
|
|
5792
|
+
/**
|
|
5793
|
+
* Compare old and new phases arrays and emit change events.
|
|
5794
|
+
*/
|
|
5795
|
+
private emitPhaseChanges;
|
|
5796
|
+
/**
|
|
5797
|
+
* Check if a phase has meaningfully changed (status or file statuses).
|
|
5798
|
+
*/
|
|
5799
|
+
private hasPhaseChanged;
|
|
5773
5800
|
clear(): void;
|
|
5774
5801
|
}
|
|
5775
5802
|
type WorkspaceChange = {
|
|
@@ -5856,6 +5883,12 @@ export declare class BuildSession {
|
|
|
5856
5883
|
count: () => number;
|
|
5857
5884
|
/** Check if all phases are completed. */
|
|
5858
5885
|
allCompleted: () => boolean;
|
|
5886
|
+
/**
|
|
5887
|
+
* Subscribe to phase timeline changes.
|
|
5888
|
+
* Fires when a phase is added or when a phase's status/files change.
|
|
5889
|
+
* @returns Unsubscribe function.
|
|
5890
|
+
*/
|
|
5891
|
+
onChange: (cb: (event: PhaseTimelineEvent) => void) => (() => void);
|
|
5859
5892
|
};
|
|
5860
5893
|
readonly wait: {
|
|
5861
5894
|
generationStarted: (options?: WaitOptions) => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -292,6 +292,9 @@ class SessionStateStore {
|
|
|
292
292
|
onChange(cb) {
|
|
293
293
|
return this.emitter.on("change", ({ prev, next }) => cb(next, prev));
|
|
294
294
|
}
|
|
295
|
+
onPhaseChange(cb) {
|
|
296
|
+
return this.emitter.on("phaseChange", cb);
|
|
297
|
+
}
|
|
295
298
|
setConnection(state) {
|
|
296
299
|
this.setState({ connection: state });
|
|
297
300
|
}
|
|
@@ -524,7 +527,7 @@ class SessionStateStore {
|
|
|
524
527
|
const files = (phaseFiles ?? []).map((f) => ({
|
|
525
528
|
path: f.path,
|
|
526
529
|
purpose: f.purpose,
|
|
527
|
-
status: status === "completed" ? "completed" : "
|
|
530
|
+
status: status === "completed" ? "completed" : "pending"
|
|
528
531
|
}));
|
|
529
532
|
if (existingIndex >= 0) {
|
|
530
533
|
phases[existingIndex] = {
|
|
@@ -549,6 +552,38 @@ class SessionStateStore {
|
|
|
549
552
|
const next = { ...prev, ...patch };
|
|
550
553
|
this.state = next;
|
|
551
554
|
this.emitter.emit("change", { prev, next });
|
|
555
|
+
if (patch.phases && patch.phases !== prev.phases) {
|
|
556
|
+
this.emitPhaseChanges(prev.phases, patch.phases);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
emitPhaseChanges(prevPhases, nextPhases) {
|
|
560
|
+
for (const phase of nextPhases) {
|
|
561
|
+
const prevPhase = prevPhases.find((p) => p.id === phase.id);
|
|
562
|
+
if (!prevPhase) {
|
|
563
|
+
this.emitter.emit("phaseChange", {
|
|
564
|
+
type: "added",
|
|
565
|
+
phase,
|
|
566
|
+
allPhases: nextPhases
|
|
567
|
+
});
|
|
568
|
+
} else if (this.hasPhaseChanged(prevPhase, phase)) {
|
|
569
|
+
this.emitter.emit("phaseChange", {
|
|
570
|
+
type: "updated",
|
|
571
|
+
phase,
|
|
572
|
+
allPhases: nextPhases
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
hasPhaseChanged(prev, next) {
|
|
578
|
+
if (prev.status !== next.status)
|
|
579
|
+
return true;
|
|
580
|
+
if (prev.files.length !== next.files.length)
|
|
581
|
+
return true;
|
|
582
|
+
for (let i = 0;i < prev.files.length; i++) {
|
|
583
|
+
if (prev.files[i].status !== next.files[i].status)
|
|
584
|
+
return true;
|
|
585
|
+
}
|
|
586
|
+
return false;
|
|
552
587
|
}
|
|
553
588
|
clear() {
|
|
554
589
|
this.state = INITIAL_STATE;
|
|
@@ -946,7 +981,8 @@ class BuildSession {
|
|
|
946
981
|
completed: () => this.state.get().phases.filter((p) => p.status === "completed"),
|
|
947
982
|
get: (id) => this.state.get().phases.find((p) => p.id === id),
|
|
948
983
|
count: () => this.state.get().phases.length,
|
|
949
|
-
allCompleted: () => this.state.get().phases.length > 0 && this.state.get().phases.every((p) => p.status === "completed")
|
|
984
|
+
allCompleted: () => this.state.get().phases.length > 0 && this.state.get().phases.every((p) => p.status === "completed"),
|
|
985
|
+
onChange: (cb) => this.state.onPhaseChange(cb)
|
|
950
986
|
};
|
|
951
987
|
wait = {
|
|
952
988
|
generationStarted: (options = {}) => this.waitForGenerationStarted(options),
|