@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,254 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import type { SupabaseClient } from '@supabase/supabase-js';
3
+ import type { HandlerContext, TokenUsage } from './types.js';
4
+ import { discoverTools, getToolInfo } from './discovery.js';
5
+
6
+ // ============================================================================
7
+ // Test Utilities
8
+ // ============================================================================
9
+
10
+ function createMockSupabase() {
11
+ return {} as unknown as SupabaseClient;
12
+ }
13
+
14
+ function createMockContext(supabase: SupabaseClient): HandlerContext {
15
+ const defaultTokenUsage: TokenUsage = {
16
+ callCount: 5,
17
+ totalTokens: 2500,
18
+ byTool: {},
19
+ };
20
+
21
+ return {
22
+ supabase,
23
+ auth: { userId: 'user-123', apiKeyId: 'api-key-123' },
24
+ session: {
25
+ instanceId: 'instance-abc',
26
+ currentSessionId: 'session-123',
27
+ currentPersona: 'Wave',
28
+ tokenUsage: defaultTokenUsage,
29
+ },
30
+ updateSession: vi.fn(),
31
+ };
32
+ }
33
+
34
+ // ============================================================================
35
+ // discoverTools Tests
36
+ // ============================================================================
37
+
38
+ describe('discoverTools', () => {
39
+ it('should return all categories when no category specified', async () => {
40
+ const supabase = createMockSupabase();
41
+ const ctx = createMockContext(supabase);
42
+
43
+ const result = await discoverTools({}, ctx);
44
+ const res = result.result as { categories: unknown[]; total_tools: number };
45
+
46
+ expect(res.categories).toBeDefined();
47
+ expect(Array.isArray(res.categories)).toBe(true);
48
+ expect(res.categories.length).toBeGreaterThan(0);
49
+ expect(res.total_tools).toBeGreaterThan(0);
50
+ });
51
+
52
+ it('should return category info with tool counts', async () => {
53
+ const supabase = createMockSupabase();
54
+ const ctx = createMockContext(supabase);
55
+
56
+ const result = await discoverTools({}, ctx);
57
+ const res = result.result as { categories: { name: string; description: string; tool_count: number }[] };
58
+
59
+ const category = res.categories[0];
60
+ expect(category.name).toBeDefined();
61
+ expect(category.description).toBeDefined();
62
+ expect(category.tool_count).toBeGreaterThan(0);
63
+ });
64
+
65
+ it('should return tools for specific category', async () => {
66
+ const supabase = createMockSupabase();
67
+ const ctx = createMockContext(supabase);
68
+
69
+ const result = await discoverTools({ category: 'session' }, ctx);
70
+ const res = result.result as { category: string; description: string; tools: unknown[] };
71
+
72
+ expect(res.category).toBe('session');
73
+ expect(res.description).toBeDefined();
74
+ expect(res.tools).toBeDefined();
75
+ expect(Array.isArray(res.tools)).toBe(true);
76
+ });
77
+
78
+ it('should return tools with name and brief for specific category', async () => {
79
+ const supabase = createMockSupabase();
80
+ const ctx = createMockContext(supabase);
81
+
82
+ const result = await discoverTools({ category: 'tasks' }, ctx);
83
+ const res = result.result as { tools: { name: string; brief: string }[] };
84
+
85
+ expect(res.tools.length).toBeGreaterThan(0);
86
+ const tool = res.tools[0];
87
+ expect(tool.name).toBeDefined();
88
+ expect(tool.brief).toBeDefined();
89
+ });
90
+
91
+ it('should return error for unknown category', async () => {
92
+ const supabase = createMockSupabase();
93
+ const ctx = createMockContext(supabase);
94
+
95
+ const result = await discoverTools({ category: 'nonexistent' }, ctx);
96
+ const res = result.result as { error: string; available: string[] };
97
+
98
+ expect(res.error).toContain('Unknown category');
99
+ expect(res.available).toBeDefined();
100
+ expect(Array.isArray(res.available)).toBe(true);
101
+ });
102
+
103
+ it('should include session category', async () => {
104
+ const supabase = createMockSupabase();
105
+ const ctx = createMockContext(supabase);
106
+
107
+ const result = await discoverTools({}, ctx);
108
+ const res = result.result as { categories: { name: string }[] };
109
+
110
+ const categoryNames = res.categories.map((c) => c.name);
111
+ expect(categoryNames).toContain('session');
112
+ });
113
+
114
+ it('should include tasks category', async () => {
115
+ const supabase = createMockSupabase();
116
+ const ctx = createMockContext(supabase);
117
+
118
+ const result = await discoverTools({}, ctx);
119
+ const res = result.result as { categories: { name: string }[] };
120
+
121
+ const categoryNames = res.categories.map((c) => c.name);
122
+ expect(categoryNames).toContain('tasks');
123
+ });
124
+
125
+ it('should include deployment category', async () => {
126
+ const supabase = createMockSupabase();
127
+ const ctx = createMockContext(supabase);
128
+
129
+ const result = await discoverTools({}, ctx);
130
+ const res = result.result as { categories: { name: string }[] };
131
+
132
+ const categoryNames = res.categories.map((c) => c.name);
133
+ expect(categoryNames).toContain('deployment');
134
+ });
135
+
136
+ it('should include usage hint in response', async () => {
137
+ const supabase = createMockSupabase();
138
+ const ctx = createMockContext(supabase);
139
+
140
+ const result = await discoverTools({}, ctx);
141
+ const res = result.result as { usage: string };
142
+
143
+ expect(res.usage).toBeDefined();
144
+ expect(res.usage).toContain('discover_tools');
145
+ expect(res.usage).toContain('get_tool_info');
146
+ });
147
+ });
148
+
149
+ // ============================================================================
150
+ // getToolInfo Tests
151
+ // ============================================================================
152
+
153
+ describe('getToolInfo', () => {
154
+ it('should return error for missing tool_name', async () => {
155
+ const supabase = createMockSupabase();
156
+ const ctx = createMockContext(supabase);
157
+
158
+ const result = await getToolInfo({}, ctx);
159
+ const res = result.result as { error: string };
160
+
161
+ expect(res.error).toBe('tool_name is required');
162
+ });
163
+
164
+ it('should return error for unknown tool', async () => {
165
+ const supabase = createMockSupabase();
166
+ const ctx = createMockContext(supabase);
167
+
168
+ const result = await getToolInfo({ tool_name: 'nonexistent_tool' }, ctx);
169
+ const res = result.result as { error: string; hint: string };
170
+
171
+ expect(res.error).toContain('Unknown tool');
172
+ expect(res.hint).toContain('discover_tools');
173
+ });
174
+
175
+ it('should return info for start_work_session', async () => {
176
+ const supabase = createMockSupabase();
177
+ const ctx = createMockContext(supabase);
178
+
179
+ const result = await getToolInfo({ tool_name: 'start_work_session' }, ctx);
180
+ const res = result.result as { tool: string; info: string };
181
+
182
+ expect(res.tool).toBe('start_work_session');
183
+ expect(res.info).toBeDefined();
184
+ expect(res.info).toContain('start_work_session');
185
+ });
186
+
187
+ it('should return info for add_task', async () => {
188
+ const supabase = createMockSupabase();
189
+ const ctx = createMockContext(supabase);
190
+
191
+ const result = await getToolInfo({ tool_name: 'add_task' }, ctx);
192
+ const res = result.result as { tool: string; info: string };
193
+
194
+ expect(res.tool).toBe('add_task');
195
+ expect(res.info).toBeDefined();
196
+ expect(res.info).toContain('task');
197
+ });
198
+
199
+ it('should return info for complete_task', async () => {
200
+ const supabase = createMockSupabase();
201
+ const ctx = createMockContext(supabase);
202
+
203
+ const result = await getToolInfo({ tool_name: 'complete_task' }, ctx);
204
+ const res = result.result as { tool: string; info: string };
205
+
206
+ expect(res.tool).toBe('complete_task');
207
+ expect(res.info).toBeDefined();
208
+ });
209
+
210
+ it('should return info for request_deployment', async () => {
211
+ const supabase = createMockSupabase();
212
+ const ctx = createMockContext(supabase);
213
+
214
+ const result = await getToolInfo({ tool_name: 'request_deployment' }, ctx);
215
+ const res = result.result as { tool: string; info: string };
216
+
217
+ expect(res.tool).toBe('request_deployment');
218
+ expect(res.info).toBeDefined();
219
+ expect(res.info).toContain('deployment');
220
+ });
221
+
222
+ it('should return info with parameters section', async () => {
223
+ const supabase = createMockSupabase();
224
+ const ctx = createMockContext(supabase);
225
+
226
+ const result = await getToolInfo({ tool_name: 'add_task' }, ctx);
227
+ const res = result.result as { info: string };
228
+
229
+ expect(res.info).toContain('Parameters');
230
+ });
231
+
232
+ it('should return info for get_help', async () => {
233
+ const supabase = createMockSupabase();
234
+ const ctx = createMockContext(supabase);
235
+
236
+ const result = await getToolInfo({ tool_name: 'get_help' }, ctx);
237
+ const res = result.result as { tool: string; info: string };
238
+
239
+ expect(res.tool).toBe('get_help');
240
+ expect(res.info).toBeDefined();
241
+ expect(res.info).toContain('topic');
242
+ });
243
+
244
+ it('should return info for discover_tools', async () => {
245
+ const supabase = createMockSupabase();
246
+ const ctx = createMockContext(supabase);
247
+
248
+ const result = await getToolInfo({ tool_name: 'discover_tools' }, ctx);
249
+ const res = result.result as { tool: string; info: string };
250
+
251
+ expect(res.tool).toBe('discover_tools');
252
+ expect(res.info).toBeDefined();
253
+ });
254
+ });