@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
@@ -119,23 +119,26 @@ describe('logDecision', () => {
119
119
  );
120
120
  });
121
121
 
122
- it('should throw error when API call fails', async () => {
122
+ it('should return error when API call fails', async () => {
123
123
  mockApiClient.logDecision.mockResolvedValue({
124
124
  ok: false,
125
125
  error: 'Insert failed',
126
126
  });
127
127
  const ctx = createMockContext();
128
128
 
129
- await expect(
130
- logDecision(
131
- {
132
- project_id: '123e4567-e89b-12d3-a456-426614174000',
133
- title: 'Test',
134
- description: 'Test',
135
- },
136
- ctx
137
- )
138
- ).rejects.toThrow('Failed to log decision: Insert failed');
129
+ const result = await logDecision(
130
+ {
131
+ project_id: '123e4567-e89b-12d3-a456-426614174000',
132
+ title: 'Test',
133
+ description: 'Test',
134
+ },
135
+ ctx
136
+ );
137
+
138
+ expect(result.isError).toBe(true);
139
+ expect(result.result).toMatchObject({
140
+ error: 'Insert failed',
141
+ });
139
142
  });
140
143
  });
141
144
 
@@ -198,7 +201,7 @@ describe('getDecisions', () => {
198
201
  });
199
202
  });
200
203
 
