@vibescope/mcp-server 0.2.0 → 0.2.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 (104) hide show
  1. package/README.md +60 -7
  2. package/dist/api-client.d.ts +251 -1
  3. package/dist/api-client.js +82 -3
  4. package/dist/handlers/blockers.js +9 -8
  5. package/dist/handlers/bodies-of-work.js +96 -63
  6. package/dist/handlers/connectors.d.ts +45 -0
  7. package/dist/handlers/connectors.js +183 -0
  8. package/dist/handlers/cost.d.ts +10 -0
  9. package/dist/handlers/cost.js +112 -50
  10. package/dist/handlers/decisions.js +32 -19
  11. package/dist/handlers/deployment.js +144 -122
  12. package/dist/handlers/discovery.d.ts +7 -0
  13. package/dist/handlers/discovery.js +96 -7
  14. package/dist/handlers/fallback.js +29 -23
  15. package/dist/handlers/file-checkouts.d.ts +20 -0
  16. package/dist/handlers/file-checkouts.js +133 -0
  17. package/dist/handlers/findings.d.ts +6 -0
  18. package/dist/handlers/findings.js +96 -40
  19. package/dist/handlers/git-issues.js +40 -36
  20. package/dist/handlers/ideas.js +49 -31
  21. package/dist/handlers/index.d.ts +3 -0
  22. package/dist/handlers/index.js +9 -0
  23. package/dist/handlers/milestones.js +39 -32
  24. package/dist/handlers/organizations.js +99 -91
  25. package/dist/handlers/progress.js +24 -13
  26. package/dist/handlers/project.js +68 -28
  27. package/dist/handlers/requests.js +18 -14
  28. package/dist/handlers/roles.d.ts +18 -0
  29. package/dist/handlers/roles.js +130 -0
  30. package/dist/handlers/session.js +58 -17
  31. package/dist/handlers/sprints.js +93 -81
  32. package/dist/handlers/tasks.d.ts +2 -0
  33. package/dist/handlers/tasks.js +189 -91
  34. package/dist/handlers/types.d.ts +64 -2
  35. package/dist/handlers/types.js +48 -1
  36. package/dist/handlers/validation.js +21 -17
  37. package/dist/index.js +7 -2716
  38. package/dist/token-tracking.d.ts +74 -0
  39. package/dist/token-tracking.js +122 -0
  40. package/dist/tools.js +685 -9
  41. package/dist/utils.d.ts +5 -0
  42. package/dist/utils.js +17 -0
  43. package/docs/TOOLS.md +2053 -0
  44. package/package.json +4 -1
  45. package/scripts/generate-docs.ts +212 -0
  46. package/src/api-client.test.ts +718 -0
  47. package/src/api-client.ts +320 -6
  48. package/src/handlers/__test-setup__.ts +16 -0
  49. package/src/handlers/blockers.test.ts +31 -19
  50. package/src/handlers/blockers.ts +9 -8
  51. package/src/handlers/bodies-of-work.test.ts +55 -32
  52. package/src/handlers/bodies-of-work.ts +115 -115
  53. package/src/handlers/connectors.test.ts +834 -0
  54. package/src/handlers/connectors.ts +229 -0
  55. package/src/handlers/cost.test.ts +34 -44
  56. package/src/handlers/cost.ts +136 -85
  57. package/src/handlers/decisions.test.ts +37 -27
  58. package/src/handlers/decisions.ts +35 -30
  59. package/src/handlers/deployment.ts +180 -208
  60. package/src/handlers/discovery.test.ts +4 -5
  61. package/src/handlers/discovery.ts +98 -8
  62. package/src/handlers/fallback.test.ts +26 -22
  63. package/src/handlers/fallback.ts +36 -33
  64. package/src/handlers/file-checkouts.test.ts +670 -0
  65. package/src/handlers/file-checkouts.ts +165 -0
  66. package/src/handlers/findings.test.ts +178 -19
  67. package/src/handlers/findings.ts +112 -74
  68. package/src/handlers/git-issues.test.ts +51 -43
  69. package/src/handlers/git-issues.ts +44 -84
  70. package/src/handlers/ideas.test.ts +28 -23
  71. package/src/handlers/ideas.ts +61 -59
  72. package/src/handlers/index.ts +9 -0
  73. package/src/handlers/milestones.test.ts +33 -28
  74. package/src/handlers/milestones.ts +52 -50
  75. package/src/handlers/organizations.test.ts +104 -83
  76. package/src/handlers/organizations.ts +117 -142
  77. package/src/handlers/progress.test.ts +20 -14
  78. package/src/handlers/progress.ts +26 -24
  79. package/src/handlers/project.test.ts +34 -27
  80. package/src/handlers/project.ts +95 -63
  81. package/src/handlers/requests.test.ts +27 -18
  82. package/src/handlers/requests.ts +21 -17
  83. package/src/handlers/roles.test.ts +303 -0
  84. package/src/handlers/roles.ts +208 -0
  85. package/src/handlers/session.test.ts +47 -0
  86. package/src/handlers/session.ts +71 -26
  87. package/src/handlers/sprints.test.ts +71 -50
  88. package/src/handlers/sprints.ts +113 -146
  89. package/src/handlers/tasks.test.ts +77 -15
  90. package/src/handlers/tasks.ts +231 -156
  91. package/src/handlers/tool-categories.test.ts +66 -0
  92. package/src/handlers/types.ts +81 -2
  93. package/src/handlers/validation.test.ts +78 -45
  94. package/src/handlers/validation.ts +23 -25
  95. package/src/index.ts +12 -2732
  96. package/src/token-tracking.test.ts +453 -0
  97. package/src/token-tracking.ts +164 -0
  98. package/src/tools.ts +685 -9
  99. package/src/utils.test.ts +2 -2
  100. package/src/utils.ts +17 -0
  101. package/dist/config/tool-categories.d.ts +0 -31
  102. package/dist/config/tool-categories.js +0 -253
  103. package/dist/knowledge.d.ts +0 -6
  104. package/dist/knowledge.js +0 -218
