@agent-foundry/studio 1.0.0 → 1.0.2

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.
Files changed (44) hide show
  1. package/README.md +180 -47
  2. package/dist/bff/client.d.ts +168 -0
  3. package/dist/bff/client.d.ts.map +1 -0
  4. package/dist/bff/client.js +288 -0
  5. package/dist/bff/client.js.map +1 -0
  6. package/dist/bff/index.d.ts +27 -0
  7. package/dist/bff/index.d.ts.map +1 -0
  8. package/dist/bff/index.js +26 -0
  9. package/dist/bff/index.js.map +1 -0
  10. package/dist/bff/types.d.ts +168 -0
  11. package/dist/bff/types.d.ts.map +1 -0
  12. package/dist/bff/types.js +8 -0
  13. package/dist/bff/types.js.map +1 -0
  14. package/dist/db/deployments.d.ts +67 -1
  15. package/dist/db/deployments.d.ts.map +1 -1
  16. package/dist/db/deployments.js +92 -1
  17. package/dist/db/deployments.js.map +1 -1
  18. package/dist/db/index.d.ts +17 -0
  19. package/dist/db/index.d.ts.map +1 -1
  20. package/dist/db/index.js +17 -0
  21. package/dist/db/index.js.map +1 -1
  22. package/dist/db/projects.d.ts +54 -1
  23. package/dist/db/projects.d.ts.map +1 -1
  24. package/dist/db/projects.js +79 -1
  25. package/dist/db/projects.js.map +1 -1
  26. package/dist/index.d.ts +14 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +16 -2
  29. package/dist/index.js.map +1 -1
  30. package/dist/types/deployment.d.ts +56 -0
  31. package/dist/types/deployment.d.ts.map +1 -1
  32. package/dist/types/project.d.ts +6 -0
  33. package/dist/types/project.d.ts.map +1 -1
  34. package/package.json +14 -4
  35. package/src/bff/client.ts +412 -0
  36. package/src/bff/index.ts +32 -0
  37. package/src/bff/types.ts +212 -0
  38. package/src/db/deployments.ts +99 -1
  39. package/src/db/index.ts +17 -0
  40. package/src/db/projects.ts +86 -1
  41. package/src/db/schema.sql +35 -52
  42. package/src/index.ts +18 -2
  43. package/src/types/deployment.ts +75 -0
  44. package/src/types/project.ts +7 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @agent-foundry/studio
2
2
 
3
- Full SDK for Agent Foundry Build Studio - provides types, Alibaba Cloud OSS upload utilities, and Supabase database client.
3
+ Full SDK for Agent Foundry Build Studio - provides types, BFF API client, Alibaba Cloud OSS upload utilities, and Supabase database client.
4
4
 
5
5
  ## Installation
6
6
 
@@ -11,86 +11,219 @@ pnpm add @agent-foundry/studio
11
11
  ## Features
12
12
 
13
13
  - **Types**: TypeScript interfaces for Studio projects, deployments, workspaces, and users
14
+ - **BFF Client**: API client for write operations (create, update, delete projects/deployments)
14
15
  - **OSS Client**: Direct upload to Alibaba Cloud OSS with STS credentials