201
- it('should call API client getDecisions', async () => {
204
+ it('should call API client getDecisions with options', async () => {
202
205
  mockApiClient.getDecisions.mockResolvedValue({
203
206
  ok: true,
204
207
  data: { decisions: [] },
@@ -211,23 +214,27 @@ describe('getDecisions', () => {
211
214
  );
212
215
 
213
216
  expect(mockApiClient.getDecisions).toHaveBeenCalledWith(
214
- '123e4567-e89b-12d3-a456-426614174000'
217
+ '123e4567-e89b-12d3-a456-426614174000',
218
+ { limit: 50, offset: 0, search_query: undefined }
215
219
  );
216
220
  });
217
221
 
218
- it('should throw error when query fails', async () => {
222
+ it('should return error when query fails', async () => {
219
223
  mockApiClient.getDecisions.mockResolvedValue({
220
224
  ok: false,
221
225
  error: 'Query failed',
222
226
  });
223
227
  const ctx = createMockContext();
224
228
 
225
- await expect(
226
- getDecisions(
227
- { project_id: '123e4567-e89b-12d3-a456-426614174000' },
228
- ctx
229
- )
230
- ).rejects.toThrow('Failed to fetch decisions: Query failed');
229
+ const result = await getDecisions(
230
+ { project_id: '123e4567-e89b-12d3-a456-426614174000' },
231
+ ctx
232
+ );
233
+
234
+ expect(result.isError).toBe(true);
235
+ expect(result.result).toMatchObject({
236
+ error: 'Query failed',
237
+ });
231
238
  });
232
239
  });
233
240
 
@@ -286,18 +293,21 @@ describe('deleteDecision', () => {
286
293
  );
287
294
  });
288
295
 
289
- it('should throw error when delete fails', async () => {
296
+ it('should return error when delete fails', async () => {
290
297
  mockApiClient.deleteDecision.mockResolvedValue({
291
298
  ok: false,
292
299
  error: 'Delete failed',
293
300
  });
294
301
  const ctx = createMockContext();
295
302
 
296
- await expect(
297
- deleteDecision(
298
- { decision_id: '123e4567-e89b-12d3-a456-426614174000' },
299
- ctx
300
- )
301
- ).rejects.toThrow('Failed to delete decision: Delete failed');
303
+ const result = await deleteDecision(
304
+ { decision_id: '123e4567-e89b-12d3-a456-426614174000' },
305
+ ctx
306
+ );
307
+
308
+ expect(result.isError).toBe(true);
309
+ expect(result.result).toMatchObject({
310
+ error: 'Delete failed',
311
+ });
302
312
  });
303
313
  });
@@ -10,22 +10,31 @@
10
10
  */
11
11
 
12
12
  import type { Handler, HandlerRegistry } from './types.js';
13
- import { validateRequired, validateUUID } from '../validators.js';
13
+ import { parseArgs, uuidValidator } from '../validators.js';
14
14
  import { getApiClient } from '../api-client.js';
15
15
 
16
- export const logDecision: Handler = async (args, ctx) => {
17
- const { project_id, title, description, rationale, alternatives_considered } = args as {
18
- project_id: string;
19
- title: string;
20
- description: string;
21
- rationale?: string;
22
- alternatives_considered?: string[];
23
- };
16
+ // Argument schemas for type-safe parsing
17
+ const logDecisionSchema = {
18
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
19
+ title: { type: 'string' as const, required: true as const },
20
+ description: { type: 'string' as const, required: true as const },
21
+ rationale: { type: 'string' as const },
22
+ alternatives_considered: { type: 'array' as const },
23
+ };
24
24
 
25
- validateRequired(project_id, 'project_id');
26
- validateUUID(project_id, 'project_id');
27
- validateRequired(title, 'title');
28
- validateRequired(description, 'description');
25
+ const getDecisionsSchema = {
26
+ project_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
27
+ limit: { type: 'number' as const, default: 50 },
28
+ offset: { type: 'number' as const, default: 0 },
29
+ search_query: { type: 'string' as const },
30
+ };
31
+
32
+ const deleteDecisionSchema = {
33
+ decision_id: { type: 'string' as const, required: true as const, validate: uuidValidator },
34
+ };
35
+
36
+ export const logDecision: Handler = async (args, ctx) => {
37
+ const { project_id, title, description, rationale, alternatives_considered } = parseArgs(args, logDecisionSchema);
29
38
 
30
39
  const { session } = ctx;
31
40
  const apiClient = getApiClient();
@@ -34,30 +43,29 @@ export const logDecision: Handler = async (args, ctx) => {
34
43
  title,
35
44
  description,
36
45
  rationale,
37
- alternatives_considered
46
+ alternatives_considered: alternatives_considered as string[] | undefined
38
47
  }, session.currentSessionId || undefined);
39
48
 
40
49
  if (!response.ok) {
41
- throw new Error(`Failed to log decision: ${response.error}`);
50
+ return { result: { error: response.error || 'Failed to log decision' }, isError: true };
42
51
  }
43
52
 
44
53
  return { result: { success: true, title, decision_id: response.data?.decision_id } };
45
54
  };
46
55
 
47
- export const getDecisions: Handler = async (args, ctx) => {
48
- const { project_id } = args as {
49
- project_id: string;
50
- };
51
-
52
- validateRequired(project_id, 'project_id');
53
- validateUUID(project_id, 'project_id');
56
+ export const getDecisions: Handler = async (args, _ctx) => {
57
+ const { project_id, limit, offset, search_query } = parseArgs(args, getDecisionsSchema);
54
58
 
55
59
  const apiClient = getApiClient();
56
60
 
57
- const response = await apiClient.getDecisions(project_id);
61
+ const response = await apiClient.getDecisions(project_id, {
62
+ limit,
63
+ offset,
64
+ search_query
65
+ });
58
66
 
59
67
  if (!response.ok) {
60
- throw new Error(`Failed to fetch decisions: ${response.error}`);
68
+ return { result: { error: response.error || 'Failed to fetch decisions' }, isError: true };
61
69
  }
62
70
 
63
71
  return {
@@ -67,18 +75,15 @@ export const getDecisions: Handler = async (args, ctx) => {
67
75
  };
68
76
  };
69
77
 
70
- export const deleteDecision: Handler = async (args, ctx) => {
71
- const { decision_id } = args as { decision_id: string };
72
-
73
- validateRequired(decision_id, 'decision_id');
74
- validateUUID(decision_id, 'decision_id');
78
+ export const deleteDecision: Handler = async (args, _ctx) => {
79
+ const { decision_id } = parseArgs(args, deleteDecisionSchema);
75
80
 
76
81
  const apiClient = getApiClient();
77
82
 
78
83
  const response = await apiClient.deleteDecision(decision_id);
79
84
 
80
85
  if (!response.ok) {
81
- throw new Error(`Failed to delete decision: ${response.error}`);
86
+ return { result: { error: response.error || 'Failed to delete decision' }, isError: true };
82
87
  }
83
88
 
84
89
  return { result: { success: true } };