@vibescope/mcp-server 0.4.3 → 0.4.5

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 (65) hide show
  1. package/dist/api-client/bodies-of-work.d.ts +125 -0
  2. package/dist/api-client/bodies-of-work.js +78 -0
  3. package/dist/api-client/chat.d.ts +26 -0
  4. package/dist/api-client/chat.js +20 -0
  5. package/dist/api-client/connectors.d.ts +104 -0
  6. package/dist/api-client/connectors.js +46 -0
  7. package/dist/api-client/deployment.d.ts +190 -0
  8. package/dist/api-client/deployment.js +113 -0
  9. package/dist/api-client/file-checkouts.d.ts +71 -0
  10. package/dist/api-client/file-checkouts.js +43 -0
  11. package/dist/api-client/git-issues.d.ts +55 -0
  12. package/dist/api-client/git-issues.js +34 -0
  13. package/dist/api-client/index.d.ts +619 -1
  14. package/dist/api-client/index.js +148 -0
  15. package/dist/api-client/organizations.d.ts +101 -0
  16. package/dist/api-client/organizations.js +86 -0
  17. package/dist/api-client/progress.d.ts +61 -0
  18. package/dist/api-client/progress.js +34 -0
  19. package/dist/api-client/requests.d.ts +28 -0
  20. package/dist/api-client/requests.js +28 -0
  21. package/dist/api-client/sprints.d.ts +153 -0
  22. package/dist/api-client/sprints.js +82 -0
  23. package/dist/api-client/subtasks.d.ts +37 -0
  24. package/dist/api-client/subtasks.js +23 -0
  25. package/dist/api-client.d.ts +22 -0
  26. package/dist/api-client.js +15 -0
  27. package/dist/handlers/blockers.js +4 -0
  28. package/dist/handlers/chat.d.ts +21 -0
  29. package/dist/handlers/chat.js +59 -0
  30. package/dist/handlers/deployment.d.ts +3 -0
  31. package/dist/handlers/deployment.js +23 -0
  32. package/dist/handlers/discovery.js +1 -0
  33. package/dist/handlers/index.d.ts +1 -0
  34. package/dist/handlers/index.js +3 -0
  35. package/dist/handlers/session.js +113 -0
  36. package/dist/handlers/tasks.js +7 -0
  37. package/dist/handlers/tool-docs.js +7 -0
  38. package/dist/tools/deployment.js +13 -0
  39. package/docs/TOOLS.md +17 -3
  40. package/package.json +1 -1
  41. package/src/api-client/bodies-of-work.ts +194 -0
  42. package/src/api-client/chat.ts +50 -0
  43. package/src/api-client/connectors.ts +152 -0
  44. package/src/api-client/deployment.ts +313 -0
  45. package/src/api-client/file-checkouts.ts +115 -0
  46. package/src/api-client/git-issues.ts +88 -0
  47. package/src/api-client/index.ts +179 -13
  48. package/src/api-client/organizations.ts +185 -0
  49. package/src/api-client/progress.ts +94 -0
  50. package/src/api-client/requests.ts +54 -0
  51. package/src/api-client/sprints.ts +227 -0
  52. package/src/api-client/subtasks.ts +57 -0
  53. package/src/api-client.test.ts +16 -19
  54. package/src/api-client.ts +34 -0
  55. package/src/handlers/__test-setup__.ts +4 -0
  56. package/src/handlers/blockers.ts +9 -0
  57. package/src/handlers/chat.test.ts +185 -0
  58. package/src/handlers/chat.ts +69 -0
  59. package/src/handlers/deployment.ts +29 -0
  60. package/src/handlers/discovery.ts +1 -0
  61. package/src/handlers/index.ts +3 -0
  62. package/src/handlers/session.ts +138 -0
  63. package/src/handlers/tasks.ts +12 -0
  64. package/src/handlers/tool-docs.ts +8 -0
  65. package/src/tools/deployment.ts +13 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Progress API Methods