15
- - **DB Client**: Supabase client wrapper for project and deployment management
16
+ - **DB Client**: Supabase client for read operations (list, get projects/deployments)
17
+
18
+ ## Recommended Usage Pattern (Hybrid Approach)
19
+
20
+ Due to RLS (Row Level Security) restrictions, this SDK uses a **hybrid access pattern**:
21
+
22
+ | Operation | Client | Reason |
23
+ |-----------|--------|--------|
24
+ | **Read** (list, get) | Supabase Client (`/db`) | Direct database access, low latency |
25
+ | **Write** (create, update, delete) | BFF Client (`/bff`) | Bypasses RLS, server-side validation |
26
+ | **File Upload** | DirectUploader (`/oss`) | Direct OSS upload with STS credentials |
27
+
28
+ ```
29
+ ┌─────────────────────────────────────────────────────────────┐
30
+ │ Desktop App / Client │
31
+ └───────────────────────────┬─────────────────────────────────┘
32
+
33
+ ┌───────────────┼───────────────┐
34
+ ▼ ▼ ▼
35
+ ┌────────────┐ ┌────────────┐ ┌────────────┐
36
+ │ BFF Client │ │ DB Client │ │ OSS Upload │
37
+ │ (writes) │ │ (reads) │ │ (files) │
38
+ └──────┬─────┘ └──────┬─────┘ └──────┬─────┘
39
+ │ │ │
40
+ ▼ ▼ ▼
41
+ ┌────────────┐ ┌────────────┐ ┌────────────┐
42
+ │ BFF API │ │ Supabase │ │ Alibaba │
43
+ │ (FastAPI) │ │ PostgreSQL │ │ Cloud OSS │
44
+ └────────────┘ └────────────┘ └────────────┘
45
+ ```
16
46
 
17
47
  ## Usage
18
48
 
19
49
  ### Types Only
20
50
 
21
51
  ```typescript
22
- import type { StudioProject, Deployment, Workspace } from '@agent-foundry/studio/types';
52
+ import type { StudioProject, Deployment } from '@agent-foundry/studio/types';
23
53
  ```
24
54
 
25
- ### OSS Upload
55
+ ### Write Operations (BFF Client) - Recommended
56
+
57
+ Use the BFF client for all write operations. It uses service_role credentials on the server side, bypassing RLS.
26
58
 
27
59
  ```typescript
28
- import { DirectUploader } from '@agent-foundry/studio/oss';
60
+ import { createBFFClient } from '@agent-foundry/studio/bff';
29
61
 
30
- const uploader = new DirectUploader({
31
- bffBaseUrl: 'http://localhost:11001',
32
- authToken: 'your-supabase-jwt',
62
+ const bff = createBFFClient({
63
+ baseUrl: 'http://localhost:11001',
64
+ authToken: 'your-supabase-jwt', // User's access token
33
65
  });
34
66
 
35
- // Upload a built bundle
36
- const result = await uploader.upload({
37
- projectId: 'project-uuid',
38
- files: distFiles,
39
- onProgress: (progress) => console.log(`${progress.percent}%`),
67
+ // Create a project
68
+ const project = await bff.projects.create({
69
+ name: 'My App',
70
+ slug: 'my-app',
71
+ rootPath: '/Users/me/projects/my-app',
72
+ });
73
+
74
+ // Update a project
75
+ await bff.projects.update(project.id, {
76
+ name: 'My Updated App',
77
+ });
78
+
79
+ // Delete a project
80
+ await bff.projects.delete(project.id);
81
+
82
+ // Fork a project
83
+ const fork = await bff.projects.fork(project.id, {
84
+ newSlug: 'my-app-fork',
85
+ newRootPath: '/Users/me/projects/my-app-fork',
86
+ });
87
+
88
+ // Publish to Feed
89
+ const published = await bff.projects.publish(project.id, {
90
+ status: 'stable',
40
91
  });
41
92
  ```
42
93
 
43
- ### Database Operations
94
+ ### Read Operations (Supabase Client)
95
+
96
+ Use the Supabase client for read operations. Requires authenticated user's session.
44
97
 
