@vibescope/mcp-server 0.0.1 → 0.1.0

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 (170) hide show
  1. package/README.md +113 -98
  2. package/dist/api-client.d.ts +1114 -0
  3. package/dist/api-client.js +698 -0
  4. package/dist/cli.d.ts +1 -6
  5. package/dist/cli.js +39 -240
  6. package/dist/config/tool-categories.d.ts +31 -0
  7. package/dist/config/tool-categories.js +253 -0
  8. package/dist/handlers/blockers.js +57 -58
  9. package/dist/handlers/bodies-of-work.d.ts +2 -0
  10. package/dist/handlers/bodies-of-work.js +106 -476
  11. package/dist/handlers/cost.d.ts +1 -0
  12. package/dist/handlers/cost.js +35 -113
  13. package/dist/handlers/decisions.d.ts +2 -0
  14. package/dist/handlers/decisions.js +28 -27
  15. package/dist/handlers/deployment.js +112 -828
  16. package/dist/handlers/discovery.js +31 -0
  17. package/dist/handlers/fallback.d.ts +2 -0
  18. package/dist/handlers/fallback.js +39 -134
  19. package/dist/handlers/findings.js +43 -67
  20. package/dist/handlers/git-issues.d.ts +9 -13
  21. package/dist/handlers/git-issues.js +80 -225
  22. package/dist/handlers/ideas.d.ts +3 -0
  23. package/dist/handlers/ideas.js +53 -134
  24. package/dist/handlers/index.d.ts +2 -0
  25. package/dist/handlers/index.js +6 -0
  26. package/dist/handlers/milestones.d.ts +2 -0
  27. package/dist/handlers/milestones.js +51 -98
  28. package/dist/handlers/organizations.js +79 -275
  29. package/dist/handlers/progress.d.ts +2 -0
  30. package/dist/handlers/progress.js +25 -123
  31. package/dist/handlers/project.js +42 -221
  32. package/dist/handlers/requests.d.ts +2 -0
  33. package/dist/handlers/requests.js +23 -83
  34. package/dist/handlers/session.js +99 -585
  35. package/dist/handlers/sprints.d.ts +32 -0
  36. package/dist/handlers/sprints.js +274 -0
  37. package/dist/handlers/tasks.d.ts +7 -10
  38. package/dist/handlers/tasks.js +230 -900
  39. package/dist/handlers/tool-docs.d.ts +8 -0
  40. package/dist/handlers/tool-docs.js +657 -0
  41. package/dist/handlers/types.d.ts +11 -3
  42. package/dist/handlers/validation.d.ts +1 -1
  43. package/dist/handlers/validation.js +26 -153
  44. package/dist/index.js +473 -160
  45. package/dist/knowledge.js +106 -9
  46. package/dist/tools.js +4 -0
  47. package/dist/validators.d.ts +21 -0
  48. package/dist/validators.js +91 -0
  49. package/package.json +2 -3
  50. package/src/api-client.ts +1752 -0
  51. package/src/cli.test.ts +128 -302
  52. package/src/cli.ts +41 -285
  53. package/src/handlers/__test-setup__.ts +210 -0
  54. package/src/handlers/__test-utils__.ts +4 -134
  55. package/src/handlers/blockers.test.ts +114 -124
  56. package/src/handlers/blockers.ts +68 -70
  57. package/src/handlers/bodies-of-work.test.ts +236 -831
  58. package/src/handlers/bodies-of-work.ts +194 -525
  59. package/src/handlers/cost.test.ts +149 -113
  60. package/src/handlers/cost.ts +44 -132
  61. package/src/handlers/decisions.test.ts +111 -209
  62. package/src/handlers/decisions.ts +35 -27
  63. package/src/handlers/deployment.test.ts +193 -239
  64. package/src/handlers/deployment.ts +140 -895
  65. package/src/handlers/discovery.test.ts +20 -67
  66. package/src/handlers/discovery.ts +32 -0
  67. package/src/handlers/fallback.test.ts +128 -361
  68. package/src/handlers/fallback.ts +62 -148
  69. package/src/handlers/findings.test.ts +127 -345
  70. package/src/handlers/findings.ts +49 -66
  71. package/src/handlers/git-issues.test.ts +623 -0
  72. package/src/handlers/git-issues.ts +174 -0
  73. package/src/handlers/ideas.test.ts +229 -343
  74. package/src/handlers/ideas.ts +69 -143
  75. package/src/handlers/index.ts +6 -0
  76. package/src/handlers/milestones.test.ts +167 -281
  77. package/src/handlers/milestones.ts +54 -93
  78. package/src/handlers/organizations.test.ts +275 -467
  79. package/src/handlers/organizations.ts +84 -294
  80. package/src/handlers/progress.test.ts +112 -218
  81. package/src/handlers/progress.ts +29 -142
  82. package/src/handlers/project.test.ts +203 -226
  83. package/src/handlers/project.ts +48 -238
  84. package/src/handlers/requests.test.ts +74 -342
  85. package/src/handlers/requests.ts +25 -83
  86. package/src/handlers/session.test.ts +241 -206
  87. package/src/handlers/session.ts +110 -657
  88. package/src/handlers/sprints.test.ts +711 -0
  89. package/src/handlers/sprints.ts +497 -0
  90. package/src/handlers/tasks.test.ts +608 -353
  91. package/src/handlers/tasks.ts +248 -1025
  92. package/src/handlers/types.ts +12 -4
  93. package/src/handlers/validation.test.ts +189 -572
  94. package/src/handlers/validation.ts +29 -166
  95. package/src/index.ts +473 -184
  96. package/src/knowledge.ts +107 -9
  97. package/src/tools.ts +2506 -0
  98. package/src/validators.test.ts +223 -223
  99. package/src/validators.ts +127 -0
  100. package/tsconfig.json +1 -1
  101. package/vitest.config.ts +14 -13
  102. package/dist/cli.test.d.ts +0 -1
  103. package/dist/cli.test.js +0 -367
  104. package/dist/handlers/__test-utils__.d.ts +0 -72
  105. package/dist/handlers/__test-utils__.js +0 -176
  106. package/dist/handlers/checkouts.d.ts +0 -37
  107. package/dist/handlers/checkouts.js +0 -377
  108. package/dist/handlers/knowledge-query.d.ts +0 -22
  109. package/dist/handlers/knowledge-query.js +0 -253
  110. package/dist/handlers/knowledge.d.ts +0 -12
  111. package/dist/handlers/knowledge.js +0 -108
  112. package/dist/handlers/roles.d.ts +0 -30
  113. package/dist/handlers/roles.js +0 -281
  114. package/dist/handlers/tasks.test.d.ts +0 -1
  115. package/dist/handlers/tasks.test.js +0 -431
  116. package/dist/utils.test.d.ts +0 -1
  117. package/dist/utils.test.js +0 -532
  118. package/dist/validators.test.d.ts +0 -1
  119. package/dist/validators.test.js +0 -176
  120. package/src/tmpclaude-0078-cwd +0 -1
  121. package/src/tmpclaude-0ee1-cwd +0 -1
  122. package/src/tmpclaude-2dd5-cwd +0 -1
  123. package/src/tmpclaude-344c-cwd +0 -1
  124. package/src/tmpclaude-3860-cwd +0 -1
  125. package/src/tmpclaude-4b63-cwd +0 -1
  126. package/src/tmpclaude-5c73-cwd +0 -1
  127. package/src/tmpclaude-5ee3-cwd +0 -1
  128. package/src/tmpclaude-6795-cwd +0 -1
  129. package/src/tmpclaude-709e-cwd +0 -1
  130. package/src/tmpclaude-9839-cwd +0 -1
  131. package/src/tmpclaude-d829-cwd +0 -1
  132. package/src/tmpclaude-e072-cwd +0 -1
  133. package/src/tmpclaude-f6ee-cwd +0 -1
  134. package/tmpclaude-0439-cwd +0 -1
  135. package/tmpclaude-132f-cwd +0 -1
  136. package/tmpclaude-15bb-cwd +0 -1
  137. package/tmpclaude-165a-cwd +0 -1
  138. package/tmpclaude-1ba9-cwd +0 -1
  139. package/tmpclaude-21a3-cwd +0 -1
  140. package/tmpclaude-2a38-cwd +0 -1
  141. package/tmpclaude-2adf-cwd +0 -1
  142. package/tmpclaude-2f56-cwd +0 -1
  143. package/tmpclaude-3626-cwd +0 -1
  144. package/tmpclaude-3727-cwd +0 -1
  145. package/tmpclaude-40bc-cwd +0 -1
  146. package/tmpclaude-436f-cwd +0 -1
  147. package/tmpclaude-4783-cwd +0 -1
  148. package/tmpclaude-4b6d-cwd +0 -1
  149. package/tmpclaude-4ba4-cwd +0 -1
  150. package/tmpclaude-51e6-cwd +0 -1
  151. package/tmpclaude-5ecf-cwd +0 -1
  152. package/tmpclaude-6f97-cwd +0 -1
  153. package/tmpclaude-7fb2-cwd +0 -1
  154. package/tmpclaude-825c-cwd +0 -1
  155. package/tmpclaude-8baf-cwd +0 -1
  156. package/tmpclaude-8d9f-cwd +0 -1
  157. package/tmpclaude-975c-cwd +0 -1
  158. package/tmpclaude-9983-cwd +0 -1
  159. package/tmpclaude-a045-cwd +0 -1
  160. package/tmpclaude-ac4a-cwd +0 -1
  161. package/tmpclaude-b593-cwd +0 -1
  162. package/tmpclaude-b891-cwd +0 -1
  163. package/tmpclaude-c032-cwd +0 -1
  164. package/tmpclaude-cf43-cwd +0 -1
  165. package/tmpclaude-d040-cwd +0 -1
  166. package/tmpclaude-dcdd-cwd +0 -1
  167. package/tmpclaude-dcee-cwd +0 -1
  168. package/tmpclaude-e16b-cwd +0 -1
  169. package/tmpclaude-ecd2-cwd +0 -1
  170. package/tmpclaude-f48d-cwd +0 -1
