@vibescope/mcp-server 0.0.1 → 0.2.0

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 (173) hide show
  1. package/README.md +113 -98
  2. package/dist/api-client.d.ts +1169 -0
  3. package/dist/api-client.js +713 -0
  4. package/dist/cli.d.ts +1 -6
  5. package/dist/cli.js +39 -240
  6. package/dist/config/tool-categories.d.ts +31 -0
  7. package/dist/config/tool-categories.js +253 -0
  8. package/dist/handlers/blockers.js +57 -58
  9. package/dist/handlers/bodies-of-work.d.ts +2 -0
  10. package/dist/handlers/bodies-of-work.js +108 -477
  11. package/dist/handlers/cost.d.ts +1 -0
  12. package/dist/handlers/cost.js +35 -113
  13. package/dist/handlers/decisions.d.ts +2 -0
  14. package/dist/handlers/decisions.js +28 -27
  15. package/dist/handlers/deployment.js +113 -828
  16. package/dist/handlers/discovery.d.ts +3 -0
  17. package/dist/handlers/discovery.js +26 -627
  18. package/dist/handlers/fallback.d.ts +2 -0
  19. package/dist/handlers/fallback.js +56 -142
  20. package/dist/handlers/findings.d.ts +8 -1
  21. package/dist/handlers/findings.js +65 -68
  22. package/dist/handlers/git-issues.d.ts +9 -13
  23. package/dist/handlers/git-issues.js +80 -225
  24. package/dist/handlers/ideas.d.ts +3 -0
  25. package/dist/handlers/ideas.js +53 -134
  26. package/dist/handlers/index.d.ts +2 -0
  27. package/dist/handlers/index.js +6 -0
  28. package/dist/handlers/milestones.d.ts +2 -0
  29. package/dist/handlers/milestones.js +51 -98
  30. package/dist/handlers/organizations.js +79 -275
  31. package/dist/handlers/progress.d.ts +2 -0
  32. package/dist/handlers/progress.js +25 -123
  33. package/dist/handlers/project.js +42 -221
  34. package/dist/handlers/requests.d.ts +2 -0
  35. package/dist/handlers/requests.js +23 -83
  36. package/dist/handlers/session.js +119 -590
  37. package/dist/handlers/sprints.d.ts +32 -0
  38. package/dist/handlers/sprints.js +275 -0
  39. package/dist/handlers/tasks.d.ts +7 -10
  40. package/dist/handlers/tasks.js +245 -894
  41. package/dist/handlers/tool-docs.d.ts +9 -0
  42. package/dist/handlers/tool-docs.js +904 -0
  43. package/dist/handlers/types.d.ts +11 -3
  44. package/dist/handlers/validation.d.ts +1 -1
  45. package/dist/handlers/validation.js +38 -153
  46. package/dist/index.js +493 -162
  47. package/dist/knowledge.js +106 -9
  48. package/dist/tools.js +34 -4
  49. package/dist/validators.d.ts +21 -0
  50. package/dist/validators.js +91 -0
  51. package/package.json +2 -3
  52. package/src/api-client.ts +1822 -0
  53. package/src/cli.test.ts +128 -302
  54. package/src/cli.ts +41 -285
  55. package/src/handlers/__test-setup__.ts +215 -0
  56. package/src/handlers/__test-utils__.ts +4 -134
  57. package/src/handlers/blockers.test.ts +114 -124
  58. package/src/handlers/blockers.ts +68 -70
  59. package/src/handlers/bodies-of-work.test.ts +236 -831
  60. package/src/handlers/bodies-of-work.ts +210 -525
  61. package/src/handlers/cost.test.ts +149 -113
  62. package/src/handlers/cost.ts +44 -132
  63. package/src/handlers/decisions.test.ts +111 -209
  64. package/src/handlers/decisions.ts +35 -27
  65. package/src/handlers/deployment.test.ts +193 -239
  66. package/src/handlers/deployment.ts +143 -896
  67. package/src/handlers/discovery.test.ts +20 -67
  68. package/src/handlers/discovery.ts +29 -714
  69. package/src/handlers/fallback.test.ts +206 -361
  70. package/src/handlers/fallback.ts +81 -156
  71. package/src/handlers/findings.test.ts +229 -320
  72. package/src/handlers/findings.ts +76 -64
  73. package/src/handlers/git-issues.test.ts +623 -0
  74. package/src/handlers/git-issues.ts +174 -0
  75. package/src/handlers/ideas.test.ts +229 -343
  76. package/src/handlers/ideas.ts +69 -143
  77. package/src/handlers/index.ts +6 -0
  78. package/src/handlers/milestones.test.ts +167 -281
  79. package/src/handlers/milestones.ts +54 -93
  80. package/src/handlers/organizations.test.ts +275 -467
  81. package/src/handlers/organizations.ts +84 -294
  82. package/src/handlers/progress.test.ts +112 -218
  83. package/src/handlers/progress.ts +29 -142
  84. package/src/handlers/project.test.ts +203 -226
  85. package/src/handlers/project.ts +48 -238
  86. package/src/handlers/requests.test.ts +74 -342
  87. package/src/handlers/requests.ts +25 -83
  88. package/src/handlers/session.test.ts +276 -206
  89. package/src/handlers/session.ts +136 -662
  90. package/src/handlers/sprints.test.ts +711 -0
  91. package/src/handlers/sprints.ts +510 -0
  92. package/src/handlers/tasks.test.ts +669 -353
  93. package/src/handlers/tasks.ts +263 -1015
  94. package/src/handlers/tool-docs.ts +1024 -0
  95. package/src/handlers/types.ts +12 -4
  96. package/src/handlers/validation.test.ts +237 -568
  97. package/src/handlers/validation.ts +43 -167
  98. package/src/index.ts +493 -186
  99. package/src/tools.ts +2532 -0
  100. package/src/validators.test.ts +223 -223
  101. package/src/validators.ts +127 -0
  102. package/tsconfig.json +1 -1
  103. package/vitest.config.ts +14 -13
  104. package/dist/cli.test.d.ts +0 -1
  105. package/dist/cli.test.js +0 -367
  106. package/dist/handlers/__test-utils__.d.ts +0 -72
  107. package/dist/handlers/__test-utils__.js +0 -176
  108. package/dist/handlers/checkouts.d.ts +0 -37
  109. package/dist/handlers/checkouts.js +0 -377
  110. package/dist/handlers/knowledge-query.d.ts +0 -22
  111. package/dist/handlers/knowledge-query.js +0 -253
  112. package/dist/handlers/knowledge.d.ts +0 -12
  113. package/dist/handlers/knowledge.js +0 -108
  114. package/dist/handlers/roles.d.ts +0 -30
  115. package/dist/handlers/roles.js +0 -281
  116. package/dist/handlers/tasks.test.d.ts +0 -1
  117. package/dist/handlers/tasks.test.js +0 -431
  118. package/dist/utils.test.d.ts +0 -1
  119. package/dist/utils.test.js +0 -532
  120. package/dist/validators.test.d.ts +0 -1
  121. package/dist/validators.test.js +0 -176
  122. package/src/knowledge.ts +0 -132
  123. package/src/tmpclaude-0078-cwd +0 -1
  124. package/src/tmpclaude-0ee1-cwd +0 -1
  125. package/src/tmpclaude-2dd5-cwd +0 -1
  126. package/src/tmpclaude-344c-cwd +0 -1
  127. package/src/tmpclaude-3860-cwd +0 -1
  128. package/src/tmpclaude-4b63-cwd +0 -1
  129. package/src/tmpclaude-5c73-cwd +0 -1
  130. package/src/tmpclaude-5ee3-cwd +0 -1
  131. package/src/tmpclaude-6795-cwd +0 -1
  132. package/src/tmpclaude-709e-cwd +0 -1
  133. package/src/tmpclaude-9839-cwd +0 -1
  134. package/src/tmpclaude-d829-cwd +0 -1
  135. package/src/tmpclaude-e072-cwd +0 -1
  136. package/src/tmpclaude-f6ee-cwd +0 -1
  137. package/tmpclaude-0439-cwd +0 -1
  138. package/tmpclaude-132f-cwd +0 -1
  139. package/tmpclaude-15bb-cwd +0 -1
  140. package/tmpclaude-165a-cwd +0 -1
  141. package/tmpclaude-1ba9-cwd +0 -1
  142. package/tmpclaude-21a3-cwd +0 -1
  143. package/tmpclaude-2a38-cwd +0 -1
  144. package/tmpclaude-2adf-cwd +0 -1
  145. package/tmpclaude-2f56-cwd +0 -1
  146. package/tmpclaude-3626-cwd +0 -1
  147. package/tmpclaude-3727-cwd +0 -1
  148. package/tmpclaude-40bc-cwd +0 -1
  149. package/tmpclaude-436f-cwd +0 -1
  150. package/tmpclaude-4783-cwd +0 -1
  151. package/tmpclaude-4b6d-cwd +0 -1
  152. package/tmpclaude-4ba4-cwd +0 -1
  153. package/tmpclaude-51e6-cwd +0 -1
  154. package/tmpclaude-5ecf-cwd +0 -1
  155. package/tmpclaude-6f97-cwd +0 -1
  156. package/tmpclaude-7fb2-cwd +0 -1
  157. package/tmpclaude-825c-cwd +0 -1
  158. package/tmpclaude-8baf-cwd +0 -1
  159. package/tmpclaude-8d9f-cwd +0 -1
  160. package/tmpclaude-975c-cwd +0 -1
  161. package/tmpclaude-9983-cwd +0 -1
  162. package/tmpclaude-a045-cwd +0 -1
  163. package/tmpclaude-ac4a-cwd +0 -1
  164. package/tmpclaude-b593-cwd +0 -1
  165. package/tmpclaude-b891-cwd +0 -1
  166. package/tmpclaude-c032-cwd +0 -1
  167. package/tmpclaude-cf43-cwd +0 -1
  168. package/tmpclaude-d040-cwd +0 -1
  169. package/tmpclaude-dcdd-cwd +0 -1
  170. package/tmpclaude-dcee-cwd +0 -1
  171. package/tmpclaude-e16b-cwd +0 -1
  172. package/tmpclaude-ecd2-cwd +0 -1
  173. package/tmpclaude-f48d-cwd +0 -1