45
98
  ```typescript
46
99
  import { createStudioClient } from '@agent-foundry/studio/db';
47
100
 
48
- const client = createStudioClient({
101
+ const db = createStudioClient({
49
102
  supabaseUrl: 'https://your-project.supabase.co',
50
103
  supabaseKey: 'your-anon-key',
104
+ // Or pass an existing Supabase client with user session
105
+ existingClient: supabaseClientWithSession,
51
106
  });
52
107
 
53
- // Create a project
54
- const project = await client.projects.create({
55
- name: 'My App',
56
- slug: 'my-app',
57
- rootPath: '/Users/me/projects/my-app',
108
+ // List projects
109
+ const projects = await db.projects.list({
110
+ framework: 'vite-react',
111
+ limit: 10,
112
+ });
113
+
114
+ // Get a project by ID
115
+ const project = await db.projects.getById('project-uuid');
116
+
117
+ // Get a project by slug
118
+ const projectBySlug = await db.projects.getBySlug('my-app');
119
+
120
+ // List deployments
121
+ const deployments = await db.deployments.list({
122
+ projectId: 'project-uuid',
58
123
  });
59
124
 
60
- // Create a deployment
61
- const deployment = await client.deployments.create({
62
- projectId: project.id,
63
- version: '1.0.0',
125
+ // Get latest published deployment
126
+ const latest = await db.deployments.getLatestPublished('project-uuid');
127
+ ```
128
+
129
+ ### File Upload (OSS)
130
+
131
+ Use DirectUploader for uploading build artifacts. It handles the complete workflow:
132
+
133
+ 1. Requests STS credentials from BFF
134
+ 2. Uploads files directly to OSS
135
+ 3. Notifies BFF of completion
136
+
137
+ ```typescript
138
+ import { DirectUploader } from '@agent-foundry/studio/oss';
139
+
140
+ const uploader = new DirectUploader({
141
+ bffBaseUrl: 'http://localhost:11001',
142
+ authToken: 'your-supabase-jwt',
64
143
  });
144
+
145
+ // Upload a built bundle
146
+ const result = await uploader.upload({
147
+ projectId: 'project-uuid',
148
+ files: [
149
+ { path: 'index.html', content: indexHtml, contentType: 'text/html' },
150
+ { path: 'assets/main.js', content: mainJs, contentType: 'application/javascript' },
151
+ ],
152
+ onProgress: (progress) => {
153
+ console.log(`${progress.stage}: ${progress.percent}%`);
154
+ },
155
+ });
156
+
157
+ if (result.success) {
158
+ console.log(`Deployed to: ${result.url}`);
159
+ }
65
160
  ```
66
161
 
67
- ## Architecture
162
+ ## Why Hybrid Approach?
163
+
164
+ 1. **Security**: Write operations go through BFF with service_role, no need to expose sensitive keys
165
+ 2. **Performance**: Read operations use direct Supabase connection, minimal latency
166
+ 3. **Validation**: BFF can validate writes (slug uniqueness, path validation, etc.)
167
+ 4. **Consistency**: Deployment state machine is controlled server-side
168
+
169
+ ## Testing
170
+
171
+ ### Unit Tests
68
172
 
173
+ ```bash
174
+ pnpm test # Run all unit tests
175
+ pnpm test:watch # Watch mode
69
176
  ```
70
- ┌─────────────────────────────────────────────────────────┐
71
- │ Tauri Desktop App │
72
- │ ┌─────────────────┐ ┌─────────────────────────────┐ │
73
- │ │ Studio UI │ │ OpenCode Server (Hono) │
74
- │ │ (React) │ │ │ │
75
- │ └────────┬────────┘ └─────────────────────────────┘ │
76
- └───────────┼─────────────────────────────────────────────┘
77
-
78
-
79
- ┌─────────────────────────────────────────────────────────┐
80
- │ @agent-foundry/studio Package │
81
- │ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
82
- │ │ Types │ │ OSS Client │ │ Supabase Client │ │
83
- │ └──────────┘ └──────┬───────┘ └────────┬─────────┘ │
84
- └─────────────────────────┼──────────────────┼────────────┘
85
- │ │
86
- ┌─────────────┘ │
87
- ▼ ▼
88
- ┌────────────────┐ ┌────────────────────┐
89
- │ Alibaba Cloud │ │ Supabase │
90
- │ OSS │ │ PostgreSQL │
91
- └────────────────┘ └────────────────────┘
177
+
178
+ ### Integration Tests
179
+
180
+ Integration tests run against a real BFF deployment:
181
+
182
+ ```bash
183
+ # Set required environment variables
184
+ export BFF_URL=http://localhost:11001
185
+ export SUPABASE_JWT_SECRET=your-secret
186
+
187
+ # Run integration tests
188
+ pnpm test:integration
92
189
  ```