@@ -14,36 +14,87 @@
14
14
  * - get_sprint_backlog
15
15
  * - get_sprint_velocity
16
16
  */
17
- import { validateRequired, validateUUID, validateEnum } from '../validators.js';
17
+ import { parseArgs, uuidValidator, createEnumValidator } from '../validators.js';
18
18
  import { getApiClient } from '../api-client.js';
19
19
  const SPRINT_STATUSES = ['planning', 'active', 'in_review', 'retrospective', 'completed', 'cancelled'];
20
20
  const TASK_PHASES = ['pre', 'core', 'post'];
21
21
  const DEPLOY_ENVIRONMENTS = ['development', 'staging', 'production'];
22
22
  const VERSION_BUMPS = ['patch', 'minor', 'major'];
23
+ // ============================================================================
24
+ // Argument Schemas
25
+ // ============================================================================
26
+ const createSprintSchema = {
27
+ project_id: { type: 'string', required: true, validate: uuidValidator },
28
+ title: { type: 'string', required: true },
29
+ goal: { type: 'string' },
30
+ start_date: { type: 'string', required: true },
31
+ end_date: { type: 'string', required: true },
32
+ auto_deploy_on_completion: { type: 'boolean' },
33
+ deploy_environment: { type: 'string', validate: createEnumValidator(DEPLOY_ENVIRONMENTS) },
34
+ deploy_version_bump: { type: 'string', validate: createEnumValidator(VERSION_BUMPS) },
35
+ };
36
+ const updateSprintSchema = {
37
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
38
+ title: { type: 'string' },
39
+ goal: { type: 'string' },
40
+ start_date: { type: 'string' },
41
+ end_date: { type: 'string' },
42
+ auto_deploy_on_completion: { type: 'boolean' },
43
+ deploy_environment: { type: 'string', validate: createEnumValidator(DEPLOY_ENVIRONMENTS) },
44
+ deploy_version_bump: { type: 'string', validate: createEnumValidator(VERSION_BUMPS) },
45
+ };
46
+ const getSprintSchema = {
47
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
48
+ summary_only: { type: 'boolean', default: false },
49
+ };
50
+ const getSprintsSchema = {
51
+ project_id: { type: 'string', required: true, validate: uuidValidator },
52
+ status: { type: 'string', validate: createEnumValidator(SPRINT_STATUSES) },
53
+ limit: { type: 'number', default: 20 },
54
+ offset: { type: 'number', default: 0 },
55
+ };
56
+ const deleteSprintSchema = {
57
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
58
+ };
59
+ const startSprintSchema = {
60
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
61
+ };
62
+ const completeSprintSchema = {
63
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
64
+ retrospective_notes: { type: 'string' },
65
+ skip_retrospective: { type: 'boolean' },
66
+ };
67
+ const addTaskToSprintSchema = {
68
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
69
+ task_id: { type: 'string', required: true, validate: uuidValidator },
70
+ story_points: { type: 'number' },
71
+ phase: { type: 'string', validate: createEnumValidator(TASK_PHASES) },
72
+ };
73
+ const removeTaskFromSprintSchema = {
74
+ sprint_id: { type: 'string', required: true, validate: uuidValidator },
75
+ task_id: { type: 'string', required: true, validate: uuidValidator },
76
+ };
77
+ const getSprintBacklogSchema = {
78
+ project_id: { type: 'string', required: true, validate: uuidValidator },
79
+ sprint_id: { type: 'string', validate: uuidValidator },
80
+ };
81
+ const getSprintVelocitySchema = {
82
+ project_id: { type: 'string', required: true, validate: uuidValidator },
83
+ limit: { type: 'number', default: 10 },
84
+ };
23
85
  export const createSprint = async (args, ctx) => {
24
- const { project_id, title, goal, start_date, end_date, auto_deploy_on_completion, deploy_environment, deploy_version_bump, } = args;
25
- validateRequired(project_id, 'project_id');
26
- validateUUID(project_id, 'project_id');
27
- validateRequired(title, 'title');
28
- validateRequired(start_date, 'start_date');
29
- validateRequired(end_date, 'end_date');
30
- if (deploy_environment) {
31
- validateEnum(deploy_environment, DEPLOY_ENVIRONMENTS, 'deploy_environment');
32
- }
33
- if (deploy_version_bump) {
34
- validateEnum(deploy_version_bump, VERSION_BUMPS, 'deploy_version_bump');
35
- }
86
+ const { project_id, title, goal, start_date, end_date, auto_deploy_on_completion, deploy_environment, deploy_version_bump, } = parseArgs(args, createSprintSchema);
36
87
  // Validate date format and order
37
88
  const startDateObj = new Date(start_date);
38
89
  const endDateObj = new Date(end_date);
39
90
  if (isNaN(startDateObj.getTime())) {
40
- throw new Error('Invalid start_date format. Use YYYY-MM-DD');
91
+ return { result: { error: 'Invalid start_date format. Use YYYY-MM-DD' }, isError: true };
41
92
  }
42
93
  if (isNaN(endDateObj.getTime())) {
43
- throw new Error('Invalid end_date format. Use YYYY-MM-DD');
94
+ return { result: { error: 'Invalid end_date format. Use YYYY-MM-DD' }, isError: true };
44
95
  }
45
96
  if (endDateObj < startDateObj) {
46
- throw new Error('end_date must be on or after start_date');
97
+ return { result: { error: 'end_date must be on or after start_date' }, isError: true };
47
98
  }
48
99
  const { session } = ctx;
49
100
  const apiClient = getApiClient();
@@ -62,7 +113,7 @@ export const createSprint = async (args, ctx) => {
62
113
  instance_id: session.instanceId
63
114
  });
