@vibescope/mcp-server 0.1.0 → 0.2.1

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 (76) hide show
  1. package/README.md +1 -1
  2. package/dist/api-client.d.ts +120 -2
  3. package/dist/api-client.js +51 -5
  4. package/dist/handlers/bodies-of-work.js +84 -50
  5. package/dist/handlers/cost.js +62 -54
  6. package/dist/handlers/decisions.js +29 -16
  7. package/dist/handlers/deployment.js +114 -107
  8. package/dist/handlers/discovery.d.ts +3 -0
  9. package/dist/handlers/discovery.js +55 -657
  10. package/dist/handlers/fallback.js +42 -28
  11. package/dist/handlers/file-checkouts.d.ts +18 -0
  12. package/dist/handlers/file-checkouts.js +101 -0
  13. package/dist/handlers/findings.d.ts +14 -1
  14. package/dist/handlers/findings.js +104 -28
  15. package/dist/handlers/git-issues.js +36 -32
  16. package/dist/handlers/ideas.js +44 -26
  17. package/dist/handlers/index.d.ts +2 -0
  18. package/dist/handlers/index.js +6 -0
  19. package/dist/handlers/milestones.js +34 -27
  20. package/dist/handlers/organizations.js +86 -78
  21. package/dist/handlers/progress.js +22 -11
  22. package/dist/handlers/project.js +62 -22
  23. package/dist/handlers/requests.js +15 -11
  24. package/dist/handlers/roles.d.ts +18 -0
  25. package/dist/handlers/roles.js +130 -0
  26. package/dist/handlers/session.js +52 -15
  27. package/dist/handlers/sprints.js +78 -65
  28. package/dist/handlers/tasks.js +135 -74
  29. package/dist/handlers/tool-docs.d.ts +4 -3
  30. package/dist/handlers/tool-docs.js +252 -5
  31. package/dist/handlers/validation.js +30 -14
  32. package/dist/index.js +25 -7
  33. package/dist/tools.js +417 -4
  34. package/package.json +1 -1
  35. package/src/api-client.ts +161 -8
  36. package/src/handlers/__test-setup__.ts +12 -0
  37. package/src/handlers/bodies-of-work.ts +127 -111
  38. package/src/handlers/cost.test.ts +34 -44
  39. package/src/handlers/cost.ts +77 -92
  40. package/src/handlers/decisions.test.ts +3 -2
  41. package/src/handlers/decisions.ts +32 -27
  42. package/src/handlers/deployment.ts +144 -190
  43. package/src/handlers/discovery.test.ts +4 -5
  44. package/src/handlers/discovery.ts +60 -746
  45. package/src/handlers/fallback.test.ts +78 -0
  46. package/src/handlers/fallback.ts +51 -38
  47. package/src/handlers/file-checkouts.test.ts +477 -0
  48. package/src/handlers/file-checkouts.ts +127 -0
  49. package/src/handlers/findings.test.ts +274 -2
  50. package/src/handlers/findings.ts +123 -57
  51. package/src/handlers/git-issues.ts +40 -80
  52. package/src/handlers/ideas.ts +56 -54
  53. package/src/handlers/index.ts +6 -0
  54. package/src/handlers/milestones.test.ts +1 -1
  55. package/src/handlers/milestones.ts +47 -45
  56. package/src/handlers/organizations.ts +104 -129
  57. package/src/handlers/progress.ts +24 -22
  58. package/src/handlers/project.ts +89 -57
  59. package/src/handlers/requests.ts +18 -14
  60. package/src/handlers/roles.test.ts +303 -0
  61. package/src/handlers/roles.ts +208 -0
  62. package/src/handlers/session.test.ts +37 -2
  63. package/src/handlers/session.ts +64 -21
  64. package/src/handlers/sprints.ts +114 -134
  65. package/src/handlers/tasks.test.ts +61 -0
  66. package/src/handlers/tasks.ts +170 -139
  67. package/src/handlers/tool-docs.ts +1024 -0
  68. package/src/handlers/validation.test.ts +53 -1
  69. package/src/handlers/validation.ts +32 -21
  70. package/src/index.ts +25 -7
  71. package/src/tools.ts +417 -4
  72. package/dist/config/tool-categories.d.ts +0 -31
  73. package/dist/config/tool-categories.js +0 -253
  74. package/dist/knowledge.d.ts +0 -6
  75. package/dist/knowledge.js +0 -218
  76. package/src/knowledge.ts +0 -230
