Skip to content

Commit 47eba5f

Browse files
committed
feat: enhance type exports and improve utility functions for better type safety
1 parent b9f0416 commit 47eba5f

File tree

6 files changed

+88
-37
lines changed

6 files changed

+88
-37
lines changed

sdk/src/index.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ export { BuildSession } from './session';
55
export { WorkspaceStore } from './workspace';
66
export { SessionStateStore } from './state';
77

8-
export { isRecord, blueprintToMarkdown, BlueprintStreamParser } from './blueprint';
8+
export { blueprintToMarkdown, BlueprintStreamParser } from './blueprint';
99
export type { Blueprint } from './blueprint';
1010

11-
export { withTimeout, TimeoutError } from './utils';
11+
export { isRecord, withTimeout, TimeoutError } from './utils';
12+
13+
export type { WebSocketFactory } from './ws';
1214

1315
export type {
1416
AgentConnection,
@@ -18,18 +20,23 @@ export type {
1820
ApiResponse,
1921
AppDetails,
2022
AppListItem,
23+
AppVisibility,
24+
AppWithFavoriteStatus,
2125
BehaviorType,
2226
BuildOptions,
2327
BuildStartEvent,
2428
CodeGenArgs,
2529
Credentials,
30+
DeleteResult,
2631
FileTreeNode,
2732
PhaseEventType,
2833
ProjectType,
2934
PublicAppsQuery,
3035
SessionDeployable,
3136
SessionFiles,
37+
ToggleResult,
3238
VibeClientOptions,
39+
VisibilityUpdateResult,
3340
WaitForPhaseOptions,
3441
WaitOptions,
3542
} from './types';

sdk/src/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ export type {
2323
CodeGenArgs as PlatformCodeGenArgs,
2424
AgentPreviewResponse,
2525
} from '../../worker/api/controllers/agent/types';
26+
27+
export type { ImageAttachment } from '../../worker/types/image-attachment';

sdk/src/session.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
BuildStartEvent,
77
Credentials,
88
FileTreeNode,
9+
ImageAttachment,
910
PhaseEventType,
1011
ProjectType,
1112
SessionDeployable,
@@ -183,7 +184,7 @@ export class BuildSession {
183184
this.connection!.send({ type: 'stop_generation' });
184185
}
185186

186-
followUp(message: string, options?: { images?: unknown[] }): void {
187+
followUp(message: string, options?: { images?: ImageAttachment[] }): void {
187188
this.assertConnected();
188189
this.connection!.send({
189190
type: 'user_suggestion',

sdk/src/types.ts

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,36 @@ import type {
33
ProjectType as PlatformProjectType,
44
PlatformCodeGenArgs,
55
WebSocketMessage,
6+
ImageAttachment as PlatformImageAttachment,
7+
AgentState as PlatformAgentState,
68
} from './protocol';
79
import type { RetryConfig } from './retry';
810
export type { RetryConfig } from './retry';
911

1012
export type BehaviorType = PlatformBehaviorType;
1113
export type ProjectType = PlatformProjectType;
14+
export type ImageAttachment = PlatformImageAttachment;
15+
export type AgentState = PlatformAgentState;
1216

13-
// Ephemeral, optional credentials (not persisted by SDK).
1417
export type Credentials = NonNullable<PlatformCodeGenArgs['credentials']>;
15-
1618
export type CodeGenArgs = PlatformCodeGenArgs;
1719

1820
export type BuildOptions = Omit<CodeGenArgs, 'query'> & {
19-
/**
20-
* If true (default), connect to the agent websocket immediately.
21-
*/
2221
autoConnect?: boolean;
23-
/**
24-
* If true (default), send `{ type: 'generate_all' }` after websocket connection.
25-
*/
2622
autoGenerate?: boolean;
27-
/**
28-
* Called for each blueprint chunk emitted by the create-agent stream.
29-
*/
3023
onBlueprintChunk?: (chunk: string) => void;
3124
};
3225

26+
export type TemplateFiles = Record<string, string>;
27+
3328
export type BuildStartEvent = {
3429
message?: string;
3530
agentId: string;
3631
websocketUrl: string;
3732
httpStatusUrl?: string;
3833
behaviorType?: BehaviorType;
3934
projectType?: string;
40-
template?: { name: string; files?: unknown };
35+
template?: { name: string; files?: TemplateFiles };
4136
};
4237

4338
export type ApiResponse<T> =
@@ -65,10 +60,44 @@ export type AppListItem = {
6560
previewUrl?: string;
6661
};
6762

68-
export type AppDetails = Record<string, unknown> & {
63+
export type AppDetails = {
6964
id: string;
7065
previewUrl?: string;
7166
cloudflareUrl?: string;
67+
title?: string;
68+
description?: string | null;
69+
framework?: string | null;
70+
visibility?: 'public' | 'private';
71+
createdAt?: string | null;
72+
updatedAt?: string | null;
73+
[key: string]: string | null | undefined;
74+
};
75+
76+
export type AppVisibility = 'public' | 'private';
77+
78+
export type AppWithFavoriteStatus = AppListItem & {
79+
isFavorite: boolean;
80+
updatedAtFormatted?: string;
81+
};
82+
83+
export type VisibilityUpdateResult = {
84+
app: {
85+
id: string;
86+
title: string;
87+
visibility: AppVisibility;
88+
updatedAt: string | null;
89+
};
90+
message: string;
91+
};
92+
93+
export type ToggleResult = {
94+
isFavorite?: boolean;
95+
isStarred?: boolean;
96+
};
97+
98+
export type DeleteResult = {
99+
success: boolean;
100+
message: string;
72101
};
73102

74103
export type AgentWsServerMessage = WebSocketMessage;
@@ -82,7 +111,7 @@ export type AgentWsClientMessage =
82111
| { type: 'deploy' }
83112
| { type: 'get_conversation_state' }
84113
| { type: 'clear_conversation' }
85-
| { type: 'user_suggestion'; message: string; images?: unknown[] };
114+
| { type: 'user_suggestion'; message: string; images?: ImageAttachment[] };
86115

87116
export type AgentWebSocketMessage = AgentWsServerMessage | AgentWsClientMessage;
88117

@@ -94,11 +123,9 @@ export type WsMessageOf<TType extends AgentWsServerMessage['type']> = Extract<
94123
export type AgentEventMap = {
95124
'ws:open': undefined;
96125
'ws:close': { code: number; reason: string };
97-
'ws:error': { error: unknown };
126+
'ws:error': { error: Error | string };
98127
'ws:reconnecting': { attempt: number; delayMs: number; reason: 'close' | 'error' };
99-
/** Server payload that isn't a well-formed typed message. */
100-
'ws:raw': { raw: unknown };
101-
/** Raw server->client message (typed) */
128+
'ws:raw': { raw: Record<string, unknown> };
102129
'ws:message': AgentWsServerMessage;
103130

104131
// High-level sugar events (typed)
@@ -130,14 +157,26 @@ export type AgentEventMap = {
130157
error: { error: string };
131158
};
132159

160+
export type WsOpenEvent = Event;
161+
export type WsCloseEvent = CloseEvent | { code?: number; reason?: string };
162+
export type WsErrorEvent = Event | Error;
163+
export type WsMessageEvent = MessageEvent | { data: string };
164+
165+
export type WebSocketEventMap = {
166+
open: WsOpenEvent;
167+
close: WsCloseEvent;
168+
error: WsErrorEvent;
169+
message: WsMessageEvent;
170+
};
171+
172+
export type WebSocketEventType = keyof WebSocketEventMap;
173+
export type WebSocketEventListener<K extends WebSocketEventType> = (event: WebSocketEventMap[K]) => void;
174+
133175
export type WebSocketLike = {
134176
send: (data: string) => void;
135177
close: () => void;
136-
addEventListener?: (
137-
type: 'open' | 'close' | 'error' | 'message',
138-
listener: (event: unknown) => void
139-
) => void;
140-
on?: (type: string, listener: (...args: unknown[]) => void) => void;
178+
addEventListener?<K extends WebSocketEventType>(type: K, listener: WebSocketEventListener<K>): void;
179+
on?<K extends WebSocketEventType>(type: K, listener: WebSocketEventListener<K>): void;
141180
};
142181

143182
export type AgentConnectionOptions = {
@@ -208,18 +247,16 @@ export type SessionDeployable = {
208247

209248
export type VibeClientOptions = {
210249
baseUrl: string;
211-
/**
212-
* Current platform requirement: JWT access token. In future this will be minted from `apiKey`.
213-
*/
250+
/** JWT access token (or will be minted from apiKey). */
214251
token?: string;
215-
/** Future: VibeSDK API key. */
252+
/** VibeSDK API key. */
216253
apiKey?: string;
217254
defaultHeaders?: Record<string, string>;
218-
/** Used as Origin header for WS (optional but often required). */
255+
/** Origin header for WebSocket connections. */
219256
websocketOrigin?: string;
220-
/** Optional WebSocket factory for Node/Bun runtimes. */
257+
/** WebSocket factory - use runtime-specific factories from /browser, /worker, or /node. */
221258
webSocketFactory?: AgentConnectionOptions['webSocketFactory'];
222259
fetchFn?: typeof fetch;
223-
/** HTTP retry configuration for transient failures (5xx, network errors). */
260+
/** HTTP retry config for transient failures. */
224261
retry?: RetryConfig;
225262
};

sdk/src/utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/**
2+
* Checks if a value is a plain object (not null, not an array).
3+
*/
4+
export function isRecord(value: unknown): value is Record<string, unknown> {
5+
return typeof value === 'object' && value !== null && !Array.isArray(value);
6+
}
7+
18
/**
29
* Error thrown when an operation times out.
310
*/

sdk/src/workspace.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { TypedEmitter } from './emitter';
2+
import { isRecord } from './utils';
23
import type { AgentState, FileOutputType } from './protocol';
34
import type { AgentWsServerMessage } from './types';
45

@@ -16,10 +17,6 @@ type WorkspaceEvents = {
1617
change: WorkspaceChange;
1718
};
1819

19-
function isRecord(value: unknown): value is Record<string, unknown> {
20-
return typeof value === 'object' && value !== null;
21-
}
22-
2320
function isFileOutputType(value: unknown): value is FileOutputType {
2421
if (!isRecord(value)) return false;
2522
return typeof value.filePath === 'string' && typeof value.fileContents === 'string';

0 commit comments

Comments
 (0)