64
115
  if (!response.ok) {
65
- throw new Error(`Failed to create sprint: ${response.error}`);
116
+ return { result: { error: response.error || 'Failed to create sprint' }, isError: true };
66
117
  }
67
118
  return {
68
119
  result: {
@@ -78,26 +129,18 @@ export const createSprint = async (args, ctx) => {
78
129
  };
79
130
  };
80
131
  export const updateSprint = async (args, ctx) => {
81
- const { sprint_id, title, goal, start_date, end_date, auto_deploy_on_completion, deploy_environment, deploy_version_bump, } = args;
82
- validateRequired(sprint_id, 'sprint_id');
83
- validateUUID(sprint_id, 'sprint_id');
84
- if (deploy_environment) {
85
- validateEnum(deploy_environment, DEPLOY_ENVIRONMENTS, 'deploy_environment');
86
- }
87
- if (deploy_version_bump) {
88
- validateEnum(deploy_version_bump, VERSION_BUMPS, 'deploy_version_bump');
89
- }
132
+ const { sprint_id, title, goal, start_date, end_date, auto_deploy_on_completion, deploy_environment, deploy_version_bump, } = parseArgs(args, updateSprintSchema);
90
133
  // Validate dates if provided
91
134
  if (start_date) {
92
135
  const startDateObj = new Date(start_date);
93
136
  if (isNaN(startDateObj.getTime())) {
94
- throw new Error('Invalid start_date format. Use YYYY-MM-DD');
137
+ return { result: { error: 'Invalid start_date format. Use YYYY-MM-DD' }, isError: true };
95
138
  }
96
139
  }
97
140
  if (end_date) {
98
141
  const endDateObj = new Date(end_date);
99
142
  if (isNaN(endDateObj.getTime())) {
100
- throw new Error('Invalid end_date format. Use YYYY-MM-DD');
143
+ return { result: { error: 'Invalid end_date format. Use YYYY-MM-DD' }, isError: true };
101
144
  }
102
145
  }
103
146
  const apiClient = getApiClient();
@@ -112,69 +155,56 @@ export const updateSprint = async (args, ctx) => {
112
155
  deploy_version_bump,
113
156
  });
114
157
  if (!response.ok) {
115
- throw new Error(`Failed to update sprint: ${response.error}`);
158
+ return { result: { error: response.error || 'Failed to update sprint' }, isError: true };
116
159
  }
117
160
  return { result: { success: true, sprint_id } };
118
161
  };