@@ -17,34 +17,132 @@
17
17
  import type { Handler, HandlerRegistry } from './types.js';
18
18
  import {
19
19
  ValidationError,
20
- validateRequired,
21
- validateUUID,
22
- validateEnvironment,
20
+ parseArgs,
21
+ uuidValidator,
22
+ createEnumValidator,
23
23
  } from '../validators.js';
24
24
  import { getApiClient } from '../api-client.js';
25
25
 
26
- export const requestDeployment: Handler = async (args, ctx) => {
27
- const { project_id, environment = 'production', version_bump = 'patch', notes, git_ref } = args as {
28
- project_id: string;
29
- environment?: string;
30
- version_bump?: 'patch' | 'minor' | 'major';
31
- notes?: string;
32
- git_ref?: string;
33
- };
26
+ const ENVIRONMENTS = ['development', 'staging', 'production'] as const;
27
+ const VERSION_BUMPS = ['patch', 'minor', 'major'] as const;
28
+ const REQUIREMENT_TYPES = ['migration', 'env_var', 'config', 'manual', 'breaking_change', 'agent_task'] as const;
29
+ const REQUIREMENT_STAGES = ['preparation', 'deployment', 'verification'] as const;
30
+ const REQUIREMENT_STATUSES = ['pending', 'completed', 'converted_to_task', 'all'] as const;
31
+ const SCHEDULE_TYPES = ['once', 'daily', 'weekly', 'monthly'] as const;
34
32
 
35
- const { session } = ctx;
33
+ type Environment = typeof ENVIRONMENTS[number];
34
+ type VersionBump = typeof VERSION_BUMPS[number];
35
+ type RequirementType = typeof REQUIREMENT_TYPES[number];
36
+ type RequirementStage = typeof REQUIREMENT_STAGES[number];
37
+ type RequirementStatus = typeof REQUIREMENT_STATUSES[number];
38
+ type ScheduleType = typeof SCHEDULE_TYPES[number];
39
+
40
+ // ============================================================================
41
+ // Argument Schemas
42
+ // ============================================================================
36
43
 
37
- validateRequired(project_id, 'project_id');
38
- validateUUID(project_id, 'project_id');
39
- validateEnvironment(environment);
44
+ const requestDeploymentSchema = {
45
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
46
+ environment: { type: 'string' as const, default: 'production', validate: createEnumValidator(ENVIRONMENTS) },
47
+ version_bump: { type: 'string' as const, default: 'patch', validate: createEnumValidator(VERSION_BUMPS) },
48
+ notes: { type: 'string' as const },
49
+ git_ref: { type: 'string' as const },
50
+ };
40
51
 
41
- if (version_bump && !['patch', 'minor', 'major'].includes(version_bump)) {
42
- throw new ValidationError('Invalid version_bump value', {
43
- field: 'version_bump',
44
- validValues: ['patch', 'minor', 'major'],
45
- hint: 'Must be one of: patch, minor, major',
46
- });
47
- }
52
+ const claimDeploymentValidationSchema = {
53
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
54
+ };
55
+
56
+ const reportValidationSchema = {
57
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
58
+ build_passed: { type: 'boolean' as const, required: true as const },
59
+ tests_passed: { type: 'boolean' as const },
60
+ error_message: { type: 'string' as const },
61
+ };
62
+
63
+ const checkDeploymentStatusSchema = {
64
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
65
+ };
66
+
67
+ const startDeploymentSchema = {
68
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
69
+ };
70
+
71
+ const completeDeploymentSchema = {
72
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
73
+ success: { type: 'boolean' as const, required: true as const },
74
+ summary: { type: 'string' as const },
75
+ };
76
+
77
+ const cancelDeploymentSchema = {
78
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
79
+ reason: { type: 'string' as const },
80
+ };
81
+
82
+ const addDeploymentRequirementSchema = {
83
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
84
+ type: { type: 'string' as const, required: true as const, validate: createEnumValidator(REQUIREMENT_TYPES) },
85
+ title: { type: 'string' as const, required: true as const },
86
+ description: { type: 'string' as const },
87
+ file_path: { type: 'string' as const },
88
+ stage: { type: 'string' as const, default: 'preparation', validate: createEnumValidator(REQUIREMENT_STAGES) },
89
+ blocking: { type: 'boolean' as const, default: false },
90
+ recurring: { type: 'boolean' as const, default: false },
91
+ };
92
+
93
+ const completeDeploymentRequirementSchema = {
94
+ requirement_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
95
+ };
96
+
97
+ const getDeploymentRequirementsSchema = {
98
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
99
+ status: { type: 'string' as const, default: 'pending', validate: createEnumValidator(REQUIREMENT_STATUSES) },
100
+ stage: { type: 'string' as const, validate: createEnumValidator([...REQUIREMENT_STAGES, 'all'] as const) },
101
+ };
102
+
103
+ const scheduleDeploymentSchema = {
104
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
105
+ environment: { type: 'string' as const, default: 'production', validate: createEnumValidator(ENVIRONMENTS) },
106
+ version_bump: { type: 'string' as const, default: 'patch', validate: createEnumValidator(VERSION_BUMPS) },
107
+ schedule_type: { type: 'string' as const, default: 'once', validate: createEnumValidator(SCHEDULE_TYPES) },
108
+ scheduled_at: { type: 'string' as const, required: true as const },
109
+ auto_trigger: { type: 'boolean' as const, default: true },
110
+ notes: { type: 'string' as const },
111
+ git_ref: { type: 'string' as const },
112
+ };
113
+
114
+ const getScheduledDeploymentsSchema = {
115
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
116
+ include_disabled: { type: 'boolean' as const, default: false },
117
+ };
118
+
119
+ const updateScheduledDeploymentSchema = {
120
+ schedule_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
121
+ environment: { type: 'string' as const, validate: createEnumValidator(ENVIRONMENTS) },
122
+ version_bump: { type: 'string' as const, validate: createEnumValidator(VERSION_BUMPS) },
123
+ schedule_type: { type: 'string' as const, validate: createEnumValidator(SCHEDULE_TYPES) },
124
+ scheduled_at: { type: 'string' as const },
125
+ auto_trigger: { type: 'boolean' as const },
126
+ enabled: { type: 'boolean' as const },
127
+ notes: { type: 'string' as const },
128
+ git_ref: { type: 'string' as const },
129
+ };
130
+
131
+ const deleteScheduledDeploymentSchema = {
132
+ schedule_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
133
+ };
134
+
135
+ const triggerScheduledDeploymentSchema = {
136
+ schedule_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
137
+ };
138
+
139
+ const checkDueDeploymentsSchema = {
140
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
141
+ };
142
+
143
+ export const requestDeployment: Handler = async (args, ctx) => {
144
+ const { project_id, environment, version_bump, notes, git_ref } = parseArgs(args, requestDeploymentSchema);
145
+ const { session } = ctx;
48
146
 
49
147
  const apiClient = getApiClient();
50
148
  const response = await apiClient.requestDeployment(project_id, {
@@ -62,12 +160,9 @@ export const requestDeployment: Handler = async (args, ctx) => {
62
160
  };
63
161
 
64
162
  export const claimDeploymentValidation: Handler = async (args, ctx) => {
65
- const { project_id } = args as { project_id: string };
163
+ const { project_id } = parseArgs(args, claimDeploymentValidationSchema);
66
164
  const { session } = ctx;
67
165
 
68
- validateRequired(project_id, 'project_id');
69
- validateUUID(project_id, 'project_id');
70
-
71
166
  const apiClient = getApiClient();
72
167
  const response = await apiClient.claimDeploymentValidation(
73
168
  project_id,
@@ -82,24 +177,9 @@ export const claimDeploymentValidation: Handler = async (args, ctx) => {
82
177
  };
83
178
 
84
179
  export const reportValidation: Handler = async (args, ctx) => {
85
- const { project_id, build_passed, tests_passed, error_message } = args as {
86
- project_id: string;
87
- build_passed: boolean;
88
- tests_passed?: boolean;
89
- error_message?: string;
90
- };
91
-
180
+ const { project_id, build_passed, tests_passed, error_message } = parseArgs(args, reportValidationSchema);
92
181
  const { session } = ctx;
93
182
 
94
- validateRequired(project_id, 'project_id');
95
- validateUUID(project_id, 'project_id');
96
- if (build_passed === undefined) {
97
- throw new ValidationError('build_passed is required', {
98
- field: 'build_passed',
99
- hint: 'Set to true if the build succeeded, false otherwise',
100
- });
101
- }
102
-
103
183
  const apiClient = getApiClient();
104
184
  const response = await apiClient.reportValidation(project_id, {
105
185
  build_passed,
@@ -115,10 +195,7 @@ export const reportValidation: Handler = async (args, ctx) => {
115
195
  };
116
196
 
117
197
  export const checkDeploymentStatus: Handler = async (args, ctx) => {
118
- const { project_id } = args as { project_id: string };
119
-
120
- validateRequired(project_id, 'project_id');
121
- validateUUID(project_id, 'project_id');
198
+ const { project_id } = parseArgs(args, checkDeploymentStatusSchema);
122
199
 
123
200
  const apiClient = getApiClient();
124
201
  const response = await apiClient.checkDeploymentStatus(project_id);
@@ -131,12 +208,9 @@ export const checkDeploymentStatus: Handler = async (args, ctx) => {
131
208
  };
132
209
 
133
210
  export const startDeployment: Handler = async (args, ctx) => {
134
- const { project_id } = args as { project_id: string };
211
+ const { project_id } = parseArgs(args, startDeploymentSchema);
135
212
  const { session } = ctx;
136
213
 
137
- validateRequired(project_id, 'project_id');
138
- validateUUID(project_id, 'project_id');
139
-
140
214
  const apiClient = getApiClient();
141
215
  const response = await apiClient.startDeployment(
142
216
  project_id,
@@ -151,23 +225,9 @@ export const startDeployment: Handler = async (args, ctx) => {
151
225
  };
152
226
 
153
227
  export const completeDeployment: Handler = async (args, ctx) => {
154
- const { project_id, success, summary } = args as {
155
- project_id: string;
156
- success: boolean;
157
- summary?: string;
158
- };
159
-
228
+ const { project_id, success, summary } = parseArgs(args, completeDeploymentSchema);
160
229
  const { session } = ctx;
161
230
 
162
- validateRequired(project_id, 'project_id');
163
- validateUUID(project_id, 'project_id');
164
- if (success === undefined) {
165
- throw new ValidationError('success is required', {
166
- field: 'success',
167
- hint: 'Set to true if deployment succeeded, false otherwise',
168
- });
169
- }
170
-
171
231
  const apiClient = getApiClient();
172
232
  const response = await apiClient.completeDeployment(project_id, {
173
233
  success,
@@ -182,10 +242,7 @@ export const completeDeployment: Handler = async (args, ctx) => {
182
242
  };
183
243
 
184
244
  export const cancelDeployment: Handler = async (args, ctx) => {
185
- const { project_id, reason } = args as { project_id: string; reason?: string };
186
-
187
- validateRequired(project_id, 'project_id');
188
- validateUUID(project_id, 'project_id');
245
+ const { project_id, reason } = parseArgs(args, cancelDeploymentSchema);
189
246
 
190
247
  const apiClient = getApiClient();
191
248
  const response = await apiClient.cancelDeployment(project_id, reason);
@@ -198,30 +255,7 @@ export const cancelDeployment: Handler = async (args, ctx) => {
198
255
  };
199
256
 
200
257
  export const addDeploymentRequirement: Handler = async (args, ctx) => {
201
- const { project_id, type, title, description, file_path, stage = 'preparation', blocking = false } = args as {
202
- project_id: string;
203
- type: string;
204
- title: string;
205
- description?: string;
206
- file_path?: string;
207
- stage?: string;
208
- blocking?: boolean;
209
- };
210
-
211
- validateRequired(project_id, 'project_id');
212
- validateUUID(project_id, 'project_id');
213
- validateRequired(type, 'type');
214
- validateRequired(title, 'title');
215
-
216
- const validTypes = ['migration', 'env_var', 'config', 'manual', 'breaking_change', 'agent_task'];
217
- if (!validTypes.includes(type)) {
218
- throw new ValidationError(`type must be one of: ${validTypes.join(', ')}`);
219
- }
220
-
221
- const validStages = ['preparation', 'deployment', 'verification'];
222
- if (!validStages.includes(stage)) {
223
- throw new ValidationError(`stage must be one of: ${validStages.join(', ')}`);
224
- }
258
+ const { project_id, type, title, description, file_path, stage, blocking, recurring } = parseArgs(args, addDeploymentRequirementSchema);
225
259
 
226
260
  const apiClient = getApiClient();
227
261
  const response = await apiClient.addDeploymentRequirement(project_id, {
@@ -230,7 +264,8 @@ export const addDeploymentRequirement: Handler = async (args, ctx) => {
230
264
  description,
231
265
  file_path,
232
266
  stage: stage as 'preparation' | 'deployment' | 'verification',
233
- blocking
267
+ blocking,
268
+ recurring
234
269
  });
235
270
 
236
271
  if (!response.ok) {
@@ -241,10 +276,7 @@ export const addDeploymentRequirement: Handler = async (args, ctx) => {
241
276
  };
242
277
 
243
278
  export const completeDeploymentRequirement: Handler = async (args, ctx) => {
244
- const { requirement_id } = args as { requirement_id: string };
245
-
246
- validateRequired(requirement_id, 'requirement_id');
247
- validateUUID(requirement_id, 'requirement_id');
279
+ const { requirement_id } = parseArgs(args, completeDeploymentRequirementSchema);
248
280
 
249
281
  const apiClient = getApiClient();
250
282
  const response = await apiClient.completeDeploymentRequirement(requirement_id);
@@ -257,14 +289,7 @@ export const completeDeploymentRequirement: Handler = async (args, ctx) => {
257
289
  };
258
290
 
259
291
  export const getDeploymentRequirements: Handler = async (args, ctx) => {
260
- const { project_id, status = 'pending', stage } = args as {
261
- project_id: string;
262
- status?: string;
263
- stage?: string;
264
- };
265
-
266
- validateRequired(project_id, 'project_id');
267
- validateUUID(project_id, 'project_id');
292
+ const { project_id, status, stage } = parseArgs(args, getDeploymentRequirementsSchema);
268
293
 
269
294
  const apiClient = getApiClient();
270
295
  const response = await apiClient.getDeploymentRequirements(project_id, {
@@ -286,42 +311,14 @@ export const getDeploymentRequirements: Handler = async (args, ctx) => {
286
311
  export const scheduleDeployment: Handler = async (args, ctx) => {
287
312
  const {
288
313
  project_id,
289
- environment = 'production',
290
- version_bump = 'patch',
291
- schedule_type = 'once',
314
+ environment,
315
+ version_bump,
316
+ schedule_type,
292
317
  scheduled_at,
293
- auto_trigger = true,
318
+ auto_trigger,
294
319
  notes,
295
320
  git_ref,
296
- } = args as {
297
- project_id: string;
298
- environment?: string;
299
- version_bump?: string;
300
- schedule_type?: string;
301
- scheduled_at: string;
302
- auto_trigger?: boolean;
303
- notes?: string;
304
- git_ref?: string;
305
- };
306
-
307
- validateRequired(project_id, 'project_id');
308
- validateUUID(project_id, 'project_id');
309
- validateRequired(scheduled_at, 'scheduled_at');
310
- validateEnvironment(environment);
311
-
312
- if (!['patch', 'minor', 'major'].includes(version_bump)) {
313
- throw new ValidationError('Invalid version_bump value', {
314
- field: 'version_bump',
315
- validValues: ['patch', 'minor', 'major'],
316
- });
317
- }
318
-
319
- if (!['once', 'daily', 'weekly', 'monthly'].includes(schedule_type)) {
320
- throw new ValidationError('Invalid schedule_type value', {
321
- field: 'schedule_type',
322
- validValues: ['once', 'daily', 'weekly', 'monthly'],
323
- });
324
- }
321
+ } = parseArgs(args, scheduleDeploymentSchema);
325
322
 
326
323
  // Parse and validate scheduled_at
327
324
  const scheduledDate = new Date(scheduled_at);
@@ -357,13 +354,7 @@ export const scheduleDeployment: Handler = async (args, ctx) => {
357
354
  };
358
355
 
359
356
  export const getScheduledDeployments: Handler = async (args, ctx) => {
360
- const { project_id, include_disabled = false } = args as {
361
- project_id: string;
362
- include_disabled?: boolean;
363
- };
364
-
365
- validateRequired(project_id, 'project_id');
366
- validateUUID(project_id, 'project_id');
357
+ const { project_id, include_disabled } = parseArgs(args, getScheduledDeploymentsSchema);
367
358
 
368
359
  const apiClient = getApiClient();
369
360
  const response = await apiClient.getScheduledDeployments(project_id, include_disabled);
@@ -386,41 +377,13 @@ export const updateScheduledDeployment: Handler = async (args, ctx) => {
386
377
  enabled,
387
378
  notes,
388
379
  git_ref,
389
- } = args as {
390
- schedule_id: string;
391
- environment?: string;
392
- version_bump?: string;
393
- schedule_type?: string;
394
- scheduled_at?: string;
395
- auto_trigger?: boolean;
396
- enabled?: boolean;
397
- notes?: string;
398
- git_ref?: string;
399
- };
400
-
401
- validateRequired(schedule_id, 'schedule_id');
402
- validateUUID(schedule_id, 'schedule_id');
380
+ } = parseArgs(args, updateScheduledDeploymentSchema);
403
381
 
404
382
  const updates: Record<string, unknown> = {};
405
383
 
406
- if (environment !== undefined) {
407
- validateEnvironment(environment);
408
- updates.environment = environment;
409
- }
410
-
411
- if (version_bump !== undefined) {
412
- if (!['patch', 'minor', 'major'].includes(version_bump)) {
413
- throw new ValidationError('Invalid version_bump value');
414
- }
415
- updates.version_bump = version_bump;
416
- }
417
-
418
- if (schedule_type !== undefined) {
419
- if (!['once', 'daily', 'weekly', 'monthly'].includes(schedule_type)) {
420
- throw new ValidationError('Invalid schedule_type value');
421
- }
422
- updates.schedule_type = schedule_type;
423
- }
384
+ if (environment !== undefined) updates.environment = environment;
385
+ if (version_bump !== undefined) updates.version_bump = version_bump;
386
+ if (schedule_type !== undefined) updates.schedule_type = schedule_type;
424
387
 
425
388
  if (scheduled_at !== undefined) {
426
389
  const scheduledDate = new Date(scheduled_at);
@@ -459,10 +422,7 @@ export const updateScheduledDeployment: Handler = async (args, ctx) => {
459
422
  };
460
423
 
461
424
  export const deleteScheduledDeployment: Handler = async (args, ctx) => {
462
- const { schedule_id } = args as { schedule_id: string };
463
-
464
- validateRequired(schedule_id, 'schedule_id');
465
- validateUUID(schedule_id, 'schedule_id');
425
+ const { schedule_id } = parseArgs(args, deleteScheduledDeploymentSchema);
466
426
 
467
427
  const apiClient = getApiClient();
468
428
  const response = await apiClient.deleteScheduledDeployment(schedule_id);
@@ -475,12 +435,9 @@ export const deleteScheduledDeployment: Handler = async (args, ctx) => {
475
435
  };
476
436
 
477
437
  export const triggerScheduledDeployment: Handler = async (args, ctx) => {
478
- const { schedule_id } = args as { schedule_id: string };
438
+ const { schedule_id } = parseArgs(args, triggerScheduledDeploymentSchema);
479
439
  const { session } = ctx;
480
440
 
481
- validateRequired(schedule_id, 'schedule_id');
482
- validateUUID(schedule_id, 'schedule_id');
483
-
484
441
  const apiClient = getApiClient();
485
442
  const response = await apiClient.triggerScheduledDeployment(
486
443
  schedule_id,
@@ -495,10 +452,7 @@ export const triggerScheduledDeployment: Handler = async (args, ctx) => {
495
452
  };
496
453
 
497
454
  export const checkDueDeployments: Handler = async (args, ctx) => {
498
- const { project_id } = args as { project_id: string };
499
-
500
- validateRequired(project_id, 'project_id');
501
- validateUUID(project_id, 'project_id');
455
+ const { project_id } = parseArgs(args, checkDueDeploymentsSchema);
502
456
 
503
457
  const apiClient = getApiClient();
504
458
  const response = await apiClient.checkDueDeployments(project_id);
@@ -1,6 +1,7 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { discoverTools, getToolInfo } from './discovery.js';
3
3
  import { createMockContext } from './__test-utils__.js';
4
+ import { ValidationError } from '../validators.js';
4
5
 
5
6
  // ============================================================================
6
7
  // discoverTools Tests
@@ -113,13 +114,11 @@ describe('discoverTools', () => {
113
114
  // ============================================================================
114
115
 
115
116
  describe('getToolInfo', () => {
116
- it('should return error for missing tool_name', async () => {
117
+ it('should throw ValidationError for missing tool_name', async () => {
117
118
  const ctx = createMockContext();
118
119
 
119
- const result = await getToolInfo({}, ctx);
120
- const res = result.result as { error: string };
121
-
122
- expect(res.error).toBe('tool_name is required');
120
+ await expect(getToolInfo({}, ctx)).rejects.toThrow(ValidationError);
121
+ await expect(getToolInfo({}, ctx)).rejects.toThrow('Missing required field: tool_name');
123
122
  });
124
123
 
125
124
  it('should return error for unknown tool', async () => {