3
+ *
4
+ * Methods for progress tracking and activity feeds:
5
+ * - logProgress: Log a progress update for a project
6
+ * - getActivityFeed: Get combined activity feed
7
+ * - getActivityHistory: Get background activity history
8
+ * - getActivitySchedules: Get background activity schedules
9
+ */
10
+
11
+ import type { ApiResponse, RequestFn, ProxyFn } from './types.js';
12
+
13
+ export interface ProgressMethods {
14
+ logProgress(projectId: string, params: {
15
+ summary: string;
16
+ details?: string;
17
+ task_id?: string;
18
+ session_id?: string;
19
+ }): Promise<ApiResponse<{
20
+ success: boolean;
21
+ progress_id: string;
22
+ }>>;
23
+
24
+ getActivityFeed(projectId: string, params?: {
25
+ limit?: number;
26
+ since?: string;
27
+ types?: string[];
28
+ created_by?: string;
29
+ }): Promise<ApiResponse<{
30
+ activities: Array<{
31
+ type: string;
32
+ data: unknown;
33
+ timestamp: string;
34
+ }>;
35
+ }>>;
36
+
37
+ getActivityHistory(projectId: string, params?: {
38
+ activity_type?: string;
39
+ limit?: number;
40
+ }): Promise<ApiResponse<{
41
+ history: Array<{
42
+ id: string;
43
+ activity_type: string;
44
+ completed_at: string;
45
+ summary?: string;
46
+ }>;
47
+ latest_by_type: Record<string, unknown>;
48
+ count: number;
49
+ }>>;
50
+
51
+ getActivitySchedules(projectId: string, params?: {
52
+ limit?: number;
53
+ offset?: number;
54
+ }): Promise<ApiResponse<{
55
+ schedules: Array<{
56
+ id: string;
57
+ activity_type: string;
58
+ schedule_type: string;
59
+ next_run_at?: string;
60
+ enabled: boolean;
61
+ }>;
62
+ total_count: number;
63
+ has_more: boolean;
64
+ }>>;
65
+ }
66
+
67
+ export function createProgressMethods(request: RequestFn, proxy: ProxyFn): ProgressMethods {
68
+ return {
69
+ async logProgress(projectId, params) {
70
+ return request('POST', `/api/mcp/projects/${projectId}/progress`, params);
71
+ },
72
+
73
+ async getActivityFeed(projectId, params) {
74
+ return proxy('get_activity_feed', {
75
+ project_id: projectId,
76
+ ...params
77
+ });
78
+ },
79
+
80
+ async getActivityHistory(projectId, params) {
81
+ return proxy('get_activity_history', {
82
+ project_id: projectId,
83
+ ...params
84
+ });
85
+ },
86
+
87
+ async getActivitySchedules(projectId, params) {
88
+ return proxy('get_activity_schedules', {
89
+ project_id: projectId,
90
+ ...params
91
+ });
92
+ }
93
+ };
94
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Requests API Methods
3
+ *
4
+ * Methods for user request handling:
5
+ * - getPendingRequests: Get unacknowledged requests for a project
6
+ * - acknowledgeRequest: Mark a request as handled
7
+ * - answerQuestion: Answer a question from the user
8
+ */
9
+
10
+ import type { ApiResponse, ProxyFn } from './types.js';
11
+
12
+ export interface RequestsMethods {
13
+ getPendingRequests(projectId: string, sessionId?: string, limit?: number, offset?: number): Promise<ApiResponse<{
14
+ requests: Array<{
15
+ id: string;
16
+ request_type: string;
17
+ message: string;
18
+ created_at: string;
19
+ }>;
20
+ total_count: number;
21
+ has_more: boolean;
22
+ }>>;
23
+
24
+ acknowledgeRequest(requestId: string, sessionId?: string): Promise<ApiResponse<{
25
+ success: boolean;
26
+ }>>;
27
+
28
+ answerQuestion(requestId: string, answer: string, sessionId?: string): Promise<ApiResponse<{
29
+ success: boolean;
30
+ }>>;
31
+ }
32
+
33
+ export function createRequestsMethods(proxy: ProxyFn): RequestsMethods {
34
+ return {
35
+ async getPendingRequests(projectId, sessionId, limit, offset) {
36
+ return proxy('get_pending_requests', {
37
+ project_id: projectId,
38
+ ...(limit !== undefined && { limit }),
39
+ ...(offset !== undefined && { offset }),
40
+ }, sessionId ? { session_id: sessionId } : undefined);
41
+ },
42
+
43
+ async acknowledgeRequest(requestId, sessionId) {
44
+ return proxy('acknowledge_request', { request_id: requestId }, sessionId ? { session_id: sessionId } : undefined);
45
+ },
46
+
47
+ async answerQuestion(requestId, answer, sessionId) {
48
+ return proxy('answer_question', {
49
+ request_id: requestId,
50
+ answer
51
+ }, sessionId ? { session_id: sessionId } : undefined);
52
+ }
53
+ };
54
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Sprints API Methods
3
+ *
4
+ * Methods for sprint management:
5
+ * - createSprint: Create a new sprint
6
+ * - updateSprint: Update sprint details
7
+ * - getSprint: Get a sprint with tasks
8
+ * - getSprints: List sprints for a project
9
+ * - deleteSprint: Delete a sprint
10
+ * - startSprint: Activate a sprint
11
+ * - completeSprint: Complete a sprint
12
+ * - addTaskToSprint: Add a task to a sprint
13
+ * - removeTaskFromSprint: Remove a task from a sprint
14
+ * - getSprintBacklog: Get tasks available to add to a sprint
15
+ * - getSprintVelocity: Get velocity metrics for completed sprints
16
+ */
17
+
18
+ import type { ApiResponse, ProxyFn } from './types.js';
19
+
20
+ export interface SprintsMethods {
21
+ createSprint(projectId: string, params: {
22
+ title: string;
23
+ start_date: string;
24
+ end_date: string;
25
+ goal?: string;
26
+ auto_deploy_on_completion?: boolean;
27
+ deploy_environment?: string;
28
+ deploy_version_bump?: string;
29
+ }): Promise<ApiResponse<{
30
+ success: boolean;
31
+ sprint_id: string;
32
+ sprint_number: number;
33
+ }>>;
34
+
35
+ updateSprint(sprintId: string, updates: {
36
+ title?: string;
37
+ goal?: string;
38
+ start_date?: string;
39
+ end_date?: string;
40
+ auto_deploy_on_completion?: boolean;
41
+ deploy_environment?: string;
42
+ deploy_version_bump?: string;
43
+ }): Promise<ApiResponse<{
44
+ success: boolean;
45
+ }>>;
46
+
47
+ getSprint(sprintId: string, summaryOnly?: boolean): Promise<ApiResponse<{
48
+ id: string;
49
+ title: string;
50
+ goal?: string;
51
+ sprint_number: number;
52
+ sprint_status: string;
53
+ start_date: string;
54
+ end_date: string;
55
+ progress_percentage: number;
56
+ velocity_points: number;
57
+ committed_points: number;
58
+ pre_tasks?: unknown[];
59
+ core_tasks?: unknown[];
60
+ post_tasks?: unknown[];
61
+ total_tasks?: number;
62
+ task_counts?: {
63
+ pre: { total: number; completed: number };
64
+ core: { total: number; completed: number };
65
+ post: { total: number; completed: number };
66
+ total: number;
67
+ completed: number;
68
+ in_progress: number;
69
+ };
70
+ next_task?: { id: string; title: string; priority: number; phase: string } | null;
71
+ }>>;
72
+
73
+ getSprints(projectId: string, params?: {
74
+ status?: string;
75
+ limit?: number;
76
+ offset?: number;
77
+ }): Promise<ApiResponse<{
78
+ sprints: Array<{
79
+ id: string;
80
+ title: string;
81
+ sprint_number: number;
82
+ sprint_status: string;
83
+ start_date: string;
84
+ end_date: string;
85
+ progress_percentage: number;
86
+ velocity_points: number;
87
+ committed_points: number;
88
+ }>;
89
+ total_count: number;
90
+ has_more: boolean;
91
+ }>>;
92
+
93
+ deleteSprint(sprintId: string): Promise<ApiResponse<{
94
+ success: boolean;
95
+ }>>;
96
+
97
+ startSprint(sprintId: string): Promise<ApiResponse<{
98
+ success: boolean;
99
+ sprint_id: string;
100
+ status: string;
101
+ }>>;
102
+
103
+ completeSprint(sprintId: string, params?: {
104
+ retrospective_notes?: string;
105
+ skip_retrospective?: boolean;
106
+ }): Promise<ApiResponse<{
107
+ success: boolean;
108
+ sprint_id: string;
109
+ status: string;
110
+ }>>;
111
+
112
+ addTaskToSprint(sprintId: string, taskId: string, params?: {
113
+ story_points?: number;
114
+ phase?: string;
115
+ }): Promise<ApiResponse<{
116
+ success: boolean;
117
+ }>>;
118
+
119
+ removeTaskFromSprint(sprintId: string, taskId: string): Promise<ApiResponse<{
120
+ success: boolean;
121
+ }>>;
122
+
123
+ getSprintBacklog(projectId: string, sprintId?: string, params?: {
124
+ limit?: number;
125
+ offset?: number;
126
+ }): Promise<ApiResponse<{
127
+ tasks: Array<{
128
+ id: string;
129
+ title: string;
130
+ priority: number;
131
+ status: string;
132
+ estimated_minutes?: number;
133
+ }>;
134
+ total_count: number;
135
+ has_more: boolean;
136
+ }>>;
137
+
138
+ getSprintVelocity(projectId: string, limit?: number): Promise<ApiResponse<{
139
+ sprints: Array<{
140
+ sprint_id: string;
141
+ sprint_number: number;
142
+ title: string;
143
+ committed_points: number;
144
+ velocity_points: number;
145
+ completion_rate: number;
146
+ }>;
147
+ average_velocity: number;
148
+ total_sprints: number;
149
+ }>>;
150
+ }
151
+
152
+ export function createSprintsMethods(proxy: ProxyFn): SprintsMethods {
153
+ return {
154
+ async createSprint(projectId, params) {
155
+ return proxy('create_sprint', {
156
+ project_id: projectId,
157
+ ...params
158
+ });
159
+ },
160
+
161
+ async updateSprint(sprintId, updates) {
162
+ return proxy('update_sprint', {
163
+ sprint_id: sprintId,
164
+ ...updates
165
+ });
166
+ },
167
+
168
+ async getSprint(sprintId, summaryOnly) {
169
+ return proxy('get_sprint', {
170
+ sprint_id: sprintId,
171
+ summary_only: summaryOnly
172
+ });
173
+ },
174
+
175
+ async getSprints(projectId, params) {
176
+ return proxy('get_sprints', {
177
+ project_id: projectId,
178
+ ...params
179
+ });
180
+ },
181
+
182
+ async deleteSprint(sprintId) {
183
+ return proxy('delete_sprint', { sprint_id: sprintId });
184
+ },
185
+
186
+ async startSprint(sprintId) {
187
+ return proxy('start_sprint', { sprint_id: sprintId });
188
+ },
189
+
190
+ async completeSprint(sprintId, params) {
191
+ return proxy('complete_sprint', {
192
+ sprint_id: sprintId,
193
+ ...params
194
+ });
195
+ },
196
+
197
+ async addTaskToSprint(sprintId, taskId, params) {
198
+ return proxy('add_task_to_sprint', {
199
+ sprint_id: sprintId,
200
+ task_id: taskId,
201
+ ...params
202
+ });
203
+ },
204
+
205
+ async removeTaskFromSprint(sprintId, taskId) {
206
+ return proxy('remove_task_from_sprint', {
207
+ sprint_id: sprintId,
208
+ task_id: taskId
209
+ });
210
+ },
211
+
212
+ async getSprintBacklog(projectId, sprintId, params) {
213
+ return proxy('get_sprint_backlog', {
214
+ project_id: projectId,
215
+ sprint_id: sprintId,
216
+ ...params
217
+ });
218
+ },
219
+
220
+ async getSprintVelocity(projectId, limit) {
221
+ return proxy('get_sprint_velocity', {
222
+ project_id: projectId,
223
+ limit
224
+ });
225
+ }
226
+ };
227
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Subtasks API Methods
3
+ *
4
+ * Methods for subtask management:
5
+ * - addSubtask: Add a subtask to a parent task
6
+ * - getSubtasks: Get subtasks for a parent task
7
+ */
8
+
9
+ import type { ApiResponse, ProxyFn } from './types.js';
10
+
11
+ export interface SubtasksMethods {
12
+ addSubtask(parentTaskId: string, params: {
13
+ title: string;
14
+ description?: string;
15
+ priority?: number;
16
+ estimated_minutes?: number;
17
+ }, sessionId?: string): Promise<ApiResponse<{
18
+ success: boolean;
19
+ subtask_id: string;
20
+ parent_task_id: string;
21
+ }>>;
22
+
23
+ getSubtasks(parentTaskId: string, status?: string): Promise<ApiResponse<{
24
+ subtasks: Array<{
25
+ id: string;
26
+ title: string;
27
+ description?: string;
28
+ priority: number;
29
+ status: string;
30
+ progress_percentage?: number;
31
+ estimated_minutes?: number;
32
+ }>;
33
+ stats: {
34
+ total: number;
35
+ completed: number;
36
+ progress_percentage: number;
37
+ };
38
+ }>>;
39
+ }
40
+
41
+ export function createSubtasksMethods(proxy: ProxyFn): SubtasksMethods {
42
+ return {
43
+ async addSubtask(parentTaskId, params, sessionId) {
44
+ return proxy('add_subtask', {
45
+ parent_task_id: parentTaskId,
46
+ ...params
47
+ }, sessionId ? { session_id: sessionId } : undefined);
48
+ },
49
+
50
+ async getSubtasks(parentTaskId, status) {
51
+ return proxy('get_subtasks', {
52
+ parent_task_id: parentTaskId,
53
+ status
54
+ });
55
+ }
56
+ };
57
+ }
@@ -258,17 +258,16 @@ describe('VibescopeApiClient', () => {
258
258
  model: 'opus',
259
259
  });
260
260
 
261
- expect(mockFetch).toHaveBeenCalledWith(
262
- expect.stringContaining('/api/mcp/sessions/start'),
263
- expect.objectContaining({
264
- method: 'POST',
265
- body: JSON.stringify({
266
- project_id: 'proj-123',
267
- mode: 'lite',
268
- model: 'opus',
269
- }),
270
- })
271
- );
261
+ const [url, opts] = mockFetch.mock.calls[0] as [string, RequestInit];
262
+ const body = JSON.parse(opts.body as string);
263
+ expect(url).toContain('/api/mcp/sessions/start');
264
+ expect(opts.method).toBe('POST');
265
+ expect(body).toMatchObject({
266
+ project_id: 'proj-123',
267
+ mode: 'lite',
268
+ model: 'opus',
269
+ });
270
+ expect(body.instance_id).toBeDefined();
272
271
  });
273
272
 
274
273
  it('should support git_url param', async () => {
@@ -280,14 +279,12 @@ describe('VibescopeApiClient', () => {
280
279
  git_url: 'https://github.com/org/repo',
281
280
  });
282
281
 
283
- expect(mockFetch).toHaveBeenCalledWith(
284
- expect.any(String),
285
- expect.objectContaining({
286
- body: JSON.stringify({
287
- git_url: 'https://github.com/org/repo',
288
- }),
289
- })
290
- );
282
+ const [, opts] = mockFetch.mock.calls[0] as [string, RequestInit];
283
+ const body = JSON.parse(opts.body as string);
284
+ expect(body).toMatchObject({
285
+ git_url: 'https://github.com/org/repo',
286
+ });
287
+ expect(body.instance_id).toBeDefined();
291
288
  });
292
289
  });