119
162
  export const getSprint = async (args, ctx) => {
120
- const { sprint_id, summary_only = false } = args;
121
- validateRequired(sprint_id, 'sprint_id');
122
- validateUUID(sprint_id, 'sprint_id');
163
+ const { sprint_id, summary_only } = parseArgs(args, getSprintSchema);
123
164
  const apiClient = getApiClient();
124
165
  // Response type varies based on summary_only
125
166
  const response = await apiClient.proxy('get_sprint', { sprint_id, summary_only });
126
167
  if (!response.ok) {
127
- throw new Error(`Failed to get sprint: ${response.error}`);
168
+ return { result: { error: response.error || 'Failed to get sprint' }, isError: true };
128
169
  }
129
170
  return { result: response.data };
130
171
  };
131
172
  export const getSprints = async (args, ctx) => {
132
- const { project_id, status, limit = 20, offset = 0 } = args;
133
- validateRequired(project_id, 'project_id');
134
- validateUUID(project_id, 'project_id');
135
- if (status) {
136
- validateEnum(status, SPRINT_STATUSES, 'status');
137
- }
173
+ const { project_id, status, limit, offset } = parseArgs(args, getSprintsSchema);
138
174
  const apiClient = getApiClient();
139
175
  const response = await apiClient.proxy('get_sprints', {
140
176
  project_id,
141
177
  status,
142
- limit: Math.min(limit, 100),
178
+ limit: Math.min(limit ?? 20, 100),
143
179
  offset,
144
180
  });
145
181
  if (!response.ok) {
146
- throw new Error(`Failed to fetch sprints: ${response.error}`);
182
+ return { result: { error: response.error || 'Failed to fetch sprints' }, isError: true };
147
183
  }
148
184
  return { result: response.data };
149
185
  };
150
186
  export const deleteSprint = async (args, ctx) => {
151
- const { sprint_id } = args;
152
- validateRequired(sprint_id, 'sprint_id');
153
- validateUUID(sprint_id, 'sprint_id');
187
+ const { sprint_id } = parseArgs(args, deleteSprintSchema);
154
188
  const apiClient = getApiClient();
155
189
  const response = await apiClient.proxy('delete_sprint', {
156
190
  sprint_id
157
191
  });
158
192
  if (!response.ok) {
159
- throw new Error(`Failed to delete sprint: ${response.error}`);
193
+ return { result: { error: response.error || 'Failed to delete sprint' }, isError: true };
160
194
  }
161
195
  return { result: { success: true, message: 'Sprint deleted. Tasks are preserved.' } };
162
196
  };
163
197
  export const startSprint = async (args, ctx) => {
164
- const { sprint_id } = args;
165
- validateRequired(sprint_id, 'sprint_id');
166
- validateUUID(sprint_id, 'sprint_id');
198
+ const { sprint_id } = parseArgs(args, startSprintSchema);
167
199
  const apiClient = getApiClient();
168
200
  const response = await apiClient.proxy('start_sprint', { sprint_id });
169
201
  if (!response.ok) {
170
- throw new Error(`Failed to start sprint: ${response.error}`);
202
+ return { result: { error: response.error || 'Failed to start sprint' }, isError: true };
171
203
  }
172
204
  return { result: response.data };
173
205
  };