93
190
 
191
+ See [test/README.md](test/README.md) for detailed test documentation.
192
+
193
+ ## API Reference
194
+
195
+ ### BFF Client (`@agent-foundry/studio/bff`)
196
+
197
+ - `createBFFClient(config)` - Create BFF client
198
+ - `bff.projects.create(input)` - Create project
199
+ - `bff.projects.get(id)` - Get project
200
+ - `bff.projects.list(options)` - List projects
201
+ - `bff.projects.update(id, input)` - Update project
202
+ - `bff.projects.delete(id)` - Delete project
203
+ - `bff.projects.fork(id, options)` - Fork project
204
+ - `bff.projects.publish(id, options)` - Publish to Feed
205
+ - `bff.deployments.start(input)` - Start deployment
206
+ - `bff.deployments.get(id)` - Get deployment
207
+ - `bff.deployments.list(projectId, limit)` - List deployments
208
+ - `bff.deployments.updateStatus(id, input)` - Update status
209
+ - `bff.deployments.complete(id, input)` - Mark complete
210
+ - `bff.deployments.fail(id, input)` - Mark failed
211
+
212
+ ### DB Client (`@agent-foundry/studio/db`)
213
+
214
+ - `createStudioClient(config)` - Create Supabase client
215
+ - `db.projects.getById(id)` - Get project by ID
216
+ - `db.projects.getBySlug(slug)` - Get project by slug
217
+ - `db.projects.list(filters)` - List projects
218
+ - `db.deployments.getById(id)` - Get deployment by ID
219
+ - `db.deployments.list(filters)` - List deployments
220
+ - `db.deployments.getLatestPublished(projectId)` - Get latest published
221
+
222
+ ### OSS Client (`@agent-foundry/studio/oss`)
223
+
224
+ - `DirectUploader` - High-level upload client
225
+ - `AliOSSClient` - Low-level OSS client
226
+
94
227
  ## License
95
228
 
96
229
  MIT