293
290
 
package/src/api-client.ts CHANGED
@@ -2203,6 +2203,16 @@ export class VibescopeApiClient {
2203
2203
  return this.proxy('complete_deployment_requirement', { requirement_id: requirementId });
2204
2204
  }
2205
2205
 
2206
+ async reorderDeploymentRequirements(projectId: string, params: {
2207
+ stage: string;
2208
+ requirement_ids: string[];
2209
+ }): Promise<ApiResponse<{ success: boolean; reordered: number }>> {
2210
+ return this.proxy('reorder_deployment_requirements', {
2211
+ project_id: projectId,
2212
+ ...params,
2213
+ });
2214
+ }
2215
+
2206
2216
  async scheduleDeployment(projectId: string, params: {
2207
2217
  scheduled_at: string;
2208
2218
  schedule_type?: string;
@@ -2650,6 +2660,30 @@ export class VibescopeApiClient {
2650
2660
  agent_type: agentType
2651
2661
  });
2652
2662
  }
2663
+
2664
+ async sendProjectMessage(projectId: string, message: string, sessionId?: string): Promise<ApiResponse<{
2665
+ success: boolean;
2666
+ message_id: string;
2667
+ sent_at: string;
2668
+ }>> {
2669
+ return this.proxy('send_project_message', { project_id: projectId, message }, sessionId ? { session_id: sessionId, persona: null, instance_id: '' } : undefined);
2670
+ }
2671
+
2672
+ async getProjectMessages(projectId: string, limit?: number): Promise<ApiResponse<{
2673
+ messages: Array<{
2674
+ id: string;
2675
+ sender_type: string;
2676
+ sender_name: string | null;
2677
+ content: string;
2678
+ created_at: string;
2679
+ }>;
2680
+ count: number;
2681
+ }>> {
2682
+ return this.proxy('get_project_messages', {
2683
+ project_id: projectId,
2684
+ ...(limit !== undefined && { limit }),
2685
+ });
2686
+ }
2653
2687
  }