174
206
  export const completeSprint = async (args, ctx) => {
175
- const { sprint_id, retrospective_notes, skip_retrospective } = args;
176
- validateRequired(sprint_id, 'sprint_id');
177
- validateUUID(sprint_id, 'sprint_id');
207
+ const { sprint_id, retrospective_notes, skip_retrospective } = parseArgs(args, completeSprintSchema);
178
208
  const apiClient = getApiClient();
179
209
  const response = await apiClient.proxy('complete_sprint', {
180
210
  sprint_id,
@@ -182,21 +212,14 @@ export const completeSprint = async (args, ctx) => {
182
212
  skip_retrospective,
183
213
  });
184
214
  if (!response.ok) {
185
- throw new Error(`Failed to complete sprint: ${response.error}`);
215
+ return { result: { error: response.error || 'Failed to complete sprint' }, isError: true };
186
216
  }
187
217
  return { result: response.data };
188
218
  };
189
219
  export const addTaskToSprint = async (args, ctx) => {
190
- const { sprint_id, task_id, story_points, phase } = args;
191
- validateRequired(sprint_id, 'sprint_id');
192
- validateUUID(sprint_id, 'sprint_id');
193
- validateRequired(task_id, 'task_id');
194
- validateUUID(task_id, 'task_id');
195
- if (phase) {
196
- validateEnum(phase, TASK_PHASES, 'phase');
197
- }
220
+ const { sprint_id, task_id, story_points, phase } = parseArgs(args, addTaskToSprintSchema);
198
221
  if (story_points !== undefined && (story_points < 0 || !Number.isInteger(story_points))) {
199
- throw new Error('story_points must be a non-negative integer');
222
+ return { result: { error: 'story_points must be a non-negative integer' }, isError: true };
200
223
  }
201
224
  const apiClient = getApiClient();
202
225
  const response = await apiClient.proxy('add_task_to_sprint', {
@@ -206,54 +229,43 @@ export const addTaskToSprint = async (args, ctx) => {
206
229
  phase: phase || 'core',
207
230
  });
208
231
  if (!response.ok) {
209
- throw new Error(`Failed to add task to sprint: ${response.error}`);
232
+ return { result: { error: response.error || 'Failed to add task to sprint' }, isError: true };
210
233
  }
211
234
  return { result: response.data };
212
235
  };
213
236
  export const removeTaskFromSprint = async (args, ctx) => {
214
- const { sprint_id, task_id } = args;
215
- validateRequired(sprint_id, 'sprint_id');
216
- validateUUID(sprint_id, 'sprint_id');
217
- validateRequired(task_id, 'task_id');
218
- validateUUID(task_id, 'task_id');
237
+ const { sprint_id, task_id } = parseArgs(args, removeTaskFromSprintSchema);
219
238
  const apiClient = getApiClient();
220
239
  const response = await apiClient.proxy('remove_task_from_sprint', {
221
240
  sprint_id,
222
241
  task_id,
223
242
  });
224
243
  if (!response.ok) {
225
- throw new Error(`Failed to remove task from sprint: ${response.error}`);
244
+ return { result: { error: response.error || 'Failed to remove task from sprint' }, isError: true };
226
245
  }
227
246
  return { result: response.data };
228
247
  };
229
248
  export const getSprintBacklog = async (args, ctx) => {
230
- const { project_id, sprint_id } = args;
231
- validateRequired(project_id, 'project_id');
232
- validateUUID(project_id, 'project_id');
233
- if (sprint_id) {
234
- validateUUID(sprint_id, 'sprint_id');
235
- }
249
+ const { project_id, sprint_id } = parseArgs(args, getSprintBacklogSchema);
236
250
  const apiClient = getApiClient();
237
251
  const response = await apiClient.proxy('get_sprint_backlog', {
238
252
  project_id,
239
253
  sprint_id,
240
254
  });
241
255
  if (!response.ok) {
242
- throw new Error(`Failed to get sprint backlog: ${response.error}`);
256
+ return { result: { error: response.error || 'Failed to get sprint backlog' }, isError: true };
243
257
  }
244
258
  return { result: response.data };
245
259
  };
246
260
  export const getSprintVelocity = async (args, ctx) => {
247
- const { project_id, limit = 10 } = args;
248
- validateRequired(project_id, 'project_id');
249
- validateUUID(project_id, 'project_id');
261
+ const { project_id, limit } = parseArgs(args, getSprintVelocitySchema);
250
262
  const apiClient = getApiClient();
251
263
  const response = await apiClient.proxy('get_sprint_velocity', {
252
264
  project_id,
253
- limit: Math.min(limit, 50),
265
+ limit: Math.min(limit ?? 10, 50),
254
266
  });
255
267
  if (!response.ok) {
256
- throw new Error(`Failed to get sprint velocity: ${response.error}`);
268
+ return { result: { error: response.error || 'Failed to get sprint velocity' }, isError: true };
257
269
  }
258
270
  return { result: response.data };
259
271
  };
@@ -42,6 +42,8 @@ export declare const batchUpdateTasks: Handler;
42
42
  export declare const batchCompleteTasks: Handler;
43
43
  export declare const addSubtask: Handler;
44
44
  export declare const getSubtasks: Handler;
45
+ export declare const getStaleWorktrees: Handler;
46
+ export declare const clearWorktreePath: Handler;
45
47
  /**
46
48
  * Task handlers registry
47
49
  */