@@ -0,0 +1,1752 @@
1
+ /**
2
+ * Vibescope API Client
3
+ *
4
+ * HTTP client for communicating with the Vibescope API.
5
+ * All database operations are handled server-side through these endpoints.
6
+ */
7
+
8
+ const DEFAULT_API_URL = 'https://vibescope.dev';
9
+
10
+ interface ApiClientConfig {
11
+ apiKey: string;
12
+ baseUrl?: string;
13
+ }
14
+
15
+ interface ApiResponse<T> {
16
+ ok: boolean;
17
+ status: number;
18
+ data?: T;
19
+ error?: string;
20
+ }
21
+
22
+ export class VibescopeApiClient {
23
+ private apiKey: string;
24
+ private baseUrl: string;
25
+
26
+ constructor(config: ApiClientConfig) {
27
+ this.apiKey = config.apiKey;
28
+ this.baseUrl = config.baseUrl || process.env.VIBESCOPE_API_URL || DEFAULT_API_URL;
29
+ }
30
+
31
+ private async request<T>(method: string, path: string, body?: unknown): Promise<ApiResponse<T>> {
32
+ const url = `${this.baseUrl}${path}`;
33
+
34
+ try {
35
+ const response = await fetch(url, {
36
+ method,
37
+ headers: {
38
+ 'Content-Type': 'application/json',
39
+ 'X-API-Key': this.apiKey
40
+ },
41
+ body: body ? JSON.stringify(body) : undefined
42
+ });
43
+
44
+ const data = await response.json();
45
+
46
+ if (!response.ok) {
47
+ return {
48
+ ok: false,
49
+ status: response.status,
50
+ error: data.error || `HTTP ${response.status}`
51
+ };
52
+ }
53
+
54
+ return {
55
+ ok: true,
56
+ status: response.status,
57
+ data
58
+ };
59
+ } catch (err) {
60
+ return {
61
+ ok: false,
62
+ status: 0,
63
+ error: err instanceof Error ? err.message : 'Network error'
64
+ };
65
+ }
66
+ }
67
+
68
+ // Auth endpoints
69
+ async validateAuth(): Promise<ApiResponse<{
70
+ valid: boolean;
71
+ user_id: string;
72
+ api_key_id: string;
73
+ key_name: string;
74
+ }>> {
75
+ return this.request('POST', '/api/mcp/auth/validate', {
76
+ api_key: this.apiKey
77
+ });
78
+ }
79
+
80
+ // Session endpoints
81
+ async startSession(params: {
82
+ project_id?: string;
83
+ git_url?: string;
84
+ mode?: 'lite' | 'full';
85
+ model?: 'opus' | 'sonnet' | 'haiku';
86
+ role?: 'developer' | 'validator' | 'deployer' | 'reviewer' | 'maintainer';
87
+ }): Promise<ApiResponse<{
88
+ session_started: boolean;
89
+ session_id?: string;
90
+ persona?: string;
91
+ role?: string;
92
+ project?: {
93
+ id: string;
94
+ name: string;
95
+ description?: string;
96
+ goal?: string;
97
+ status?: string;
98
+ git_url?: string;
99
+ agent_instructions?: string;
100
+ tech_stack?: string[];
101
+ git_workflow?: string;
102
+ git_main_branch?: string;
103
+ git_develop_branch?: string;
104
+ git_auto_branch?: boolean;
105
+ };
106
+ active_tasks?: Array<{
107
+ id: string;
108
+ title: string;
109
+ status: string;
110
+ priority: number;
111
+ progress_percentage?: number;
112
+ estimated_minutes?: number;
113
+ }>;
114
+ blockers?: Array<{
115
+ id: string;
116
+ description: string;
117
+ status: string;
118
+ }>;
119
+ next_task?: {
120
+ id: string;
121
+ title: string;
122
+ priority: number;
123
+ estimated_minutes?: number;
124
+ } | null;
125
+ directive?: string;
126
+ blockers_count?: number;
127
+ validation_count?: number;
128
+ project_not_found?: boolean;
129
+ message?: string;
130
+ suggestion?: {
131
+ action: string;
132
+ example: string;
133
+ note: string;
134
+ };
135
+ error?: string;
136
+ }>> {
137
+ return this.request('POST', '/api/mcp/sessions/start', params);
138
+ }
139
+
140
+ async heartbeat(sessionId: string): Promise<ApiResponse<{
141
+ success: boolean;
142
+ session_id: string;
143
+ timestamp: string;
144
+ }>> {
145
+ return this.request('POST', '/api/mcp/sessions/heartbeat', {
146
+ session_id: sessionId
147
+ });
148
+ }
149
+
150
+ async endSession(sessionId: string): Promise<ApiResponse<{
151
+ success: boolean;
152
+ ended_session_id?: string;
153
+ session_summary?: {
154
+ agent_name: string;
155
+ tasks_completed_this_session: number;
156
+ tasks_awaiting_validation: number;
157
+ tasks_released: number;
158
+ };
159
+ reminders?: string[];
160
+ }>> {
161
+ return this.request('POST', '/api/mcp/sessions/end', {
162
+ session_id: sessionId
163
+ });
164
+ }
165
+
166
+ // Project endpoints
167
+ async listProjects(): Promise<ApiResponse<{
168
+ projects: Array<{
169
+ id: string;
170
+ name: string;
171
+ description?: string;
172
+ status: string;
173
+ git_url?: string;
174
+ goal?: string;
175
+ tech_stack?: string[];
176
+ }>;
177
+ }>> {
178
+ return this.request('GET', '/api/mcp/projects');
179
+ }
180
+
181
+ async createProject(params: {
182
+ name: string;
183
+ description?: string;
184
+ goal?: string;
185
+ git_url?: string;
186
+ tech_stack?: string[];
187
+ }): Promise<ApiResponse<{
188
+ success: boolean;
189
+ project: {
190
+ id: string;
191
+ name: string;
192
+ };
193
+ }>> {
194
+ return this.request('POST', '/api/mcp/projects', params);
195
+ }
196
+
197
+ async getProject(projectId: string, gitUrl?: string): Promise<ApiResponse<{
198
+ found: boolean;
199
+ project?: {
200
+ id: string;
201
+ name: string;
202
+ description?: string;
203
+ goal?: string;
204
+ status: string;
205
+ git_url?: string;
206
+ agent_instructions?: string;
207
+ tech_stack?: string[];
208
+ git_workflow?: string;
209
+ git_main_branch?: string;
210
+ git_develop_branch?: string;
211
+ git_auto_branch?: boolean;
212
+ git_auto_tag?: boolean;
213
+ deployment_instructions?: string;
214
+ };
215
+ active_tasks?: Array<{
216
+ id: string;
217
+ title: string;
218
+ description?: string;
219
+ priority: number;
220
+ status: string;
221
+ progress_percentage?: number;
222
+ estimated_minutes?: number;
223
+ }>;
224
+ open_blockers?: Array<{
225
+ id: string;
226
+ description: string;
227
+ }>;
228
+ recent_decisions?: Array<{
229
+ id: string;
230
+ title: string;
231
+ description?: string;
232
+ }>;
233
+ message?: string;
234
+ }>> {
235
+ const url = gitUrl
236
+ ? `/api/mcp/projects/${projectId}?git_url=${encodeURIComponent(gitUrl)}`
237
+ : `/api/mcp/projects/${projectId}`;
238
+ return this.request('GET', url);
239
+ }
240
+
241
+ async updateProject(projectId: string, updates: {
242
+ name?: string;
243
+ description?: string;
244
+ goal?: string;
245
+ git_url?: string;
246
+ tech_stack?: string[];
247
+ status?: string;
248
+ git_workflow?: string;
249
+ git_main_branch?: string;
250
+ git_develop_branch?: string;
251
+ git_auto_branch?: boolean;
252
+ git_auto_tag?: boolean;
253
+ deployment_instructions?: string;
254
+ agent_instructions?: string;
255
+ }): Promise<ApiResponse<{
256
+ success: boolean;
257
+ project_id: string;
258
+ }>> {
259
+ return this.request('PATCH', `/api/mcp/projects/${projectId}`, updates);
260
+ }
261
+
262
+ // Task endpoints
263
+ async getTasks(projectId: string, params?: {
264
+ status?: string;
265
+ limit?: number;
266
+ offset?: number;
267
+ include_subtasks?: boolean;
268
+ search_query?: string;
269
+ include_metadata?: boolean; // When true, returns all task fields; when false (default), only id/title/priority/status
270
+ }): Promise<ApiResponse<{
271
+ tasks: Array<{
272
+ id: string;
273
+ title: string;
274
+ description?: string;
275
+ priority: number;
276
+ status: string;
277
+ progress_percentage?: number;
278
+ estimated_minutes?: number;
279
+ started_at?: string;
280
+ completed_at?: string;
281
+ parent_task_id?: string;
282
+ }>;
283
+ total_count: number;
284
+ has_more: boolean;
285
+ }>> {
286
+ const queryParams = new URLSearchParams();
287
+ if (params?.status) queryParams.set('status', params.status);
288
+ if (params?.limit) queryParams.set('limit', params.limit.toString());
289
+ if (params?.offset) queryParams.set('offset', params.offset.toString());
290
+ if (params?.include_subtasks) queryParams.set('include_subtasks', 'true');
291
+ if (params?.search_query) queryParams.set('search_query', params.search_query);
292
+ if (params?.include_metadata) queryParams.set('include_metadata', 'true');
293
+
294
+ const query = queryParams.toString();
295
+ const url = `/api/mcp/projects/${projectId}/tasks${query ? `?${query}` : ''}`;
296
+ return this.request('GET', url);
297
+ }
298
+
299
+ async createTask(projectId: string, params: {
300
+ title: string;
301
+ description?: string;
302
+ priority?: number;
303
+ estimated_minutes?: number;
304
+ blocking?: boolean;
305
+ session_id?: string;
306
+ }): Promise<ApiResponse<{
307
+ success: boolean;
308
+ task_id: string;
309
+ title: string;
310
+ blocking?: boolean;
311
+ message?: string;
312
+ }>> {
313
+ return this.request('POST', `/api/mcp/projects/${projectId}/tasks`, params);
314
+ }
315
+
316
+ async getNextTask(projectId: string, sessionId?: string): Promise<ApiResponse<{
317
+ task?: {
318
+ id: string;
319
+ title: string;
320
+ description?: string;
321
+ priority: number;
322
+ estimated_minutes?: number;
323
+ blocking?: boolean;
324
+ } | null;
325
+ blocking_task?: boolean;
326
+ deployment_blocks_tasks?: boolean;
327
+ deployment?: {
328
+ id: string;
329
+ status: string;
330
+ env: string;
331
+ };
332
+ awaiting_validation?: Array<{
333
+ id: string;
334
+ title: string;
335
+ }>;
336
+ validation_priority?: string;
337
+ all_claimed?: boolean;
338
+ is_subtask?: boolean;
339
+ suggested_activity?: string;
340
+ directive?: string;
341
+ message?: string;
342
+ action?: string;
343
+ }>> {
344
+ const url = sessionId
345
+ ? `/api/mcp/projects/${projectId}/next-task?session_id=${sessionId}`
346
+ : `/api/mcp/projects/${projectId}/next-task`;
347
+ return this.request('GET', url);
348
+ }
349
+
350
+ async getTask(taskId: string): Promise<ApiResponse<{
351
+ task: {
352
+ id: string;
353
+ title: string;
354
+ description?: string;
355
+ priority: number;
356
+ status: string;
357
+ progress_percentage?: number;
358
+ estimated_minutes?: number;
359
+ started_at?: string;
360
+ completed_at?: string;
361
+ git_branch?: string;
362
+ blocking?: boolean;
363
+ references?: Array<{ url: string; label?: string }>;
364
+ parent_task_id?: string;
365
+ working_agent_session_id?: string;
366
+ };
367
+ }>> {
368
+ return this.request('GET', `/api/mcp/tasks/${taskId}`);
369
+ }
370
+
371
+ async updateTask(taskId: string, updates: {
372
+ title?: string;
373
+ description?: string;
374
+ priority?: number;
375
+ status?: string;
376
+ progress_percentage?: number;
377
+ progress_note?: string;
378
+ estimated_minutes?: number;
379
+ git_branch?: string;
380
+ session_id?: string;
381
+ }): Promise<ApiResponse<{
382
+ success: boolean;
383
+ task_id: string;
384
+ }>> {
385
+ return this.request('PATCH', `/api/mcp/tasks/${taskId}`, updates);
386
+ }
387
+
388
+ async completeTask(taskId: string, params: {
389
+ summary?: string;
390
+ session_id?: string;
391
+ }): Promise<ApiResponse<{
392
+ success: boolean;
393
+ directive: string;
394
+ auto_continue: boolean;
395
+ completed_task_id: string;
396
+ next_task?: {
397
+ id: string;
398
+ title: string;
399
+ priority: number;
400
+ estimated_minutes?: number;
401
+ } | null;
402
+ context?: {
403
+ validation?: number;
404
+ blockers?: number;
405
+ deployment?: string;
406
+ };
407
+ next_action: string;
408
+ }>> {
409
+ return this.request('POST', `/api/mcp/tasks/${taskId}/complete`, params);
410
+ }
411
+
412
+ async deleteTask(taskId: string): Promise<ApiResponse<{
413
+ success: boolean;
414
+ deleted_id: string;
415
+ }>> {
416
+ return this.request('DELETE', `/api/mcp/tasks/${taskId}`);
417
+ }
418
+
419
+ // Progress endpoints
420
+ async logProgress(projectId: string, params: {
421
+ summary: string;
422
+ details?: string;
423
+ task_id?: string;
424
+ session_id?: string;
425
+ }): Promise<ApiResponse<{
426
+ success: boolean;
427
+ progress_id: string;
428
+ }>> {
429
+ return this.request('POST', `/api/mcp/projects/${projectId}/progress`, params);
430
+ }
431
+
432
+ // Git workflow endpoint
433
+ async getGitWorkflow(projectId: string, taskId?: string): Promise<ApiResponse<{
434
+ workflow: string;
435
+ main_branch: string;
436
+ develop_branch?: string | null;
437
+ auto_branch?: boolean;
438
+ auto_tag?: boolean;
439
+ instructions: string[];
440
+ task?: {
441
+ id: string;
442
+ title: string;
443
+ current_branch?: string;
444
+ suggested_branch?: string | null;
445
+ };
446
+ }>> {
447
+ const url = taskId
448
+ ? `/api/mcp/projects/${projectId}/git-workflow?task_id=${taskId}`
449
+ : `/api/mcp/projects/${projectId}/git-workflow`;
450
+ return this.request('GET', url);
451
+ }
452
+
453
+ // ============================================================================
454
+ // Proxy endpoint - Generic method for all operations
455
+ // ============================================================================
456
+ async proxy<T>(operation: string, args: Record<string, unknown>, sessionContext?: {
457
+ session_id: string | null;
458
+ persona: string | null;
459
+ instance_id: string;
460
+ }): Promise<ApiResponse<T>> {
461
+ return this.request('POST', '/api/mcp/proxy', {
462
+ operation,
463
+ args,
464
+ session_context: sessionContext
465
+ });
466
+ }
467
+
468
+ // ============================================================================
469
+ // Blocker endpoints
470
+ // ============================================================================
471
+ async getBlockers(projectId: string, params?: {
472
+ status?: string;
473
+ limit?: number;
474
+ offset?: number;
475
+ search_query?: string;
476
+ }): Promise<ApiResponse<{
477
+ blockers: Array<{
478
+ id: string;
479
+ description: string;
480
+ status: string;
481
+ resolution_note?: string;
482
+ created_at: string;
483
+ resolved_at?: string;
484
+ }>;
485
+ total_count?: number;
486
+ has_more?: boolean;
487
+ }>> {
488
+ return this.proxy('get_blockers', {
489
+ project_id: projectId,
490
+ ...params
491
+ });
492
+ }
493
+
494
+ async addBlocker(projectId: string, description: string, sessionId?: string): Promise<ApiResponse<{
495
+ success: boolean;
496
+ blocker_id: string;
497
+ }>> {
498
+ return this.proxy('add_blocker', { project_id: projectId, description }, sessionId ? {
499
+ session_id: sessionId,
500
+ persona: null,
501
+ instance_id: ''
502
+ } : undefined);
503
+ }
504
+
505
+ async resolveBlocker(blockerId: string, resolutionNote?: string): Promise<ApiResponse<{
506
+ success: boolean;
507
+ blocker_id: string;
508
+ }>> {
509
+ return this.proxy('resolve_blocker', {
510
+ blocker_id: blockerId,
511
+ resolution_note: resolutionNote
512
+ });
513
+ }
514
+
515
+ async deleteBlocker(blockerId: string): Promise<ApiResponse<{
516
+ success: boolean;
517
+ }>> {
518
+ return this.proxy('delete_blocker', { blocker_id: blockerId });
519
+ }
520
+
521
+ // ============================================================================
522
+ // Decision endpoints
523
+ // ============================================================================
524
+ async getDecisions(projectId: string): Promise<ApiResponse<{
525
+ decisions: Array<{
526
+ id: string;
527
+ title: string;
528
+ description: string;
529
+ rationale?: string;
530
+ alternatives_considered?: string[];
531
+ created_at: string;
532
+ }>;
533
+ }>> {
534
+ return this.proxy('get_decisions', { project_id: projectId });
535
+ }
536
+
537
+ async logDecision(projectId: string, params: {
538
+ title: string;
539
+ description: string;
540
+ rationale?: string;
541
+ alternatives_considered?: string[];
542
+ }, sessionId?: string): Promise<ApiResponse<{
543
+ success: boolean;
544
+ decision_id: string;
545
+ }>> {
546
+ return this.proxy('log_decision', {
547
+ project_id: projectId,
548
+ ...params
549
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
550
+ }
551
+
552
+ async deleteDecision(decisionId: string): Promise<ApiResponse<{
553
+ success: boolean;
554
+ }>> {
555
+ return this.proxy('delete_decision', { decision_id: decisionId });
556
+ }
557
+
558
+ // ============================================================================
559
+ // Idea endpoints
560
+ // ============================================================================
561
+ async getIdeas(projectId: string, params?: {
562
+ status?: string;
563
+ limit?: number;
564
+ offset?: number;
565
+ search_query?: string;
566
+ }): Promise<ApiResponse<{
567
+ ideas: Array<{
568
+ id: string;
569
+ title: string;
570
+ description?: string;
571
+ status: string;
572
+ doc_url?: string;
573
+ created_at: string;
574
+ }>;
575
+ }>> {
576
+ return this.proxy('get_ideas', {
577
+ project_id: projectId,
578
+ ...params
579
+ });
580
+ }
581
+
582
+ async addIdea(projectId: string, params: {
583
+ title: string;
584
+ description?: string;
585
+ status?: string;
586
+ }, sessionId?: string): Promise<ApiResponse<{
587
+ success: boolean;
588
+ idea_id: string;
589
+ }>> {
590
+ return this.proxy('add_idea', {
591
+ project_id: projectId,
592
+ ...params
593
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
594
+ }
595
+
596
+ async updateIdea(ideaId: string, updates: {
597
+ title?: string;
598
+ description?: string;
599
+ status?: string;
600
+ doc_url?: string;
601
+ }): Promise<ApiResponse<{
602
+ success: boolean;
603
+ idea_id: string;
604
+ }>> {
605
+ return this.proxy('update_idea', {
606
+ idea_id: ideaId,
607
+ ...updates
608
+ });
609
+ }
610
+
611
+ async deleteIdea(ideaId: string): Promise<ApiResponse<{
612
+ success: boolean;
613
+ }>> {
614
+ return this.proxy('delete_idea', { idea_id: ideaId });
615
+ }
616
+
617
+ async convertIdeaToTask(ideaId: string, params?: {
618
+ priority?: number;
619
+ estimated_minutes?: number;
620
+ update_status?: boolean;
621
+ }): Promise<ApiResponse<{
622
+ success: boolean;
623
+ task_id?: string;
624
+ task_title?: string;
625
+ idea_id?: string;
626
+ idea_status?: string;
627
+ message?: string;
628
+ error?: string;
629
+ existing_task_id?: string;
630
+ }>> {
631
+ return this.proxy('convert_idea_to_task', {
632
+ idea_id: ideaId,
633
+ ...params
634
+ });
635
+ }
636
+
637
+ // ============================================================================
638
+ // Finding endpoints
639
+ // ============================================================================
640
+ async getFindings(projectId: string, params?: {
641
+ category?: string;
642
+ severity?: string;
643
+ status?: string;
644
+ limit?: number;
645
+ }): Promise<ApiResponse<{
646
+ findings: Array<{
647
+ id: string;
648
+ title: string;
649
+ description?: string;
650
+ category: string;
651
+ severity: string;
652
+ status: string;
653
+ file_path?: string;
654
+ line_number?: number;
655
+ resolution_note?: string;
656
+ created_at: string;
657
+ }>;
658
+ }>> {
659
+ return this.proxy('get_findings', {
660
+ project_id: projectId,
661
+ ...params
662
+ });
663
+ }
664
+
665
+ async addFinding(projectId: string, params: {
666
+ title: string;
667
+ description?: string;
668
+ category?: string;
669
+ severity?: string;
670
+ file_path?: string;
671
+ line_number?: number;
672
+ related_task_id?: string;
673
+ }, sessionId?: string): Promise<ApiResponse<{
674
+ success: boolean;
675
+ finding_id: string;
676
+ }>> {
677
+ return this.proxy('add_finding', {
678
+ project_id: projectId,
679
+ ...params
680
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
681
+ }
682
+
683
+ async updateFinding(findingId: string, updates: {
684
+ title?: string;
685
+ description?: string;
686
+ severity?: string;
687
+ status?: string;
688
+ resolution_note?: string;
689
+ }): Promise<ApiResponse<{
690
+ success: boolean;
691
+ finding_id: string;
692
+ }>> {
693
+ return this.proxy('update_finding', {
694
+ finding_id: findingId,
695
+ ...updates
696
+ });
697
+ }
698
+
699
+ async deleteFinding(findingId: string): Promise<ApiResponse<{
700
+ success: boolean;
701
+ }>> {
702
+ return this.proxy('delete_finding', { finding_id: findingId });
703
+ }
704
+
705
+ // ============================================================================
706
+ // Milestone endpoints
707
+ // ============================================================================
708
+ async getMilestones(taskId: string): Promise<ApiResponse<{
709
+ milestones: Array<{
710
+ id: string;
711
+ title: string;
712
+ description?: string;
713
+ status: string;
714
+ order_index: number;
715
+ created_at: string;
716
+ completed_at?: string;
717
+ }>;
718
+ stats: {
719
+ total: number;
720
+ completed: number;
721
+ progress_percentage: number;
722
+ };
723
+ }>> {
724
+ return this.proxy('get_milestones', { task_id: taskId });
725
+ }
726
+
727
+ async addMilestone(taskId: string, params: {
728
+ title: string;
729
+ description?: string;
730
+ order_index?: number;
731
+ }, sessionId?: string): Promise<ApiResponse<{
732
+ success: boolean;
733
+ milestone_id: string;
734
+ }>> {
735
+ return this.proxy('add_milestone', {
736
+ task_id: taskId,
737
+ ...params
738
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
739
+ }
740
+
741
+ async updateMilestone(milestoneId: string, updates: {
742
+ title?: string;
743
+ description?: string;
744
+ status?: string;
745
+ order_index?: number;
746
+ }): Promise<ApiResponse<{
747
+ success: boolean;
748
+ milestone: {
749
+ id: string;
750
+ title: string;
751
+ status: string;
752
+ };
753
+ }>> {
754
+ return this.proxy('update_milestone', {
755
+ milestone_id: milestoneId,
756
+ ...updates
757
+ });
758
+ }
759
+
760
+ async completeMilestone(milestoneId: string): Promise<ApiResponse<{
761
+ success: boolean;
762
+ milestone: {
763
+ id: string;
764
+ title: string;
765
+ status: string;
766
+ };
767
+ }>> {
768
+ return this.proxy('complete_milestone', { milestone_id: milestoneId });
769
+ }
770
+
771
+ async deleteMilestone(milestoneId: string): Promise<ApiResponse<{
772
+ success: boolean;
773
+ }>> {
774
+ return this.proxy('delete_milestone', { milestone_id: milestoneId });
775
+ }
776
+
777
+ // ============================================================================
778
+ // Request endpoints
779
+ // ============================================================================
780
+ async getPendingRequests(projectId: string, sessionId?: string): Promise<ApiResponse<{
781
+ requests: Array<{
782
+ id: string;
783
+ request_type: string;
784
+ message: string;
785
+ created_at: string;
786
+ }>;
787
+ }>> {
788
+ return this.proxy('get_pending_requests', { project_id: projectId }, sessionId ? {
789
+ session_id: sessionId,
790
+ persona: null,
791
+ instance_id: ''
792
+ } : undefined);
793
+ }
794
+
795
+ async acknowledgeRequest(requestId: string, sessionId?: string): Promise<ApiResponse<{
796
+ success: boolean;
797
+ }>> {
798
+ return this.proxy('acknowledge_request', { request_id: requestId }, sessionId ? {
799
+ session_id: sessionId,
800
+ persona: null,
801
+ instance_id: ''
802
+ } : undefined);
803
+ }
804
+
805
+ async answerQuestion(requestId: string, answer: string, sessionId?: string): Promise<ApiResponse<{
806
+ success: boolean;
807
+ }>> {
808
+ return this.proxy('answer_question', {
809
+ request_id: requestId,
810
+ answer
811
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
812
+ }
813
+
814
+ // ============================================================================
815
+ // Validation endpoints
816
+ // ============================================================================
817
+ async getTasksAwaitingValidation(projectId: string): Promise<ApiResponse<{
818
+ tasks: Array<{
819
+ id: string;
820
+ title: string;
821
+ completed_at?: string;
822
+ completed_by_session_id?: string;
823
+ }>;
824
+ }>> {
825
+ return this.proxy('get_tasks_awaiting_validation', { project_id: projectId });
826
+ }
827
+
828
+ async claimValidation(taskId: string, sessionId?: string): Promise<ApiResponse<{
829
+ success: boolean;
830
+ task_id: string;
831
+ }>> {
832
+ return this.proxy('claim_validation', { task_id: taskId }, sessionId ? {
833
+ session_id: sessionId,
834
+ persona: null,
835
+ instance_id: ''
836
+ } : undefined);
837
+ }
838
+
839
+ async validateTask(taskId: string, params: {
840
+ approved: boolean;
841
+ validation_notes?: string;
842
+ }, sessionId?: string): Promise<ApiResponse<{
843
+ success: boolean;
844
+ approved: boolean;
845
+ task_id: string;
846
+ message?: string;
847
+ }>> {
848
+ return this.proxy('validate_task', {
849
+ task_id: taskId,
850
+ ...params
851
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
852
+ }
853
+
854
+ // ============================================================================
855
+ // Fallback activity endpoints
856
+ // ============================================================================
857
+ async startFallbackActivity(projectId: string, activity: string, sessionId?: string): Promise<ApiResponse<{
858
+ success: boolean;
859
+ activity: string;
860
+ message: string;
861
+ }>> {
862
+ return this.proxy('start_fallback_activity', {
863
+ project_id: projectId,
864
+ activity
865
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
866
+ }
867
+
868
+ async stopFallbackActivity(projectId: string, summary?: string, sessionId?: string): Promise<ApiResponse<{
869
+ success: boolean;
870
+ }>> {
871
+ return this.proxy('stop_fallback_activity', {
872
+ project_id: projectId,
873
+ summary
874
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
875
+ }
876
+
877
+ async getActivityHistory(projectId: string, params?: {
878
+ activity_type?: string;
879
+ limit?: number;
880
+ }): Promise<ApiResponse<{
881
+ history: Array<{
882
+ id: string;
883
+ activity_type: string;
884
+ completed_at: string;
885
+ summary?: string;
886
+ }>;
887
+ latest_by_type: Record<string, unknown>;
888
+ count: number;
889
+ }>> {
890
+ return this.proxy('get_activity_history', {
891
+ project_id: projectId,
892
+ ...params
893
+ });
894
+ }
895
+
896
+ async getActivitySchedules(projectId: string): Promise<ApiResponse<{
897
+ schedules: Array<{
898
+ id: string;
899
+ activity_type: string;
900
+ schedule_type: string;
901
+ next_run_at?: string;
902
+ enabled: boolean;
903
+ }>;
904
+ due_activities: string[];
905
+ count: number;
906
+ }>> {
907
+ return this.proxy('get_activity_schedules', { project_id: projectId });
908
+ }
909
+
910
+ // ============================================================================
911
+ // Subtask endpoints
912
+ // ============================================================================
913
+ async addSubtask(parentTaskId: string, params: {
914
+ title: string;
915
+ description?: string;
916
+ priority?: number;
917
+ estimated_minutes?: number;
918
+ }, sessionId?: string): Promise<ApiResponse<{
919
+ success: boolean;
920
+ subtask_id: string;
921
+ parent_task_id: string;
922
+ }>> {
923
+ return this.proxy('add_subtask', {
924
+ parent_task_id: parentTaskId,
925
+ ...params
926
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
927
+ }
928
+
929
+ async getSubtasks(parentTaskId: string, status?: string): Promise<ApiResponse<{
930
+ subtasks: Array<{
931
+ id: string;
932
+ title: string;
933
+ description?: string;
934
+ priority: number;
935
+ status: string;
936
+ progress_percentage?: number;
937
+ estimated_minutes?: number;
938
+ }>;
939
+ stats: {
940
+ total: number;
941
+ completed: number;
942
+ progress_percentage: number;
943
+ };
944
+ }>> {
945
+ return this.proxy('get_subtasks', {
946
+ parent_task_id: parentTaskId,
947
+ status
948
+ });
949
+ }
950
+
951
+ // ============================================================================
952
+ // Activity feed endpoint
953
+ // ============================================================================
954
+ async getActivityFeed(projectId: string, params?: {
955
+ limit?: number;
956
+ since?: string;
957
+ }): Promise<ApiResponse<{
958
+ activities: Array<{
959
+ type: string;
960
+ data: unknown;
961
+ timestamp: string;
962
+ }>;
963
+ }>> {
964
+ return this.proxy('get_activity_feed', {
965
+ project_id: projectId,
966
+ ...params
967
+ });
968
+ }
969
+
970
+ // ============================================================================
971
+ // Deployment endpoints
972
+ // ============================================================================
973
+ async requestDeployment(projectId: string, params?: {
974
+ environment?: string;
975
+ version_bump?: string;
976
+ git_ref?: string;
977
+ notes?: string;
978
+ }, sessionId?: string): Promise<ApiResponse<{
979
+ success: boolean;
980
+ deployment_id: string;
981
+ status: string;
982
+ }>> {
983
+ return this.proxy('request_deployment', {
984
+ project_id: projectId,
985
+ ...params
986
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
987
+ }
988
+
989
+ async checkDeploymentStatus(projectId: string): Promise<ApiResponse<{
990
+ active_deployment: boolean;
991
+ deployment?: {
992
+ id: string;
993
+ status: string;
994
+ environment: string;
995
+ git_ref?: string;
996
+ created_at: string;
997
+ };
998
+ }>> {
999
+ return this.proxy('check_deployment_status', { project_id: projectId });
1000
+ }
1001
+
1002
+ async claimDeploymentValidation(projectId: string, sessionId?: string): Promise<ApiResponse<{
1003
+ success: boolean;
1004
+ deployment_id: string;
1005
+ message: string;
1006
+ }>> {
1007
+ return this.proxy('claim_deployment_validation', { project_id: projectId }, sessionId ? {
1008
+ session_id: sessionId,
1009
+ persona: null,
1010
+ instance_id: ''
1011
+ } : undefined);
1012
+ }
1013
+
1014
+ async reportValidation(projectId: string, params: {
1015
+ build_passed: boolean;
1016
+ tests_passed: boolean;
1017
+ error_message?: string;
1018
+ }): Promise<ApiResponse<{
1019
+ success: boolean;
1020
+ deployment_id: string;
1021
+ status: string;
1022
+ }>> {
1023
+ return this.proxy('report_validation', {
1024
+ project_id: projectId,
1025
+ ...params
1026
+ });
1027
+ }
1028
+
1029
+ async startDeployment(projectId: string, sessionId?: string): Promise<ApiResponse<{
1030
+ success: boolean;
1031
+ deployment_id: string;
1032
+ instructions: string;
1033
+ }>> {
1034
+ return this.proxy('start_deployment', { project_id: projectId }, sessionId ? {
1035
+ session_id: sessionId,
1036
+ persona: null,
1037
+ instance_id: ''
1038
+ } : undefined);
1039
+ }
1040
+
1041
+ async completeDeployment(projectId: string, params: {
1042
+ success: boolean;
1043
+ summary?: string;
1044
+ }): Promise<ApiResponse<{
1045
+ success: boolean;
1046
+ deployment_id: string;
1047
+ status: string;
1048
+ }>> {
1049
+ return this.proxy('complete_deployment', {
1050
+ project_id: projectId,
1051
+ ...params
1052
+ });
1053
+ }
1054
+
1055
+ async cancelDeployment(projectId: string, reason?: string): Promise<ApiResponse<{
1056
+ success: boolean;
1057
+ }>> {
1058
+ return this.proxy('cancel_deployment', {
1059
+ project_id: projectId,
1060
+ reason
1061
+ });
1062
+ }
1063
+
1064
+ // ============================================================================
1065
+ // Task reference endpoints
1066
+ // ============================================================================
1067
+ async addTaskReference(taskId: string, url: string, label?: string): Promise<ApiResponse<{
1068
+ success: boolean;
1069
+ reference: { url: string; label?: string };
1070
+ }>> {
1071
+ return this.proxy('add_task_reference', {
1072
+ task_id: taskId,
1073
+ url,
1074
+ label
1075
+ });
1076
+ }
1077
+
1078
+ async removeTaskReference(taskId: string, url: string): Promise<ApiResponse<{
1079
+ success: boolean;
1080
+ }>> {
1081
+ return this.proxy('remove_task_reference', {
1082
+ task_id: taskId,
1083
+ url
1084
+ });
1085
+ }
1086
+
1087
+ // ============================================================================
1088
+ // Knowledge base endpoint
1089
+ // ============================================================================
1090
+ async queryKnowledgeBase(projectId: string, params?: {
1091
+ categories?: string[];
1092
+ limit?: number;
1093
+ search_query?: string;
1094
+ }): Promise<ApiResponse<{
1095
+ findings?: Array<{ id: string; title: string; category: string; severity: string }>;
1096
+ decisions?: Array<{ id: string; title: string; description: string }>;
1097
+ completed_tasks?: Array<{ id: string; title: string; completed_at: string }>;
1098
+ resolved_blockers?: Array<{ id: string; description: string; resolution_note?: string }>;
1099
+ }>> {
1100
+ return this.proxy('query_knowledge_base', {
1101
+ project_id: projectId,
1102
+ ...params
1103
+ });
1104
+ }
1105
+
1106
+ // ============================================================================
1107
+ // Session sync endpoint
1108
+ // ============================================================================
1109
+ async syncSession(sessionId: string, params?: {
1110
+ total_tokens?: number;
1111
+ token_breakdown?: Record<string, unknown>;
1112
+ model_usage?: Record<string, unknown>;
1113
+ }): Promise<ApiResponse<{
1114
+ success: boolean;
1115
+ }>> {
1116
+ return this.proxy('sync_session', {
1117
+ session_id: sessionId,
1118
+ ...params
1119
+ });
1120
+ }
1121
+
1122
+ // ============================================================================
1123
+ // Organization endpoints
1124
+ // ============================================================================
1125
+ async listOrganizations(): Promise<ApiResponse<{
1126
+ organizations: Array<{
1127
+ id: string;
1128
+ name: string;
1129
+ slug: string;
1130
+ description?: string;
1131
+ role: string;
1132
+ }>;
1133
+ }>> {
1134
+ return this.proxy('list_organizations', {});
1135
+ }
1136
+
1137
+ async createOrganization(params: {
1138
+ name: string;
1139
+ slug?: string;
1140
+ description?: string;
1141
+ }): Promise<ApiResponse<{
1142
+ success: boolean;
1143
+ organization: { id: string; name: string; slug: string };
1144
+ }>> {
1145
+ return this.proxy('create_organization', params);
1146
+ }
1147
+
1148
+ async updateOrganization(organizationId: string, updates: {
1149
+ name?: string;
1150
+ description?: string;
1151
+ logo_url?: string;
1152
+ }): Promise<ApiResponse<{
1153
+ success: boolean;
1154
+ organization_id: string;
1155
+ }>> {
1156
+ return this.proxy('update_organization', {
1157
+ organization_id: organizationId,
1158
+ ...updates
1159
+ });
1160
+ }
1161
+
1162
+ async deleteOrganization(organizationId: string): Promise<ApiResponse<{
1163
+ success: boolean;
1164
+ }>> {
1165
+ return this.proxy('delete_organization', { organization_id: organizationId });
1166
+ }
1167
+
1168
+ async listOrgMembers(organizationId: string): Promise<ApiResponse<{
1169
+ members: Array<{
1170
+ user_id: string;
1171
+ email: string;
1172
+ role: string;
1173
+ joined_at: string;
1174
+ }>;
1175
+ }>> {
1176
+ return this.proxy('list_org_members', { organization_id: organizationId });
1177
+ }
1178
+
1179
+ async inviteMember(organizationId: string, email: string, role?: string): Promise<ApiResponse<{
1180
+ success: boolean;
1181
+ invite_id: string;
1182
+ }>> {
1183
+ return this.proxy('invite_member', {
1184
+ organization_id: organizationId,
1185
+ email,
1186
+ role
1187
+ });
1188
+ }
1189
+
1190
+ async updateMemberRole(organizationId: string, userId: string, role: string): Promise<ApiResponse<{
1191
+ success: boolean;
1192
+ }>> {
1193
+ return this.proxy('update_member_role', {
1194
+ organization_id: organizationId,
1195
+ user_id: userId,
1196
+ role
1197
+ });
1198
+ }
1199
+
1200
+ async removeMember(organizationId: string, userId: string): Promise<ApiResponse<{
1201
+ success: boolean;
1202
+ }>> {
1203
+ return this.proxy('remove_member', {
1204
+ organization_id: organizationId,
1205
+ user_id: userId
1206
+ });
1207
+ }
1208
+
1209
+ async shareProjectWithOrg(projectId: string, organizationId: string, permission?: string): Promise<ApiResponse<{
1210
+ success: boolean;
1211
+ }>> {
1212
+ return this.proxy('share_project_with_org', {
1213
+ project_id: projectId,
1214
+ organization_id: organizationId,
1215
+ permission
1216
+ });
1217
+ }
1218
+
1219
+ async unshareProject(projectId: string, organizationId: string): Promise<ApiResponse<{
1220
+ success: boolean;
1221
+ }>> {
1222
+ return this.proxy('unshare_project', {
1223
+ project_id: projectId,
1224
+ organization_id: organizationId
1225
+ });
1226
+ }
1227
+
1228
+ async leaveOrganization(organizationId: string): Promise<ApiResponse<{
1229
+ success: boolean;
1230
+ message: string;
1231
+ }>> {
1232
+ return this.proxy('leave_organization', { organization_id: organizationId });
1233
+ }
1234
+
1235
+ async updateProjectShare(projectId: string, organizationId: string, permission: string): Promise<ApiResponse<{
1236
+ success: boolean;
1237
+ share: { permission: string };
1238
+ }>> {
1239
+ return this.proxy('update_project_share', {
1240
+ project_id: projectId,
1241
+ organization_id: organizationId,
1242
+ permission
1243
+ });
1244
+ }
1245
+
1246
+ async listProjectShares(projectId: string): Promise<ApiResponse<{
1247
+ shares: Array<{
1248
+ id: string;
1249
+ permission: string;
1250
+ shared_at: string;
1251
+ organization: { id: string; name: string; slug: string };
1252
+ }>;
1253
+ count: number;
1254
+ }>> {
1255
+ return this.proxy('list_project_shares', { project_id: projectId });
1256
+ }
1257
+
1258
+ // ============================================================================
1259
+ // Body of work endpoints
1260
+ // ============================================================================
1261
+ async createBodyOfWork(projectId: string, params: {
1262
+ title: string;
1263
+ description?: string;
1264
+ auto_deploy_on_completion?: boolean;
1265
+ deploy_environment?: string;
1266
+ deploy_version_bump?: string;
1267
+ deploy_trigger?: string;
1268
+ }): Promise<ApiResponse<{
1269
+ success: boolean;
1270
+ body_of_work_id: string;
1271
+ }>> {
1272
+ return this.proxy('create_body_of_work', {
1273
+ project_id: projectId,
1274
+ ...params
1275
+ });
1276
+ }
1277
+
1278
+ async getBodyOfWork(bodyOfWorkId: string): Promise<ApiResponse<{
1279
+ body_of_work: {
1280
+ id: string;
1281
+ title: string;
1282
+ description?: string;
1283
+ status: string;
1284
+ auto_deploy_on_completion: boolean;
1285
+ };
1286
+ tasks: {
1287
+ pre: Array<{ id: string; title: string; status: string }>;
1288
+ core: Array<{ id: string; title: string; status: string }>;
1289
+ post: Array<{ id: string; title: string; status: string }>;
1290
+ };
1291
+ }>> {
1292
+ return this.proxy('get_body_of_work', { body_of_work_id: bodyOfWorkId });
1293
+ }
1294
+
1295
+ async getBodiesOfWork(projectId: string, params?: {
1296
+ status?: string;
1297
+ limit?: number;
1298
+ offset?: number;
1299
+ search_query?: string;
1300
+ }): Promise<ApiResponse<{
1301
+ bodies_of_work: Array<{
1302
+ id: string;
1303
+ title: string;
1304
+ description?: string;
1305
+ status: string;
1306
+ task_counts: { pre: number; core: number; post: number };
1307
+ }>;
1308
+ }>> {
1309
+ return this.proxy('get_bodies_of_work', {
1310
+ project_id: projectId,
1311
+ ...params
1312
+ });
1313
+ }
1314
+
1315
+ async updateBodyOfWork(bodyOfWorkId: string, updates: {
1316
+ title?: string;
1317
+ description?: string;
1318
+ auto_deploy_on_completion?: boolean;
1319
+ deploy_environment?: string;
1320
+ deploy_version_bump?: string;
1321
+ deploy_trigger?: string;
1322
+ }): Promise<ApiResponse<{
1323
+ success: boolean;
1324
+ }>> {
1325
+ return this.proxy('update_body_of_work', {
1326
+ body_of_work_id: bodyOfWorkId,
1327
+ ...updates
1328
+ });
1329
+ }
1330
+
1331
+ async deleteBodyOfWork(bodyOfWorkId: string): Promise<ApiResponse<{
1332
+ success: boolean;
1333
+ }>> {
1334
+ return this.proxy('delete_body_of_work', { body_of_work_id: bodyOfWorkId });
1335
+ }
1336
+
1337
+ async addTaskToBodyOfWork(bodyOfWorkId: string, taskId: string, phase?: string, orderIndex?: number): Promise<ApiResponse<{
1338
+ success: boolean;
1339
+ }>> {
1340
+ return this.proxy('add_task_to_body_of_work', {
1341
+ body_of_work_id: bodyOfWorkId,
1342
+ task_id: taskId,
1343
+ phase,
1344
+ order_index: orderIndex
1345
+ });
1346
+ }
1347
+
1348
+ async removeTaskFromBodyOfWork(taskId: string): Promise<ApiResponse<{
1349
+ success: boolean;
1350
+ }>> {
1351
+ return this.proxy('remove_task_from_body_of_work', { task_id: taskId });
1352
+ }
1353
+
1354
+ async activateBodyOfWork(bodyOfWorkId: string): Promise<ApiResponse<{
1355
+ success: boolean;
1356
+ status: string;
1357
+ }>> {
1358
+ return this.proxy('activate_body_of_work', { body_of_work_id: bodyOfWorkId });
1359
+ }
1360
+
1361
+ async addTaskDependency(bodyOfWorkId: string, taskId: string, dependsOnTaskId: string): Promise<ApiResponse<{
1362
+ success: boolean;
1363
+ }>> {
1364
+ return this.proxy('add_task_dependency', {
1365
+ body_of_work_id: bodyOfWorkId,
1366
+ task_id: taskId,
1367
+ depends_on_task_id: dependsOnTaskId
1368
+ });
1369
+ }
1370
+
1371
+ async removeTaskDependency(taskId: string, dependsOnTaskId: string): Promise<ApiResponse<{
1372
+ success: boolean;
1373
+ }>> {
1374
+ return this.proxy('remove_task_dependency', {
1375
+ task_id: taskId,
1376
+ depends_on_task_id: dependsOnTaskId
1377
+ });
1378
+ }
1379
+
1380
+ async getTaskDependencies(params: {
1381
+ body_of_work_id?: string;
1382
+ task_id?: string;
1383
+ }): Promise<ApiResponse<{
1384
+ dependencies: Array<{
1385
+ id: string;
1386
+ task_id: string;
1387
+ depends_on_task_id: string;
1388
+ created_at: string;
1389
+ }>;
1390
+ }>> {
1391
+ return this.proxy('get_task_dependencies', params);
1392
+ }
1393
+
1394
+ async getNextBodyOfWorkTask(bodyOfWorkId: string): Promise<ApiResponse<{
1395
+ task?: {
1396
+ id: string;
1397
+ title: string;
1398
+ priority: number;
1399
+ phase: string;
1400
+ } | null;
1401
+ message?: string;
1402
+ }>> {
1403
+ return this.proxy('get_next_body_of_work_task', { body_of_work_id: bodyOfWorkId });
1404
+ }
1405
+
1406
+ // ============================================================================
1407
+ // Git issues endpoints
1408
+ // ============================================================================
1409
+ async addGitIssue(projectId: string, params: {
1410
+ issue_type: string;
1411
+ branch: string;
1412
+ target_branch?: string;
1413
+ pr_url?: string;
1414
+ conflicting_files?: string[];
1415
+ error_message?: string;
1416
+ task_id?: string;
1417
+ }, sessionId?: string): Promise<ApiResponse<{
1418
+ success: boolean;
1419
+ git_issue_id: string;
1420
+ }>> {
1421
+ return this.proxy('add_git_issue', {
1422
+ project_id: projectId,
1423
+ ...params
1424
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
1425
+ }
1426
+
1427
+ async resolveGitIssue(gitIssueId: string, params?: {
1428
+ resolution_note?: string;
1429
+ auto_resolved?: boolean;
1430
+ }, sessionId?: string): Promise<ApiResponse<{
1431
+ success: boolean;
1432
+ git_issue_id: string;
1433
+ }>> {
1434
+ return this.proxy('resolve_git_issue', {
1435
+ git_issue_id: gitIssueId,
1436
+ ...params
1437
+ }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
1438
+ }
1439
+
1440
+ async getGitIssues(projectId: string, params?: {
1441
+ status?: string;
1442
+ issue_type?: string;
1443
+ branch?: string;
1444
+ limit?: number;
1445
+ }): Promise<ApiResponse<{
1446
+ git_issues: Array<{
1447
+ id: string;
1448
+ issue_type: string;
1449
+ branch: string;
1450
+ target_branch?: string;
1451
+ pr_url?: string;
1452
+ conflicting_files?: string[];
1453
+ error_message?: string;
1454
+ status: string;
1455
+ created_at: string;
1456
+ resolved_at?: string;
1457
+ }>;
1458
+ }>> {
1459
+ return this.proxy('get_git_issues', {
1460
+ project_id: projectId,
1461
+ ...params
1462
+ });
1463
+ }
1464
+
1465
+ async deleteGitIssue(gitIssueId: string): Promise<ApiResponse<{
1466
+ success: boolean;
1467
+ }>> {
1468
+ return this.proxy('delete_git_issue', { git_issue_id: gitIssueId });
1469
+ }
1470
+
1471
+ // ============================================================================
1472
+ // Cost tracking endpoints
1473
+ // ============================================================================
1474
+ async getCostSummary(projectId: string, params?: {
1475
+ period?: 'daily' | 'weekly' | 'monthly';
1476
+ limit?: number;
1477
+ }): Promise<ApiResponse<{
1478
+ summaries: Array<{
1479
+ date: string;
1480
+ total_cost: number;
1481
+ input_tokens: number;
1482
+ output_tokens: number;
1483
+ }>;
1484
+ }>> {
1485
+ return this.proxy('get_cost_summary', {
1486
+ project_id: projectId,
1487
+ ...params
1488
+ });
1489
+ }
1490
+
1491
+ async getCostAlerts(): Promise<ApiResponse<{
1492
+ alerts: Array<{
1493
+ id: string;
1494
+ threshold_amount: number;
1495
+ threshold_period: string;
1496
+ alert_type: string;
1497
+ enabled: boolean;
1498
+ }>;
1499
+ }>> {
1500
+ return this.proxy('get_cost_alerts', {});
1501
+ }
1502
+
1503
+ async addCostAlert(params: {
1504
+ threshold_amount: number;
1505
+ threshold_period: 'daily' | 'weekly' | 'monthly';
1506
+ alert_type?: 'warning' | 'critical';
1507
+ project_id?: string;
1508
+ }): Promise<ApiResponse<{
1509
+ success: boolean;
1510
+ alert_id: string;
1511
+ }>> {
1512
+ return this.proxy('add_cost_alert', params);
1513
+ }
1514
+
1515
+ async updateCostAlert(alertId: string, updates: {
1516
+ threshold_amount?: number;
1517
+ threshold_period?: string;
1518
+ alert_type?: string;
1519
+ enabled?: boolean;
1520
+ }): Promise<ApiResponse<{
1521
+ success: boolean;
1522
+ }>> {
1523
+ return this.proxy('update_cost_alert', {
1524
+ alert_id: alertId,
1525
+ ...updates
1526
+ });
1527
+ }
1528
+
1529
+ async deleteCostAlert(alertId: string): Promise<ApiResponse<{
1530
+ success: boolean;
1531
+ }>> {
1532
+ return this.proxy('delete_cost_alert', { alert_id: alertId });
1533
+ }
1534
+
1535
+ async getTaskCosts(projectId: string, limit?: number): Promise<ApiResponse<{
1536
+ task_costs: Array<{
1537
+ task_id: string;
1538
+ title: string;
1539
+ total_cost: number;
1540
+ input_tokens: number;
1541
+ output_tokens: number;
1542
+ }>;
1543
+ }>> {
1544
+ return this.proxy('get_task_costs', {
1545
+ project_id: projectId,
1546
+ limit
1547
+ });
1548
+ }
1549
+
1550
+ async getTokenUsage(): Promise<ApiResponse<{
1551
+ session_tokens: number;
1552
+ estimated_cost: number;
1553
+ }>> {
1554
+ return this.proxy('get_token_usage', {});
1555
+ }
1556
+
1557
+ // ============================================================================
1558
+ // Batch operation endpoints
1559
+ // ============================================================================
1560
+ async batchUpdateTasks(updates: Array<{
1561
+ task_id: string;
1562
+ status?: string;
1563
+ priority?: number;
1564
+ progress_percentage?: number;
1565
+ progress_note?: string;
1566
+ }>): Promise<ApiResponse<{
1567
+ success: boolean;
1568
+ updated_count: number;
1569
+ }>> {
1570
+ return this.proxy('batch_update_tasks', { updates });
1571
+ }
1572
+
1573
+ async batchCompleteTasks(completions: Array<{
1574
+ task_id: string;
1575
+ summary?: string;
1576
+ }>): Promise<ApiResponse<{
1577
+ success: boolean;
1578
+ completed_count: number;
1579
+ next_task?: { id: string; title: string } | null;
1580
+ }>> {
1581
+ return this.proxy('batch_complete_tasks', { completions });
1582
+ }
1583
+
1584
+ // ============================================================================
1585
+ // Deployment requirements and scheduling endpoints
1586
+ // ============================================================================
1587
+ async addDeploymentRequirement(projectId: string, params: {
1588
+ type: string;
1589
+ title: string;
1590
+ description?: string;
1591
+ file_path?: string;
1592
+ stage?: string;
1593
+ blocking?: boolean;
1594
+ }): Promise<ApiResponse<{
1595
+ success: boolean;
1596
+ requirement_id: string;
1597
+ }>> {
1598
+ return this.proxy('add_deployment_requirement', {
1599
+ project_id: projectId,
1600
+ ...params
1601
+ });
1602
+ }
1603
+
1604
+ async getDeploymentRequirements(projectId: string, params?: {
1605
+ status?: string;
1606
+ stage?: string;
1607
+ }): Promise<ApiResponse<{
1608
+ requirements: Array<{
1609
+ id: string;
1610
+ type: string;
1611
+ title: string;
1612
+ description?: string;
1613
+ status: string;
1614
+ stage: string;
1615
+ }>;
1616
+ }>> {
1617
+ return this.proxy('get_deployment_requirements', {
1618
+ project_id: projectId,
1619
+ ...params
1620
+ });
1621
+ }
1622
+
1623
+ async completeDeploymentRequirement(requirementId: string): Promise<ApiResponse<{
1624
+ success: boolean;
1625
+ }>> {
1626
+ return this.proxy('complete_deployment_requirement', { requirement_id: requirementId });
1627
+ }
1628
+
1629
+ async scheduleDeployment(projectId: string, params: {
1630
+ scheduled_at: string;
1631
+ schedule_type?: string;
1632
+ environment?: string;
1633
+ version_bump?: string;
1634
+ auto_trigger?: boolean;
1635
+ notes?: string;
1636
+ git_ref?: string;
1637
+ }): Promise<ApiResponse<{
1638
+ success: boolean;
1639
+ schedule_id: string;
1640
+ }>> {
1641
+ return this.proxy('schedule_deployment', {
1642
+ project_id: projectId,
1643
+ ...params
1644
+ });
1645
+ }
1646
+
1647
+ async getScheduledDeployments(projectId: string, includeDisabled?: boolean): Promise<ApiResponse<{
1648
+ schedules: Array<{
1649
+ id: string;
1650
+ scheduled_at: string;
1651
+ schedule_type: string;
1652
+ environment: string;
1653
+ version_bump: string;
1654
+ auto_trigger: boolean;
1655
+ enabled: boolean;
1656
+ git_ref?: string;
1657
+ notes?: string;
1658
+ }>;
1659
+ count: number;
1660
+ due_count: number;
1661
+ }>> {
1662
+ return this.proxy('get_scheduled_deployments', {
1663
+ project_id: projectId,
1664
+ include_disabled: includeDisabled
1665
+ });
1666
+ }
1667
+
1668
+ async updateScheduledDeployment(scheduleId: string, updates: {
1669
+ scheduled_at?: string;
1670
+ schedule_type?: string;
1671
+ environment?: string;
1672
+ version_bump?: string;
1673
+ auto_trigger?: boolean;
1674
+ enabled?: boolean;
1675
+ git_ref?: string;
1676
+ notes?: string;
1677
+ }): Promise<ApiResponse<{
1678
+ success: boolean;
1679
+ schedule_id: string;
1680
+ }>> {
1681
+ return this.proxy('update_scheduled_deployment', {
1682
+ schedule_id: scheduleId,
1683
+ ...updates
1684
+ });
1685
+ }
1686
+
1687
+ async deleteScheduledDeployment(scheduleId: string): Promise<ApiResponse<{
1688
+ success: boolean;
1689
+ }>> {
1690
+ return this.proxy('delete_scheduled_deployment', { schedule_id: scheduleId });
1691
+ }
1692
+
1693
+ async triggerScheduledDeployment(scheduleId: string, sessionId?: string): Promise<ApiResponse<{
1694
+ success: boolean;
1695
+ deployment_id?: string;
1696
+ schedule_id: string;
1697
+ schedule_type: string;
1698
+ next_scheduled_at?: string;
1699
+ message?: string;
1700
+ }>> {
1701
+ return this.proxy('trigger_scheduled_deployment', { schedule_id: scheduleId }, sessionId ? {
1702
+ session_id: sessionId,
1703
+ persona: null,
1704
+ instance_id: ''
1705
+ } : undefined);
1706
+ }
1707
+
1708
+ async checkDueDeployments(projectId: string): Promise<ApiResponse<{
1709
+ due_schedules: Array<{
1710
+ id: string;
1711
+ scheduled_at: string;
1712
+ environment: string;
1713
+ version_bump: string;
1714
+ schedule_type: string;
1715
+ }>;
1716
+ count: number;
1717
+ }>> {
1718
+ return this.proxy('check_due_deployments', { project_id: projectId });
1719
+ }
1720
+
1721
+ // ============================================================================
1722
+ // Project README endpoint
1723
+ // ============================================================================
1724
+ async updateProjectReadme(projectId: string, readmeContent: string): Promise<ApiResponse<{
1725
+ success: boolean;
1726
+ project_id: string;
1727
+ }>> {
1728
+ return this.proxy('update_project_readme', {
1729
+ project_id: projectId,
1730
+ readme_content: readmeContent
1731
+ });
1732
+ }
1733
+ }
1734
+
1735
+ // Singleton instance
1736
+ let apiClient: VibescopeApiClient | null = null;
1737
+
1738
+ export function getApiClient(): VibescopeApiClient {
1739
+ if (!apiClient) {
1740
+ const apiKey = process.env.VIBESCOPE_API_KEY;
1741
+ if (!apiKey) {
1742
+ throw new Error('VIBESCOPE_API_KEY environment variable is required');
1743
+ }
1744
+ apiClient = new VibescopeApiClient({ apiKey });
1745
+ }
1746
+ return apiClient;
1747
+ }
1748
+
1749
+ export function initApiClient(config: ApiClientConfig): VibescopeApiClient {
1750
+ apiClient = new VibescopeApiClient(config);
1751
+ return apiClient;
1752
+ }