2654
2688
 
2655
2689
  // Singleton instance
@@ -190,6 +190,10 @@ export const mockApiClient = {
190
190
  testConnector: vi.fn(),
191
191
  getConnectorEvents: vi.fn(),
192
192
 
193
+ // Chat
194
+ sendProjectMessage: vi.fn(),
195
+ getProjectMessages: vi.fn(),
196
+
193
197
  // Proxy (generic)
194
198
  proxy: vi.fn(),
195
199
  };
@@ -17,6 +17,7 @@ import {
17
17
  VALID_BLOCKER_STATUSES,
18
18
  } from '../validators.js';
19
19
  import { getApiClient } from '../api-client.js';
20
+ import { autoPostActivity } from './chat.js';
20
21
 
21
22
  // Argument schemas for type-safe parsing
22
23
  const addBlockerSchema = {
@@ -59,6 +60,14 @@ export const addBlocker: Handler = async (args, ctx) => {
59
60
  return error(response.error || 'Failed to add blocker');
60
61
  }
61
62
 
63
+ // Auto-post blocker activity to project chat
64
+ const persona = ctx.session.currentPersona || 'Agent';
65
+ void autoPostActivity(
66
+ project_id,
67
+ `🚧 **${persona}** reported a blocker: ${description}`,
68
+ ctx.session.currentSessionId
69
+ );
70
+
62
71
  return success(response.data);
63
72
  };
64
73