@@ -0,0 +1,168 @@
1
+ /**
2
+ * BFF API Client
3
+ *
4
+ * Client for interacting with the BFF Studio API endpoints.
5
+ * All write operations (create, update, delete) should go through this client.
6
+ *
7
+ * The BFF uses SQLAlchemy with service_role credentials, which bypasses RLS.
8
+ * This is the secure and recommended way to perform write operations.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createBFFClient } from '@agent-foundry/studio/bff';
13
+ *
14
+ * const client = createBFFClient({
15
+ * baseUrl: 'http://localhost:11001',
16
+ * authToken: 'your-supabase-jwt',
17
+ * });
18
+ *
19
+ * // Create a project
20
+ * const project = await client.projects.create({
21
+ * name: 'My App',
22
+ * slug: 'my-app',
23
+ * rootPath: '/Users/me/projects/my-app',
24
+ * });
25
+ * ```
26
+ */
27
+ import type { StudioProject, CreateProjectInput, UpdateProjectInput } from '../types/project';
28
+ import type { Deployment, DeploymentMetadata } from '../types/deployment';
29
+ import type { BFFClientConfig, ProjectResponse, ProjectListResponse, StartDeploymentResponse, UpdateDeploymentStatusRequest, CompleteDeploymentRequest, CompleteDeploymentResponse, FailDeploymentRequest, DeploymentListResponse, PublishRequest, PublishResponse } from './types';
30
+ /**
31
+ * Error thrown by BFF API client
32
+ */
33
+ export declare class BFFAPIError extends Error {
34
+ readonly status: number;
35
+ readonly detail?: string | undefined;
36
+ readonly code?: string | undefined;
37
+ constructor(message: string, status: number, detail?: string | undefined, code?: string | undefined);
38
+ }
39
+ /**
40
+ * Projects API client
41
+ */
42
+ export declare class ProjectsAPI {
43
+ private readonly baseUrl;
44
+ private readonly authToken;
45
+ private readonly timeout;
46
+ constructor(baseUrl: string, authToken: string, timeout: number);
47
+ private get headers();
48
+ private request;
49
+ /**
50
+ * Create a new project
51
+ */
52
+ create(input: CreateProjectInput): Promise<StudioProject>;
53
+ /**
54
+ * Get a project by ID
55
+ */
56
+ get(id: string): Promise<ProjectResponse>;
57
+ /**
58
+ * List all projects with optional pagination
59
+ */
60
+ list(options?: {
61
+ page?: number;
62
+ pageSize?: number;
63
+ framework?: string;
64
+ search?: string;
65
+ }): Promise<ProjectListResponse>;
66
+ /**
67
+ * Update a project
68
+ */
69
+ update(id: string, input: UpdateProjectInput): Promise<StudioProject>;
70
+ /**
71
+ * Delete a project
72
+ */
73
+ delete(id: string): Promise<void>;
74
+ /**
75
+ * Fork a project
76
+ */
77
+ fork(id: string, options: {
78
+ newSlug: string;
79
+ newRootPath: string;
80
+ newName?: string;
81
+ }): Promise<StudioProject>;
82
+ /**
83
+ * Publish a project to Feed
84
+ */
85
+ publish(id: string, options?: PublishRequest): Promise<PublishResponse>;
86
+ }
87
+ /**
88
+ * Deployments API client
89
+ */
90
+ export declare class DeploymentsAPI {
91
+ private readonly baseUrl;
92
+ private readonly authToken;
93
+ private readonly timeout;
94
+ constructor(baseUrl: string, authToken: string, timeout: number);
95
+ private get headers();
96
+ private request;
97
+ /**
98
+ * Start a new deployment (creates deployment record and returns STS credentials)
99
+ */
100
+ start(input: {
101
+ projectId: string;
102
+ version?: string;
103
+ metadata?: Partial<DeploymentMetadata>;
104
+ }): Promise<StartDeploymentResponse>;
105
+ /**
106
+ * Get a deployment by ID
107
+ */
108
+ get(id: string): Promise<Deployment>;
109
+ /**
110
+ * List deployments for a project
111
+ */
112
+ list(projectId: string, limit?: number): Promise<DeploymentListResponse>;
113
+ /**
114
+ * Update deployment status
115
+ */
116
+ updateStatus(id: string, input: UpdateDeploymentStatusRequest): Promise<{
117
+ status: string;
118
+ deploymentId: string;
119
+ }>;
120
+ /**
121
+ * Mark deployment as complete (after successful OSS upload)
122
+ */
123
+ complete(id: string, input: CompleteDeploymentRequest): Promise<CompleteDeploymentResponse>;
124
+ /**
125
+ * Mark deployment as failed
126
+ */
127
+ fail(id: string, input: FailDeploymentRequest): Promise<{
128
+ status: string;
129
+ deploymentId: string;
130
+ }>;
131
+ }
132
+ /**
133
+ * BFF Client - main entry point for BFF API operations
134
+ */
135
+ export interface BFFClient {
136
+ /** Projects API */
137
+ readonly projects: ProjectsAPI;
138
+ /** Deployments API */
139
+ readonly deployments: DeploymentsAPI;
140
+ }
141
+ /**
142
+ * Create a new BFF client
143
+ *
144
+ * @param config - Client configuration
145
+ * @returns BFFClient instance
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * const client = createBFFClient({
150
+ * baseUrl: 'http://localhost:11001',
151
+ * authToken: 'your-supabase-jwt',
152
+ * });
153
+ *
154
+ * // Create a project
155
+ * const project = await client.projects.create({
156
+ * name: 'My App',
157
+ * slug: 'my-app',
158
+ * rootPath: '/Users/me/projects/my-app',
159
+ * });
160
+ *
161
+ * // Start a deployment
162
+ * const deployment = await client.deployments.start({
163
+ * projectId: project.id,
164
+ * });
165
+ * ```
166
+ */
167
+ export declare function createBFFClient(config: BFFClientConfig): BFFClient;
168
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/bff/client.ts"],"names":[],"mappings":"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"}