@vibescope/mcp-server 0.0.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 (170) hide show
  1. package/README.md +98 -0
  2. package/dist/cli.d.ts +34 -0
  3. package/dist/cli.js +356 -0
  4. package/dist/cli.test.d.ts +1 -0
  5. package/dist/cli.test.js +367 -0
  6. package/dist/handlers/__test-utils__.d.ts +72 -0
  7. package/dist/handlers/__test-utils__.js +176 -0
  8. package/dist/handlers/blockers.d.ts +18 -0
  9. package/dist/handlers/blockers.js +81 -0
  10. package/dist/handlers/bodies-of-work.d.ts +34 -0
  11. package/dist/handlers/bodies-of-work.js +614 -0
  12. package/dist/handlers/checkouts.d.ts +37 -0
  13. package/dist/handlers/checkouts.js +377 -0
  14. package/dist/handlers/cost.d.ts +39 -0
  15. package/dist/handlers/cost.js +247 -0
  16. package/dist/handlers/decisions.d.ts +16 -0
  17. package/dist/handlers/decisions.js +64 -0
  18. package/dist/handlers/deployment.d.ts +36 -0
  19. package/dist/handlers/deployment.js +1062 -0
  20. package/dist/handlers/discovery.d.ts +14 -0
  21. package/dist/handlers/discovery.js +870 -0
  22. package/dist/handlers/fallback.d.ts +18 -0
  23. package/dist/handlers/fallback.js +216 -0
  24. package/dist/handlers/findings.d.ts +18 -0
  25. package/dist/handlers/findings.js +110 -0
  26. package/dist/handlers/git-issues.d.ts +22 -0
  27. package/dist/handlers/git-issues.js +247 -0
  28. package/dist/handlers/ideas.d.ts +19 -0
  29. package/dist/handlers/ideas.js +188 -0
  30. package/dist/handlers/index.d.ts +29 -0
  31. package/dist/handlers/index.js +65 -0
  32. package/dist/handlers/knowledge-query.d.ts +22 -0
  33. package/dist/handlers/knowledge-query.js +253 -0
  34. package/dist/handlers/knowledge.d.ts +12 -0
  35. package/dist/handlers/knowledge.js +108 -0
  36. package/dist/handlers/milestones.d.ts +20 -0
  37. package/dist/handlers/milestones.js +179 -0
  38. package/dist/handlers/organizations.d.ts +36 -0
  39. package/dist/handlers/organizations.js +428 -0
  40. package/dist/handlers/progress.d.ts +14 -0
  41. package/dist/handlers/progress.js +149 -0
  42. package/dist/handlers/project.d.ts +20 -0
  43. package/dist/handlers/project.js +278 -0
  44. package/dist/handlers/requests.d.ts +16 -0
  45. package/dist/handlers/requests.js +131 -0
  46. package/dist/handlers/roles.d.ts +30 -0
  47. package/dist/handlers/roles.js +281 -0
  48. package/dist/handlers/session.d.ts +20 -0
  49. package/dist/handlers/session.js +791 -0
  50. package/dist/handlers/tasks.d.ts +52 -0
  51. package/dist/handlers/tasks.js +1111 -0
  52. package/dist/handlers/tasks.test.d.ts +1 -0
  53. package/dist/handlers/tasks.test.js +431 -0
  54. package/dist/handlers/types.d.ts +94 -0
  55. package/dist/handlers/types.js +1 -0
  56. package/dist/handlers/validation.d.ts +16 -0
  57. package/dist/handlers/validation.js +188 -0
  58. package/dist/index.d.ts +2 -0
  59. package/dist/index.js +2707 -0
  60. package/dist/knowledge.d.ts +6 -0
  61. package/dist/knowledge.js +121 -0
  62. package/dist/tools.d.ts +2 -0
  63. package/dist/tools.js +2498 -0
  64. package/dist/utils.d.ts +149 -0
  65. package/dist/utils.js +317 -0
  66. package/dist/utils.test.d.ts +1 -0
  67. package/dist/utils.test.js +532 -0
  68. package/dist/validators.d.ts +35 -0
  69. package/dist/validators.js +111 -0
  70. package/dist/validators.test.d.ts +1 -0
  71. package/dist/validators.test.js +176 -0
  72. package/package.json +44 -0
  73. package/src/cli.test.ts +442 -0
  74. package/src/cli.ts +439 -0
  75. package/src/handlers/__test-utils__.ts +217 -0
  76. package/src/handlers/blockers.test.ts +390 -0
  77. package/src/handlers/blockers.ts +110 -0
  78. package/src/handlers/bodies-of-work.test.ts +1276 -0
  79. package/src/handlers/bodies-of-work.ts +783 -0
  80. package/src/handlers/cost.test.ts +436 -0
  81. package/src/handlers/cost.ts +322 -0
  82. package/src/handlers/decisions.test.ts +401 -0
  83. package/src/handlers/decisions.ts +86 -0
  84. package/src/handlers/deployment.test.ts +516 -0
  85. package/src/handlers/deployment.ts +1289 -0
  86. package/src/handlers/discovery.test.ts +254 -0
  87. package/src/handlers/discovery.ts +969 -0
  88. package/src/handlers/fallback.test.ts +687 -0
  89. package/src/handlers/fallback.ts +260 -0
  90. package/src/handlers/findings.test.ts +565 -0
  91. package/src/handlers/findings.ts +153 -0
  92. package/src/handlers/ideas.test.ts +753 -0
  93. package/src/handlers/ideas.ts +247 -0
  94. package/src/handlers/index.ts +69 -0
  95. package/src/handlers/milestones.test.ts +584 -0
  96. package/src/handlers/milestones.ts +217 -0
  97. package/src/handlers/organizations.test.ts +997 -0
  98. package/src/handlers/organizations.ts +550 -0
  99. package/src/handlers/progress.test.ts +369 -0
  100. package/src/handlers/progress.ts +188 -0
  101. package/src/handlers/project.test.ts +562 -0
  102. package/src/handlers/project.ts +352 -0
  103. package/src/handlers/requests.test.ts +531 -0
  104. package/src/handlers/requests.ts +150 -0
  105. package/src/handlers/session.test.ts +459 -0
  106. package/src/handlers/session.ts +912 -0
  107. package/src/handlers/tasks.test.ts +602 -0
  108. package/src/handlers/tasks.ts +1393 -0
  109. package/src/handlers/types.ts +88 -0
  110. package/src/handlers/validation.test.ts +880 -0
  111. package/src/handlers/validation.ts +223 -0
  112. package/src/index.ts +3205 -0
  113. package/src/knowledge.ts +132 -0
  114. package/src/tmpclaude-0078-cwd +1 -0
  115. package/src/tmpclaude-0ee1-cwd +1 -0
  116. package/src/tmpclaude-2dd5-cwd +1 -0
  117. package/src/tmpclaude-344c-cwd +1 -0
  118. package/src/tmpclaude-3860-cwd +1 -0
  119. package/src/tmpclaude-4b63-cwd +1 -0
  120. package/src/tmpclaude-5c73-cwd +1 -0
  121. package/src/tmpclaude-5ee3-cwd +1 -0
  122. package/src/tmpclaude-6795-cwd +1 -0
  123. package/src/tmpclaude-709e-cwd +1 -0
  124. package/src/tmpclaude-9839-cwd +1 -0
  125. package/src/tmpclaude-d829-cwd +1 -0
  126. package/src/tmpclaude-e072-cwd +1 -0
  127. package/src/tmpclaude-f6ee-cwd +1 -0
  128. package/src/utils.test.ts +681 -0
  129. package/src/utils.ts +375 -0
  130. package/src/validators.test.ts +223 -0
  131. package/src/validators.ts +122 -0
  132. package/tmpclaude-0439-cwd +1 -0
  133. package/tmpclaude-132f-cwd +1 -0
  134. package/tmpclaude-15bb-cwd +1 -0
  135. package/tmpclaude-165a-cwd +1 -0
  136. package/tmpclaude-1ba9-cwd +1 -0
  137. package/tmpclaude-21a3-cwd +1 -0
  138. package/tmpclaude-2a38-cwd +1 -0
  139. package/tmpclaude-2adf-cwd +1 -0
  140. package/tmpclaude-2f56-cwd +1 -0
  141. package/tmpclaude-3626-cwd +1 -0
  142. package/tmpclaude-3727-cwd +1 -0
  143. package/tmpclaude-40bc-cwd +1 -0
  144. package/tmpclaude-436f-cwd +1 -0
  145. package/tmpclaude-4783-cwd +1 -0
  146. package/tmpclaude-4b6d-cwd +1 -0
  147. package/tmpclaude-4ba4-cwd +1 -0
  148. package/tmpclaude-51e6-cwd +1 -0
  149. package/tmpclaude-5ecf-cwd +1 -0
  150. package/tmpclaude-6f97-cwd +1 -0
  151. package/tmpclaude-7fb2-cwd +1 -0
  152. package/tmpclaude-825c-cwd +1 -0
  153. package/tmpclaude-8baf-cwd +1 -0
  154. package/tmpclaude-8d9f-cwd +1 -0
  155. package/tmpclaude-975c-cwd +1 -0
  156. package/tmpclaude-9983-cwd +1 -0
  157. package/tmpclaude-a045-cwd +1 -0
  158. package/tmpclaude-ac4a-cwd +1 -0
  159. package/tmpclaude-b593-cwd +1 -0
  160. package/tmpclaude-b891-cwd +1 -0
  161. package/tmpclaude-c032-cwd +1 -0
  162. package/tmpclaude-cf43-cwd +1 -0
  163. package/tmpclaude-d040-cwd +1 -0
  164. package/tmpclaude-dcdd-cwd +1 -0
  165. package/tmpclaude-dcee-cwd +1 -0
  166. package/tmpclaude-e16b-cwd +1 -0
  167. package/tmpclaude-ecd2-cwd +1 -0
  168. package/tmpclaude-f48d-cwd +1 -0
  169. package/tsconfig.json +16 -0
  170. package/vitest.config.ts +13 -0