@@ -7,6 +7,7 @@
7
7
  * - add_cost_alert
8
8
  * - update_cost_alert
9
9
  * - delete_cost_alert
10
+ * - get_task_costs
10
11
  */
11
12
  import type { Handler, HandlerRegistry } from './types.js';
12
13
  /**
@@ -7,86 +7,50 @@
7
7
  * - add_cost_alert
8
8
  * - update_cost_alert
9
9
  * - delete_cost_alert
10
+ * - get_task_costs
10
11
  */
12
+ import { getApiClient } from '../api-client.js';
11
13
  /**
12
14
  * Get cost summary for a project (daily, weekly, or monthly)
13
15
  */
14
16
  export const getCostSummary = async (args, ctx) => {
15
17
  const { project_id, period = 'daily', limit = 30 } = args;
16
- const { supabase } = ctx;
17
18
  if (!project_id) {
18
19
  return {
19
20
  result: { error: 'project_id is required' },
20
21
  isError: true,
21
22
  };
22
23
  }
23
- // Select the appropriate view based on period
24
- const viewName = `${period}_cost_summary`;
25
- const { data, error } = await supabase
26
- .from(viewName)
27
- .select('*')
28
- .eq('project_id', project_id)
29
- .order(period === 'daily' ? 'date' : period === 'weekly' ? 'week_start' : 'month_start', { ascending: false })
30
- .limit(limit);
31
- if (error) {
24
+ const apiClient = getApiClient();
25
+ const response = await apiClient.getCostSummary(project_id, { period, limit });
26
+ if (!response.ok) {
32
27
  return {
33
- result: { error: `Failed to get cost summary: ${error.message}` },
28
+ result: { error: response.error || 'Failed to get cost summary' },
34
29
  isError: true,
35
30
  };
36
31
  }
37
- // Calculate totals
38
- const totals = (data || []).reduce((acc, row) => ({
39
- sessions: acc.sessions + (row.session_count || 0),
40
- tokens: acc.tokens + (row.total_tokens || 0),
41
- calls: acc.calls + (row.total_calls || 0),
42
- cost: acc.cost + parseFloat(row.estimated_cost_usd || '0'),
43
- }), { sessions: 0, tokens: 0, calls: 0, cost: 0 });
44
- return {
45
- result: {
46
- period,
47
- project_id,
48
- summary: data || [],
49
- totals: {
50
- ...totals,
51
- cost: Math.round(totals.cost * 100) / 100,
52
- },
53
- },
54
- };
32
+ return { result: response.data };
55
33
  };
56
34
  /**
57
35
  * Get cost alerts for the current user
58
36
  */
59
37
  export const getCostAlerts = async (args, ctx) => {
60
38
  const { project_id } = args;
61
- const { supabase, auth } = ctx;
62
- let query = supabase
63
- .from('cost_alerts')
64
- .select('*')
65
- .eq('user_id', auth.userId)
66
- .order('threshold_amount', { ascending: true });
67
- if (project_id) {
68
- query = query.eq('project_id', project_id);
69
- }
70
- const { data, error } = await query;
71
- if (error) {
39
+ const apiClient = getApiClient();
40
+ const response = await apiClient.getCostAlerts();
41
+ if (!response.ok) {
72
42
  return {
73
- result: { error: `Failed to get cost alerts: ${error.message}` },
43
+ result: { error: response.error || 'Failed to get cost alerts' },
74
44
  isError: true,
75
45
  };
76
46
  }
77
- return {
78
- result: {
79
- alerts: data || [],
80
- count: data?.length || 0,
81
- },
82
- };
47
+ return { result: response.data };
83
48
  };
84
49
  /**
85
50
  * Add a cost alert
86
51
  */
87
52
  export const addCostAlert = async (args, ctx) => {
88
53
  const { project_id, threshold_amount, threshold_period, alert_type = 'warning', } = args;
89
- const { supabase, auth } = ctx;
90
54
  if (!threshold_amount || threshold_amount <= 0) {
91
55
  return {
92
56
  result: { error: 'threshold_amount must be a positive number' },
@@ -99,37 +63,26 @@ export const addCostAlert = async (args, ctx) => {
99
63
  isError: true,
100
64
  };
101
65
  }
102
- const { data, error } = await supabase
103
- .from('cost_alerts')
104
- .insert({
105
- user_id: auth.userId,
106
- project_id: project_id || null,
66
+ const apiClient = getApiClient();
67
+ const response = await apiClient.addCostAlert({
68
+ project_id,
107
69
  threshold_amount,
108
70
  threshold_period,
109
- alert_type,
110
- })
111
- .select()
112
- .single();
113
- if (error) {
71
+ alert_type
72
+ });
73
+ if (!response.ok) {
114
74
  return {
115
- result: { error: `Failed to create cost alert: ${error.message}` },
75
+ result: { error: response.error || 'Failed to create cost alert' },
116
76
  isError: true,
117
77
  };
118
78
  }
119
- return {
120
- result: {
121
- success: true,
122
- alert: data,
123
- message: `Alert created: ${alert_type} when ${threshold_period} cost exceeds $${threshold_amount}`,
124
- },
125
- };
79
+ return { result: response.data };
126
80
  };
127
81
  /**
128
82
  * Update a cost alert
129
83
  */
130
84
  export const updateCostAlert = async (args, ctx) => {
131
85
  const { alert_id, threshold_amount, threshold_period, alert_type, enabled, } = args;
132
- const { supabase, auth } = ctx;
133
86
  if (!alert_id) {
134
87
  return {
135
88
  result: { error: 'alert_id is required' },
@@ -151,88 +104,57 @@ export const updateCostAlert = async (args, ctx) => {
151
104
  isError: true,
152
105
  };
153
106
  }
154
- const { data, error } = await supabase
155
- .from('cost_alerts')
156
- .update(updates)
157
- .eq('id', alert_id)
158
- .eq('user_id', auth.userId)
159
- .select()
160
- .single();
161
- if (error) {
107
+ const apiClient = getApiClient();
108
+ const response = await apiClient.updateCostAlert(alert_id, updates);
109
+ if (!response.ok) {
162
110
  return {
163
- result: { error: `Failed to update cost alert: ${error.message}` },
111
+ result: { error: response.error || 'Failed to update cost alert' },
164
112
  isError: true,
165
113
  };
166
114
  }
167
- return {
168
- result: {
169
- success: true,
170
- alert: data,
171
- },
172
- };
115
+ return { result: response.data };
173
116
  };
174
117
  /**
175
118
  * Delete a cost alert
176
119
  */
177
120
  export const deleteCostAlert = async (args, ctx) => {
178
121
  const { alert_id } = args;
179
- const { supabase, auth } = ctx;
180
122
  if (!alert_id) {
181
123
  return {
182
124
  result: { error: 'alert_id is required' },
183
125
  isError: true,
184
126
  };
185
127
  }
186
- const { error } = await supabase
187
- .from('cost_alerts')
188
- .delete()
189
- .eq('id', alert_id)
190
- .eq('user_id', auth.userId);
191
- if (error) {
128
+ const apiClient = getApiClient();
129
+ const response = await apiClient.deleteCostAlert(alert_id);
130
+ if (!response.ok) {
192
131
  return {
193
- result: { error: `Failed to delete cost alert: ${error.message}` },
132
+ result: { error: response.error || 'Failed to delete cost alert' },
194
133
  isError: true,
195
134
  };
196
135
  }
197
- return {
198
- result: {
199
- success: true,
200
- deleted_alert_id: alert_id,
201
- },
202
- };
136
+ return { result: response.data };
203
137
  };
204
138
  /**
205
139
  * Get task costs for a project
206
140
  */
207
141
  export const getTaskCosts = async (args, ctx) => {
208
142
  const { project_id, limit = 20 } = args;
209
- const { supabase } = ctx;
210
143
  if (!project_id) {
211
144
  return {
212
145
  result: { error: 'project_id is required' },
213
146
  isError: true,
214
147
  };
215
148
  }
216
- const { data, error } = await supabase
217
- .from('task_costs')
218
- .select('*')
219
- .eq('project_id', project_id)
220
- .order('estimated_cost_usd', { ascending: false })
221
- .limit(limit);
222
- if (error) {
149
+ const apiClient = getApiClient();
150
+ const response = await apiClient.getTaskCosts(project_id, limit);
151
+ if (!response.ok) {
223
152
  return {
224
- result: { error: `Failed to get task costs: ${error.message}` },
153
+ result: { error: response.error || 'Failed to get task costs' },
225
154
  isError: true,
226
155
  };
227
156
  }
228
- const totalCost = (data || []).reduce((sum, task) => sum + parseFloat(task.estimated_cost_usd || '0'), 0);
229
- return {
230
- result: {
231
- project_id,
232
- tasks: data || [],
233
- total_cost_usd: Math.round(totalCost * 100) / 100,
234
- },
235
- };
157
+ return { result: response.data };
236
158
  };
237
159
  /**
238
160
  * Cost handlers registry
@@ -5,6 +5,8 @@
5
5
  * - log_decision
6
6
  * - get_decisions
7
7
  * - delete_decision
8
+ *
9
+ * MIGRATED: Uses Vibescope API client instead of direct Supabase
8
10
  */
9
11
  import type { Handler, HandlerRegistry } from './types.js';
10
12
  export declare const logDecision: Handler;
@@ -5,53 +5,54 @@
5
5
  * - log_decision
6
6
  * - get_decisions
7
7
  * - delete_decision
8
+ *
9
+ * MIGRATED: Uses Vibescope API client instead of direct Supabase
8
10
  */
9
11
  import { validateRequired, validateUUID } from '../validators.js';
12
+ import { getApiClient } from '../api-client.js';
10
13
  export const logDecision = async (args, ctx) => {
11
14
  const { project_id, title, description, rationale, alternatives_considered } = args;
12
15
  validateRequired(project_id, 'project_id');
13
16
  validateUUID(project_id, 'project_id');
14
17
  validateRequired(title, 'title');
15
18
  validateRequired(description, 'description');
16
- const { supabase, session } = ctx;
17
- const { error } = await supabase
18
- .from('decisions')
19
- .insert({
20
- project_id,
19
+ const { session } = ctx;
20
+ const apiClient = getApiClient();
21
+ const response = await apiClient.logDecision(project_id, {
21
22
  title,
22
23
  description,
23
- rationale: rationale || null,
24
- alternatives_considered: alternatives_considered || null,
25
- created_by: 'agent',
26
- created_by_session_id: session.currentSessionId,
27
- });
28
- if (error)
29
- throw new Error(`Failed to log decision: ${error.message}`);
30
- return { result: { success: true, title } };
24
+ rationale,
25
+ alternatives_considered
26
+ }, session.currentSessionId || undefined);
27
+ if (!response.ok) {
28
+ throw new Error(`Failed to log decision: ${response.error}`);
29
+ }
30
+ return { result: { success: true, title, decision_id: response.data?.decision_id } };
31
31
  };
32
32
  export const getDecisions = async (args, ctx) => {
33
33
  const { project_id } = args;
34
34
  validateRequired(project_id, 'project_id');
35
35
  validateUUID(project_id, 'project_id');
36
- const { data, error } = await ctx.supabase
37
- .from('decisions')
38
- .select('id, title, description, rationale, created_at')
39
- .eq('project_id', project_id)
40
- .order('created_at', { ascending: false });
41
- if (error)
42
- throw new Error(`Failed to fetch decisions: ${error.message}`);
43
- return { result: { decisions: data || [] } };
36
+ const apiClient = getApiClient();
37
+ const response = await apiClient.getDecisions(project_id);
38
+ if (!response.ok) {
39
+ throw new Error(`Failed to fetch decisions: ${response.error}`);
40
+ }
41
+ return {
42
+ result: {
43
+ decisions: response.data?.decisions || [],
44
+ },
45
+ };
44
46
  };
45
47
  export const deleteDecision = async (args, ctx) => {
46
48
  const { decision_id } = args;
47
49
  validateRequired(decision_id, 'decision_id');
48
50
  validateUUID(decision_id, 'decision_id');
49
- const { error } = await ctx.supabase
50
- .from('decisions')
51
- .delete()
52
- .eq('id', decision_id);
53
- if (error)
54
- throw new Error(`Failed to delete decision: ${error.message}`);
51
+ const apiClient = getApiClient();
52
+ const response = await apiClient.deleteDecision(decision_id);
53
+ if (!response.ok) {
54
+ throw new Error(`Failed to delete decision: ${response.error}`);
55
+ }
55
56
  return { result: { success: true } };
56
57
  };
57
58
  /**