@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
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { Handler, HandlerRegistry } from './types.js';
12
- import { validateRequired, validateUUID } from '../validators.js';
12
+ import { parseArgs, uuidValidator, createEnumValidator } from '../validators.js';
13
13
  import { getApiClient } from '../api-client.js';
14
14
 
15
15
  const VALID_GIT_ISSUE_TYPES = [
@@ -25,41 +25,38 @@ const VALID_GIT_ISSUE_STATUSES = ['open', 'resolved'] as const;
25
25
  type GitIssueType = (typeof VALID_GIT_ISSUE_TYPES)[number];
26
26
  type GitIssueStatus = (typeof VALID_GIT_ISSUE_STATUSES)[number];
27
27
 
28
- export const addGitIssue: Handler = async (args, ctx) => {
29
- const {
30
- project_id,
31
- issue_type,
32
- branch,
33
- target_branch,
34
- pr_url,
35
- conflicting_files,
36
- error_message,
37
- task_id,
38
- } = args as {
39
- project_id: string;
40
- issue_type: string;
41
- branch: string;
42
- target_branch?: string;
43
- pr_url?: string;
44
- conflicting_files?: string[];
45
- error_message?: string;
46
- task_id?: string;
47
- };
48
-
49
- validateRequired(project_id, 'project_id');
50
- validateUUID(project_id, 'project_id');
51
- validateRequired(issue_type, 'issue_type');
52
- validateRequired(branch, 'branch');
53
-
54
- if (!VALID_GIT_ISSUE_TYPES.includes(issue_type as GitIssueType)) {
55
- throw new Error(
56
- `Invalid issue_type. Valid types: ${VALID_GIT_ISSUE_TYPES.join(', ')}`
57
- );
58
- }
28
+ // Argument schemas for type-safe parsing
29
+ const addGitIssueSchema = {
30
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
31
+ issue_type: { type: 'string' as const, required: true as const, validate: createEnumValidator(VALID_GIT_ISSUE_TYPES) },
32
+ branch: { type: 'string' as const, required: true as const },
33
+ target_branch: { type: 'string' as const },
34
+ pr_url: { type: 'string' as const },
35
+ conflicting_files: { type: 'array' as const },
36
+ error_message: { type: 'string' as const },
37
+ task_id: { type: 'string' as const, validate: uuidValidator },
38
+ };
59
39
 
60
- if (task_id) {
61
- validateUUID(task_id, 'task_id');
62
- }
40
+ const resolveGitIssueSchema = {
41
+ git_issue_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
42
+ resolution_note: { type: 'string' as const },
43
+ auto_resolved: { type: 'boolean' as const },
44
+ };
45
+
46
+ const getGitIssuesSchema = {
47
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
48
+ status: { type: 'string' as const, default: 'open', validate: createEnumValidator(VALID_GIT_ISSUE_STATUSES) },
49
+ issue_type: { type: 'string' as const, validate: createEnumValidator(VALID_GIT_ISSUE_TYPES) },
50
+ branch: { type: 'string' as const },
51
+ limit: { type: 'number' as const, default: 50 },
52
+ };
53
+
54
+ const deleteGitIssueSchema = {
55
+ git_issue_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
56
+ };
57
+
58
+ export const addGitIssue: Handler = async (args, ctx) => {
59
+ const { project_id, issue_type, branch, target_branch, pr_url, conflicting_files, error_message, task_id } = parseArgs(args, addGitIssueSchema);
63
60
 
64
61
  const apiClient = getApiClient();
65
62
  const response = await apiClient.addGitIssue(project_id, {
@@ -67,7 +64,7 @@ export const addGitIssue: Handler = async (args, ctx) => {
67
64
  branch,
68
65
  target_branch,
69
66
  pr_url,
70
- conflicting_files,
67
+ conflicting_files: conflicting_files as string[] | undefined,
71
68
  error_message,
72
69
  task_id
73
70
  }, ctx.session.currentSessionId || undefined);
@@ -80,14 +77,7 @@ export const addGitIssue: Handler = async (args, ctx) => {
80
77
  };
81
78
 
82
79
  export const resolveGitIssue: Handler = async (args, ctx) => {
83
- const { git_issue_id, resolution_note, auto_resolved } = args as {
84
- git_issue_id: string;
85
- resolution_note?: string;
86
- auto_resolved?: boolean;
87
- };
88
-
89
- validateRequired(git_issue_id, 'git_issue_id');
90
- validateUUID(git_issue_id, 'git_issue_id');
80
+ const { git_issue_id, resolution_note, auto_resolved } = parseArgs(args, resolveGitIssueSchema);
91
81
 
92
82
  const apiClient = getApiClient();
93
83
  const response = await apiClient.resolveGitIssue(git_issue_id, {
@@ -102,40 +92,13 @@ export const resolveGitIssue: Handler = async (args, ctx) => {
102
92
  return { result: response.data };
103
93
  };
104
94
 
105
- export const getGitIssues: Handler = async (args, ctx) => {
106
- const {
107
- project_id,
108
- status = 'open',
109
- issue_type,
110
- branch,
111
- limit = 50,
112
- } = args as {
113
- project_id: string;
114
- status?: string;
115
- issue_type?: string;
116
- branch?: string;
117
- limit?: number;
118
- };
119
-
120
- validateRequired(project_id, 'project_id');
121
- validateUUID(project_id, 'project_id');
122
-
123
- if (status && !VALID_GIT_ISSUE_STATUSES.includes(status as GitIssueStatus)) {
124
- throw new Error(
125
- `Invalid status. Valid statuses: ${VALID_GIT_ISSUE_STATUSES.join(', ')}`
126
- );
127
- }
128
-
129
- if (issue_type && !VALID_GIT_ISSUE_TYPES.includes(issue_type as GitIssueType)) {
130
- throw new Error(
131
- `Invalid issue_type. Valid types: ${VALID_GIT_ISSUE_TYPES.join(', ')}`
132
- );
133
- }
95
+ export const getGitIssues: Handler = async (args, _ctx) => {
96
+ const { project_id, status, issue_type, branch, limit } = parseArgs(args, getGitIssuesSchema);
134
97
 
135
98
  const apiClient = getApiClient();
136
99
  const response = await apiClient.getGitIssues(project_id, {
137
- status,
138
- issue_type,
100
+ status: status as GitIssueStatus | undefined,
101
+ issue_type: issue_type as GitIssueType | undefined,
139
102
  branch,
140
103
  limit
141
104
  });
@@ -147,11 +110,8 @@ export const getGitIssues: Handler = async (args, ctx) => {
147
110
  return { result: response.data };
148
111
  };
149
112
 
150
- export const deleteGitIssue: Handler = async (args, ctx) => {
151
- const { git_issue_id } = args as { git_issue_id: string };
152
-
153
- validateRequired(git_issue_id, 'git_issue_id');
154
- validateUUID(git_issue_id, 'git_issue_id');
113
+ export const deleteGitIssue: Handler = async (args, _ctx) => {
114
+ const { git_issue_id } = parseArgs(args, deleteGitIssueSchema);
155
115
 
156
116
  const apiClient = getApiClient();
157
117
  const response = await apiClient.deleteGitIssue(git_issue_id);
@@ -12,22 +12,55 @@
12
12
  */
13
13
 
14
14
  import type { Handler, HandlerRegistry } from './types.js';
15
- import { validateRequired, validateUUID, validatePriority, validateEstimatedMinutes } from '../validators.js';
15
+ import {
16
+ parseArgs,
17
+ uuidValidator,
18
+ priorityValidator,
19
+ minutesValidator,
20
+ createEnumValidator,
21
+ } from '../validators.js';
16
22
  import { getApiClient } from '../api-client.js';
17
23
 
18
- type IdeaStatus = 'raw' | 'exploring' | 'planned' | 'in_development' | 'shipped';
24
+ const VALID_IDEA_STATUSES = ['raw', 'exploring', 'planned', 'in_development', 'shipped'] as const;
25
+ type IdeaStatus = typeof VALID_IDEA_STATUSES[number];
19
26
 
20
- export const addIdea: Handler = async (args, ctx) => {
21
- const { project_id, title, description, status } = args as {
22
- project_id: string;
23
- title: string;
24
- description?: string;
25
- status?: IdeaStatus;
26
- };
27
+ // Argument schemas for type-safe parsing
28
+ const addIdeaSchema = {
29
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
30
+ title: { type: 'string' as const, required: true as const },
31
+ description: { type: 'string' as const },
32
+ status: { type: 'string' as const, validate: createEnumValidator(VALID_IDEA_STATUSES) },
33
+ };
34
+
35
+ const updateIdeaSchema = {
36
+ idea_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
37
+ title: { type: 'string' as const },
38
+ description: { type: 'string' as const },
39
+ status: { type: 'string' as const, validate: createEnumValidator(VALID_IDEA_STATUSES) },
40
+ doc_url: { type: 'string' as const },
41
+ };
27
42
 
28
- validateRequired(project_id, 'project_id');
29
- validateUUID(project_id, 'project_id');
30
- validateRequired(title, 'title');
43
+ const getIdeasSchema = {
44
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
45
+ status: { type: 'string' as const, validate: createEnumValidator(VALID_IDEA_STATUSES) },
46
+ limit: { type: 'number' as const, default: 50 },
47
+ offset: { type: 'number' as const, default: 0 },
48
+ search_query: { type: 'string' as const },
49
+ };
50
+
51
+ const deleteIdeaSchema = {
52
+ idea_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
53
+ };
54
+
55
+ const convertIdeaToTaskSchema = {
56
+ idea_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
57
+ priority: { type: 'number' as const, default: 3, validate: priorityValidator },
58
+ estimated_minutes: { type: 'number' as const, validate: minutesValidator },
59
+ update_status: { type: 'boolean' as const, default: true },
60
+ };
61
+
62
+ export const addIdea: Handler = async (args, ctx) => {
63
+ const { project_id, title, description, status } = parseArgs(args, addIdeaSchema);
31
64
 
32
65
  const { session } = ctx;
33
66
  const apiClient = getApiClient();
@@ -35,7 +68,7 @@ export const addIdea: Handler = async (args, ctx) => {
35
68
  const response = await apiClient.addIdea(project_id, {
36
69
  title,
37
70
  description,
38
- status
71
+ status: status as IdeaStatus | undefined
39
72
  }, session.currentSessionId || undefined);
40
73
 
41
74
  if (!response.ok) {
@@ -45,24 +78,15 @@ export const addIdea: Handler = async (args, ctx) => {
45
78
  return { result: { success: true, idea_id: response.data?.idea_id, title } };
46
79
  };
47
80
 
48
- export const updateIdea: Handler = async (args, ctx) => {
49
- const { idea_id, title, description, status, doc_url } = args as {
50
- idea_id: string;
51
- title?: string;
52
- description?: string;
53
- status?: IdeaStatus;
54
- doc_url?: string;
55
- };
56
-
57
- validateRequired(idea_id, 'idea_id');
58
- validateUUID(idea_id, 'idea_id');
81
+ export const updateIdea: Handler = async (args, _ctx) => {
82
+ const { idea_id, title, description, status, doc_url } = parseArgs(args, updateIdeaSchema);
59
83
 
60
84
  const apiClient = getApiClient();
61
85
 
62
86
  const response = await apiClient.updateIdea(idea_id, {
63
87
  title,
64
88
  description,
65
- status,
89
+ status: status as IdeaStatus | undefined,
66
90
  doc_url
67
91
  });
68
92
 
@@ -73,22 +97,13 @@ export const updateIdea: Handler = async (args, ctx) => {
73
97
  return { result: { success: true, idea_id } };
74
98
  };
75
99
 
76
- export const getIdeas: Handler = async (args, ctx) => {
77
- const { project_id, status, limit = 50, offset = 0, search_query } = args as {
78
- project_id: string;
79
- status?: IdeaStatus;
80
- limit?: number;
81
- offset?: number;
82
- search_query?: string;
83
- };
84
-
85
- validateRequired(project_id, 'project_id');
86
- validateUUID(project_id, 'project_id');
100
+ export const getIdeas: Handler = async (args, _ctx) => {
101
+ const { project_id, status, limit, offset, search_query } = parseArgs(args, getIdeasSchema);
87
102
 
88
103
  const apiClient = getApiClient();
89
104
 
90
105
  const response = await apiClient.getIdeas(project_id, {
91
- status,
106
+ status: status as IdeaStatus | undefined,
92
107
  limit,
93
108
  offset,
94
109
  search_query
@@ -105,11 +120,8 @@ export const getIdeas: Handler = async (args, ctx) => {
105
120
  };
106
121
  };
107
122
 
108
- export const deleteIdea: Handler = async (args, ctx) => {
109
- const { idea_id } = args as { idea_id: string };
110
-
111
- validateRequired(idea_id, 'idea_id');
112
- validateUUID(idea_id, 'idea_id');
123
+ export const deleteIdea: Handler = async (args, _ctx) => {
124
+ const { idea_id } = parseArgs(args, deleteIdeaSchema);
113
125
 
114
126
  const apiClient = getApiClient();
115
127
 
@@ -122,18 +134,8 @@ export const deleteIdea: Handler = async (args, ctx) => {
122
134
  return { result: { success: true } };
123
135
  };
124
136
 
125
- export const convertIdeaToTask: Handler = async (args, ctx) => {
126
- const { idea_id, priority = 3, estimated_minutes, update_status = true } = args as {
127
- idea_id: string;
128
- priority?: number;
129
- estimated_minutes?: number;
130
- update_status?: boolean;
131
- };
132
-
133
- validateRequired(idea_id, 'idea_id');
134
- validateUUID(idea_id, 'idea_id');
135
- validatePriority(priority);
136
- validateEstimatedMinutes(estimated_minutes);
137
+ export const convertIdeaToTask: Handler = async (args, _ctx) => {
138
+ const { idea_id, priority, estimated_minutes, update_status } = parseArgs(args, convertIdeaToTaskSchema);
137
139
 
138
140
  const apiClient = getApiClient();
139
141
 
@@ -25,6 +25,8 @@ export * from './organizations.js';
25
25
  export * from './cost.js';
26
26
  export * from './git-issues.js';
27
27
  export * from './sprints.js';
28
+ export * from './file-checkouts.js';
29
+ export * from './roles.js';
28
30
 
29
31
  import type { HandlerRegistry } from './types.js';
30
32
  import { milestoneHandlers } from './milestones.js';
@@ -46,6 +48,8 @@ import { organizationHandlers } from './organizations.js';
46
48
  import { costHandlers } from './cost.js';
47
49
  import { gitIssueHandlers } from './git-issues.js';
48
50
  import { sprintHandlers } from './sprints.js';
51
+ import { fileCheckoutHandlers } from './file-checkouts.js';
52
+ import { roleHandlers } from './roles.js';
49
53
 
50
54
  /**
51
55
  * Build the complete handler registry from all modules
@@ -71,5 +75,7 @@ export function buildHandlerRegistry(): HandlerRegistry {
71
75
  ...costHandlers,
72
76
  ...gitIssueHandlers,
73
77
  ...sprintHandlers,
78
+ ...fileCheckoutHandlers,
79
+ ...roleHandlers,
74
80
  };
75
81
  }
@@ -143,7 +143,7 @@ describe('updateMilestone', () => {
143
143
  milestone_id: '123e4567-e89b-12d3-a456-426614174000',
144
144
  status: 'invalid_status',
145
145
  }, ctx)
146
- ).rejects.toThrow('status must be pending, in_progress, or completed');
146
+ ).rejects.toThrow('Invalid status: "invalid_status"');
147
147
  });
148
148
 
149
149
  it('should update title successfully', async () => {
@@ -12,20 +12,47 @@
12
12
  */
13
13
 
14
14
  import type { Handler, HandlerRegistry } from './types.js';
15
- import { ValidationError, validateRequired, validateUUID } from '../validators.js';
15
+ import {
16
+ parseArgs,
17
+ uuidValidator,
18
+ createEnumValidator,
19
+ ValidationError,
20
+ } from '../validators.js';
16
21
  import { getApiClient } from '../api-client.js';
17
22
 
18
- export const addMilestone: Handler = async (args, ctx) => {
19
- const { task_id, title, description, order_index } = args as {
20
- task_id: string;
21
- title: string;
22
- description?: string;
23
- order_index?: number;
24
- };
23
+ const VALID_MILESTONE_STATUSES = ['pending', 'in_progress', 'completed'] as const;
24
+ type MilestoneStatus = typeof VALID_MILESTONE_STATUSES[number];
25
+
26
+ // Argument schemas for type-safe parsing
27
+ const addMilestoneSchema = {
28
+ task_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
29
+ title: { type: 'string' as const, required: true as const },
30
+ description: { type: 'string' as const },
31
+ order_index: { type: 'number' as const },
32
+ };
33
+
34
+ const updateMilestoneSchema = {
35
+ milestone_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
36
+ title: { type: 'string' as const },
37
+ description: { type: 'string' as const },
38
+ status: { type: 'string' as const, validate: createEnumValidator(VALID_MILESTONE_STATUSES) },
39
+ order_index: { type: 'number' as const },
40
+ };
41
+
42
+ const completeMilestoneSchema = {
43
+ milestone_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
44
+ };
45
+
46
+ const deleteMilestoneSchema = {
47
+ milestone_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
48
+ };
25
49
 
26
- validateRequired(task_id, 'task_id');
27
- validateUUID(task_id, 'task_id');
28
- validateRequired(title, 'title');
50
+ const getMilestonesSchema = {
51
+ task_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
52
+ };
53
+
54
+ export const addMilestone: Handler = async (args, ctx) => {
55
+ const { task_id, title, description, order_index } = parseArgs(args, addMilestoneSchema);
29
56
 
30
57
  const { session } = ctx;
31
58
  const apiClient = getApiClient();
@@ -48,24 +75,8 @@ export const addMilestone: Handler = async (args, ctx) => {
48
75
  };
49
76
  };
50
77
 
51
- export const updateMilestone: Handler = async (args, ctx) => {
52
- const { milestone_id, title, description, status, order_index } = args as {
53
- milestone_id: string;
54
- title?: string;
55
- description?: string;
56
- status?: string;
57
- order_index?: number;
58
- };
59
-
60
- validateRequired(milestone_id, 'milestone_id');
61
- validateUUID(milestone_id, 'milestone_id');
62
-
63
- // Validate status if provided
64
- if (status !== undefined) {
65
- if (!['pending', 'in_progress', 'completed'].includes(status)) {
66
- throw new ValidationError('status must be pending, in_progress, or completed');
67
- }
68
- }
78
+ export const updateMilestone: Handler = async (args, _ctx) => {
79
+ const { milestone_id, title, description, status, order_index } = parseArgs(args, updateMilestoneSchema);
69
80
 
70
81
  // Check that at least one field is provided
71
82
  if (title === undefined && description === undefined && status === undefined && order_index === undefined) {
@@ -77,7 +88,7 @@ export const updateMilestone: Handler = async (args, ctx) => {
77
88
  const response = await apiClient.updateMilestone(milestone_id, {
78
89
  title,
79
90
  description,
80
- status: status as 'pending' | 'in_progress' | 'completed' | undefined,
91
+ status: status as MilestoneStatus | undefined,
81
92
  order_index
82
93
  });
83
94
 
@@ -93,11 +104,8 @@ export const updateMilestone: Handler = async (args, ctx) => {
93
104
  };
94
105
  };
95
106
 
96
- export const completeMilestone: Handler = async (args, ctx) => {
97
- const { milestone_id } = args as { milestone_id: string };
98
-
99
- validateRequired(milestone_id, 'milestone_id');
100
- validateUUID(milestone_id, 'milestone_id');
107
+ export const completeMilestone: Handler = async (args, _ctx) => {
108
+ const { milestone_id } = parseArgs(args, completeMilestoneSchema);
101
109
 
102
110
  const apiClient = getApiClient();
103
111
 
@@ -115,11 +123,8 @@ export const completeMilestone: Handler = async (args, ctx) => {
115
123
  };
116
124
  };
117
125
 
118
- export const deleteMilestone: Handler = async (args, ctx) => {
119
- const { milestone_id } = args as { milestone_id: string };
120
-
121
- validateRequired(milestone_id, 'milestone_id');
122
- validateUUID(milestone_id, 'milestone_id');
126
+ export const deleteMilestone: Handler = async (args, _ctx) => {
127
+ const { milestone_id } = parseArgs(args, deleteMilestoneSchema);
123
128
 
124
129
  const apiClient = getApiClient();
125
130
 
@@ -137,11 +142,8 @@ export const deleteMilestone: Handler = async (args, ctx) => {
137
142
  };
138
143
  };
139
144
 
140
- export const getMilestones: Handler = async (args, ctx) => {
141
- const { task_id } = args as { task_id: string };
142
-
143
- validateRequired(task_id, 'task_id');
144
- validateUUID(task_id, 'task_id');
145
+ export const getMilestones: Handler = async (args, _ctx) => {
146
+ const { task_id } = parseArgs(args, getMilestonesSchema);
145
147
 
146
148
  const apiClient = getApiClient();
147
149