@@ -0,0 +1,247 @@
1
+ /**
2
+ * Ideas Handlers
3
+ *
4
+ * Handles feature ideas tracking:
5
+ * - add_idea
6
+ * - update_idea
7
+ * - get_ideas
8
+ * - delete_idea
9
+ */
10
+
11
+ import type { Handler, HandlerRegistry } from './types.js';
12
+ import { validateRequired, validateUUID, validatePriority, validateEstimatedMinutes } from '../validators.js';
13
+
14
+ type IdeaStatus = 'raw' | 'exploring' | 'planned' | 'in_development' | 'shipped';
15
+
16
+ export const addIdea: Handler = async (args, ctx) => {
17
+ const { project_id, title, description, status } = args as {
18
+ project_id: string;
19
+ title: string;
20
+ description?: string;
21
+ status?: IdeaStatus;
22
+ };
23
+
24
+ validateRequired(project_id, 'project_id');
25
+ validateUUID(project_id, 'project_id');
26
+ validateRequired(title, 'title');
27
+
28
+ const { supabase, session } = ctx;
29
+
30
+ const { data, error } = await supabase
31
+ .from('ideas')
32
+ .insert({
33
+ project_id,
34
+ title,
35
+ description: description || null,
36
+ status: status || 'raw',
37
+ created_by: 'agent',
38
+ created_by_session_id: session.currentSessionId,
39
+ })
40
+ .select('id')
41
+ .single();
42
+
43
+ if (error) throw new Error(`Failed to add idea: ${error.message}`);
44
+
45
+ return { result: { success: true, idea_id: data.id, title } };
46
+ };
47
+
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');
59
+
60
+ const { supabase } = ctx;
61
+
62
+ // Get current idea status
63
+ const { data: existingIdea } = await supabase
64
+ .from('ideas')
65
+ .select('status')
66
+ .eq('id', idea_id)
67
+ .single();
68
+
69
+ if (!existingIdea) {
70
+ throw new Error(`Idea not found: ${idea_id}`);
71
+ }
72
+
73
+ // Build update object
74
+ const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };
75
+ if (title !== undefined) updates.title = title;
76
+ if (description !== undefined) updates.description = description;
77
+ if (doc_url !== undefined) updates.doc_url = doc_url;
78
+ if (status !== undefined) {
79
+ updates.status = status;
80
+ // Set planned_at when transitioning to planned status
81
+ if (status === 'planned' && existingIdea.status !== 'planned') {
82
+ updates.planned_at = new Date().toISOString();
83
+ }
84
+ }
85
+
86
+ const { error } = await supabase
87
+ .from('ideas')
88
+ .update(updates)
89
+ .eq('id', idea_id);
90
+
91
+ if (error) throw new Error(`Failed to update idea: ${error.message}`);
92
+
93
+ return { result: { success: true, idea_id } };
94
+ };
95
+
96
+ export const getIdeas: Handler = async (args, ctx) => {
97
+ const { project_id, status } = args as {
98
+ project_id: string;
99
+ status?: IdeaStatus;
100
+ };
101
+
102
+ validateRequired(project_id, 'project_id');
103
+ validateUUID(project_id, 'project_id');
104
+
105
+ const { supabase } = ctx;
106
+
107
+ let query = supabase
108
+ .from('ideas')
109
+ .select('id, title, description, status, doc_url')
110
+ .eq('project_id', project_id);
111
+
112
+ if (status) {
113
+ query = query.eq('status', status);
114
+ }
115
+
116
+ const { data, error } = await query.order('created_at', { ascending: false });
117
+
118
+ if (error) throw new Error(`Failed to fetch ideas: ${error.message}`);
119
+
120
+ return { result: { ideas: data || [] } };
121
+ };
122
+
123
+ export const deleteIdea: Handler = async (args, ctx) => {
124
+ const { idea_id } = args as { idea_id: string };
125
+
126
+ validateRequired(idea_id, 'idea_id');
127
+ validateUUID(idea_id, 'idea_id');
128
+
129
+ const { error } = await ctx.supabase
130
+ .from('ideas')
131
+ .delete()
132
+ .eq('id', idea_id);
133
+
134
+ if (error) throw new Error(`Failed to delete idea: ${error.message}`);
135
+
136
+ return { result: { success: true } };
137
+ };
138
+
139
+ export const convertIdeaToTask: Handler = async (args, ctx) => {
140
+ const { idea_id, priority = 3, estimated_minutes, update_status = true } = args as {
141
+ idea_id: string;
142
+ priority?: number;
143
+ estimated_minutes?: number;
144
+ update_status?: boolean;
145
+ };
146
+
147
+ validateRequired(idea_id, 'idea_id');
148
+ validateUUID(idea_id, 'idea_id');
149
+ validatePriority(priority);
150
+ validateEstimatedMinutes(estimated_minutes);
151
+
152
+ const { supabase, session } = ctx;
153
+ const currentSessionId = session.currentSessionId;
154
+
155
+ // Get the idea
156
+ const { data: idea, error: fetchError } = await supabase
157
+ .from('ideas')
158
+ .select('id, project_id, title, description, status, converted_to_task_id')
159
+ .eq('id', idea_id)
160
+ .single();
161
+
162
+ if (fetchError || !idea) {
163
+ throw new Error(`Idea not found: ${idea_id}`);
164
+ }
165
+
166
+ // Check if already converted
167
+ if (idea.converted_to_task_id) {
168
+ return {
169
+ result: {
170
+ success: false,
171
+ error: 'Idea has already been converted to a task',
172
+ existing_task_id: idea.converted_to_task_id,
173
+ hint: 'Use get_tasks to find the existing task',
174
+ },
175
+ };
176
+ }
177
+
178
+ // Create the task
179
+ const { data: task, error: taskError } = await supabase
180
+ .from('tasks')
181
+ .insert({
182
+ project_id: idea.project_id,
183
+ title: idea.title,
184
+ description: idea.description || `Converted from idea: ${idea.title}`,
185
+ priority,
186
+ estimated_minutes: estimated_minutes || null,
187
+ created_by: 'agent',
188
+ created_by_session_id: currentSessionId,
189
+ })
190
+ .select('id, title')
191
+ .single();
192
+
193
+ if (taskError || !task) {
194
+ throw new Error(`Failed to create task: ${taskError?.message}`);
195
+ }
196
+
197
+ // Update the idea with the task reference and optionally update status
198
+ const ideaUpdates: Record<string, unknown> = {
199
+ converted_to_task_id: task.id,
200
+ updated_at: new Date().toISOString(),
201
+ };
202
+
203
+ if (update_status && idea.status !== 'shipped') {
204
+ ideaUpdates.status = 'in_development';
205
+ }
206
+
207
+ const { error: updateError } = await supabase
208
+ .from('ideas')
209
+ .update(ideaUpdates)
210
+ .eq('id', idea_id);
211
+
212
+ if (updateError) {
213
+ // Log but don't fail - task was created successfully
214
+ console.error(`Failed to update idea after conversion: ${updateError.message}`);
215
+ }
216
+
217
+ // Log progress
218
+ await supabase.from('progress_logs').insert({
219
+ project_id: idea.project_id,
220
+ task_id: task.id,
221
+ summary: `Converted idea "${idea.title}" to task`,
222
+ created_by: 'agent',
223
+ created_by_session_id: currentSessionId,
224
+ });
225
+
226
+ return {
227
+ result: {
228
+ success: true,
229
+ task_id: task.id,
230
+ task_title: task.title,
231
+ idea_id: idea.id,
232
+ idea_status: update_status ? 'in_development' : idea.status,
233
+ message: `Created task from idea. Start with: update_task(task_id: "${task.id}", status: "in_progress")`,
234
+ },
235
+ };
236
+ };
237
+
238
+ /**
239
+ * Ideas handlers registry
240
+ */
241
+ export const ideaHandlers: HandlerRegistry = {
242
+ add_idea: addIdea,
243
+ update_idea: updateIdea,
244
+ get_ideas: getIdeas,
245
+ delete_idea: deleteIdea,
246
+ convert_idea_to_task: convertIdeaToTask,
247
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * MCP Server Handlers
3
+ *
4
+ * This module exports all tool handlers organized by category.
5
+ * Each handler receives a HandlerContext and returns a HandlerResult.
6
+ */
7
+
8
+ export * from './types.js';
9
+ export * from './milestones.js';
10
+ export * from './session.js';
11
+ export * from './ideas.js';
12
+ export * from './findings.js';
13
+ export * from './blockers.js';
14
+ export * from './decisions.js';
15
+ export * from './progress.js';
16
+ export * from './requests.js';
17
+ export * from './tasks.js';
18
+ export * from './project.js';
19
+ export * from './deployment.js';
20
+ export * from './validation.js';
21
+ export * from './fallback.js';
22
+ export * from './bodies-of-work.js';
23
+ export * from './discovery.js';
24
+ export * from './organizations.js';
25
+ export * from './cost.js';
26
+
27
+ import type { HandlerRegistry } from './types.js';
28
+ import { milestoneHandlers } from './milestones.js';
29
+ import { sessionHandlers } from './session.js';
30
+ import { ideaHandlers } from './ideas.js';
31
+ import { findingHandlers } from './findings.js';
32
+ import { blockerHandlers } from './blockers.js';
33
+ import { decisionHandlers } from './decisions.js';
34
+ import { progressHandlers } from './progress.js';
35
+ import { requestHandlers } from './requests.js';
36
+ import { taskHandlers } from './tasks.js';
37
+ import { projectHandlers } from './project.js';
38
+ import { deploymentHandlers } from './deployment.js';
39
+ import { validationHandlers } from './validation.js';
40
+ import { fallbackHandlers } from './fallback.js';
41
+ import { bodiesOfWorkHandlers } from './bodies-of-work.js';
42
+ import { discoveryHandlers } from './discovery.js';
43
+ import { organizationHandlers } from './organizations.js';
44
+ import { costHandlers } from './cost.js';
45
+
46
+ /**
47
+ * Build the complete handler registry from all modules
48
+ */
49
+ export function buildHandlerRegistry(): HandlerRegistry {
50
+ return {
51
+ ...milestoneHandlers,
52
+ ...sessionHandlers,
53
+ ...ideaHandlers,
54
+ ...findingHandlers,
55
+ ...blockerHandlers,
56
+ ...decisionHandlers,
57
+ ...progressHandlers,
58
+ ...requestHandlers,
59
+ ...taskHandlers,
60
+ ...projectHandlers,
61
+ ...deploymentHandlers,
62
+ ...validationHandlers,
63
+ ...fallbackHandlers,
64
+ ...bodiesOfWorkHandlers,
65
+ ...discoveryHandlers,
66
+ ...organizationHandlers,
67
+ ...costHandlers,
68
+ };
69
+ }