@vibescope/mcp-server 0.0.1 → 0.1.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.
- package/README.md +113 -98
- package/dist/api-client.d.ts +1114 -0
- package/dist/api-client.js +698 -0
- package/dist/cli.d.ts +1 -6
- package/dist/cli.js +39 -240
- package/dist/config/tool-categories.d.ts +31 -0
- package/dist/config/tool-categories.js +253 -0
- package/dist/handlers/blockers.js +57 -58
- package/dist/handlers/bodies-of-work.d.ts +2 -0
- package/dist/handlers/bodies-of-work.js +106 -476
- package/dist/handlers/cost.d.ts +1 -0
- package/dist/handlers/cost.js +35 -113
- package/dist/handlers/decisions.d.ts +2 -0
- package/dist/handlers/decisions.js +28 -27
- package/dist/handlers/deployment.js +112 -828
- package/dist/handlers/discovery.js +31 -0
- package/dist/handlers/fallback.d.ts +2 -0
- package/dist/handlers/fallback.js +39 -134
- package/dist/handlers/findings.js +43 -67
- package/dist/handlers/git-issues.d.ts +9 -13
- package/dist/handlers/git-issues.js +80 -225
- package/dist/handlers/ideas.d.ts +3 -0
- package/dist/handlers/ideas.js +53 -134
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +6 -0
- package/dist/handlers/milestones.d.ts +2 -0
- package/dist/handlers/milestones.js +51 -98
- package/dist/handlers/organizations.js +79 -275
- package/dist/handlers/progress.d.ts +2 -0
- package/dist/handlers/progress.js +25 -123
- package/dist/handlers/project.js +42 -221
- package/dist/handlers/requests.d.ts +2 -0
- package/dist/handlers/requests.js +23 -83
- package/dist/handlers/session.js +99 -585
- package/dist/handlers/sprints.d.ts +32 -0
- package/dist/handlers/sprints.js +274 -0
- package/dist/handlers/tasks.d.ts +7 -10
- package/dist/handlers/tasks.js +230 -900
- package/dist/handlers/tool-docs.d.ts +8 -0
- package/dist/handlers/tool-docs.js +657 -0
- package/dist/handlers/types.d.ts +11 -3
- package/dist/handlers/validation.d.ts +1 -1
- package/dist/handlers/validation.js +26 -153
- package/dist/index.js +473 -160
- package/dist/knowledge.js +106 -9
- package/dist/tools.js +4 -0
- package/dist/validators.d.ts +21 -0
- package/dist/validators.js +91 -0
- package/package.json +2 -3
- package/src/api-client.ts +1752 -0
- package/src/cli.test.ts +128 -302
- package/src/cli.ts +41 -285
- package/src/handlers/__test-setup__.ts +210 -0
- package/src/handlers/__test-utils__.ts +4 -134
- package/src/handlers/blockers.test.ts +114 -124
- package/src/handlers/blockers.ts +68 -70
- package/src/handlers/bodies-of-work.test.ts +236 -831
- package/src/handlers/bodies-of-work.ts +194 -525
- package/src/handlers/cost.test.ts +149 -113
- package/src/handlers/cost.ts +44 -132
- package/src/handlers/decisions.test.ts +111 -209
- package/src/handlers/decisions.ts +35 -27
- package/src/handlers/deployment.test.ts +193 -239
- package/src/handlers/deployment.ts +140 -895
- package/src/handlers/discovery.test.ts +20 -67
- package/src/handlers/discovery.ts +32 -0
- package/src/handlers/fallback.test.ts +128 -361
- package/src/handlers/fallback.ts +62 -148
- package/src/handlers/findings.test.ts +127 -345
- package/src/handlers/findings.ts +49 -66
- package/src/handlers/git-issues.test.ts +623 -0
- package/src/handlers/git-issues.ts +174 -0
- package/src/handlers/ideas.test.ts +229 -343
- package/src/handlers/ideas.ts +69 -143
- package/src/handlers/index.ts +6 -0
- package/src/handlers/milestones.test.ts +167 -281
- package/src/handlers/milestones.ts +54 -93
- package/src/handlers/organizations.test.ts +275 -467
- package/src/handlers/organizations.ts +84 -294
- package/src/handlers/progress.test.ts +112 -218
- package/src/handlers/progress.ts +29 -142
- package/src/handlers/project.test.ts +203 -226
- package/src/handlers/project.ts +48 -238
- package/src/handlers/requests.test.ts +74 -342
- package/src/handlers/requests.ts +25 -83
- package/src/handlers/session.test.ts +241 -206
- package/src/handlers/session.ts +110 -657
- package/src/handlers/sprints.test.ts +711 -0
- package/src/handlers/sprints.ts +497 -0
- package/src/handlers/tasks.test.ts +608 -353
- package/src/handlers/tasks.ts +248 -1025
- package/src/handlers/types.ts +12 -4
- package/src/handlers/validation.test.ts +189 -572
- package/src/handlers/validation.ts +29 -166
- package/src/index.ts +473 -184
- package/src/knowledge.ts +107 -9
- package/src/tools.ts +2506 -0
- package/src/validators.test.ts +223 -223
- package/src/validators.ts +127 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +14 -13
- package/dist/cli.test.d.ts +0 -1
- package/dist/cli.test.js +0 -367
- package/dist/handlers/__test-utils__.d.ts +0 -72
- package/dist/handlers/__test-utils__.js +0 -176
- package/dist/handlers/checkouts.d.ts +0 -37
- package/dist/handlers/checkouts.js +0 -377
- package/dist/handlers/knowledge-query.d.ts +0 -22
- package/dist/handlers/knowledge-query.js +0 -253
- package/dist/handlers/knowledge.d.ts +0 -12
- package/dist/handlers/knowledge.js +0 -108
- package/dist/handlers/roles.d.ts +0 -30
- package/dist/handlers/roles.js +0 -281
- package/dist/handlers/tasks.test.d.ts +0 -1
- package/dist/handlers/tasks.test.js +0 -431
- package/dist/utils.test.d.ts +0 -1
- package/dist/utils.test.js +0 -532
- package/dist/validators.test.d.ts +0 -1
- package/dist/validators.test.js +0 -176
- package/src/tmpclaude-0078-cwd +0 -1
- package/src/tmpclaude-0ee1-cwd +0 -1
- package/src/tmpclaude-2dd5-cwd +0 -1
- package/src/tmpclaude-344c-cwd +0 -1
- package/src/tmpclaude-3860-cwd +0 -1
- package/src/tmpclaude-4b63-cwd +0 -1
- package/src/tmpclaude-5c73-cwd +0 -1
- package/src/tmpclaude-5ee3-cwd +0 -1
- package/src/tmpclaude-6795-cwd +0 -1
- package/src/tmpclaude-709e-cwd +0 -1
- package/src/tmpclaude-9839-cwd +0 -1
- package/src/tmpclaude-d829-cwd +0 -1
- package/src/tmpclaude-e072-cwd +0 -1
- package/src/tmpclaude-f6ee-cwd +0 -1
- package/tmpclaude-0439-cwd +0 -1
- package/tmpclaude-132f-cwd +0 -1
- package/tmpclaude-15bb-cwd +0 -1
- package/tmpclaude-165a-cwd +0 -1
- package/tmpclaude-1ba9-cwd +0 -1
- package/tmpclaude-21a3-cwd +0 -1
- package/tmpclaude-2a38-cwd +0 -1
- package/tmpclaude-2adf-cwd +0 -1
- package/tmpclaude-2f56-cwd +0 -1
- package/tmpclaude-3626-cwd +0 -1
- package/tmpclaude-3727-cwd +0 -1
- package/tmpclaude-40bc-cwd +0 -1
- package/tmpclaude-436f-cwd +0 -1
- package/tmpclaude-4783-cwd +0 -1
- package/tmpclaude-4b6d-cwd +0 -1
- package/tmpclaude-4ba4-cwd +0 -1
- package/tmpclaude-51e6-cwd +0 -1
- package/tmpclaude-5ecf-cwd +0 -1
- package/tmpclaude-6f97-cwd +0 -1
- package/tmpclaude-7fb2-cwd +0 -1
- package/tmpclaude-825c-cwd +0 -1
- package/tmpclaude-8baf-cwd +0 -1
- package/tmpclaude-8d9f-cwd +0 -1
- package/tmpclaude-975c-cwd +0 -1
- package/tmpclaude-9983-cwd +0 -1
- package/tmpclaude-a045-cwd +0 -1
- package/tmpclaude-ac4a-cwd +0 -1
- package/tmpclaude-b593-cwd +0 -1
- package/tmpclaude-b891-cwd +0 -1
- package/tmpclaude-c032-cwd +0 -1
- package/tmpclaude-cf43-cwd +0 -1
- package/tmpclaude-d040-cwd +0 -1
- package/tmpclaude-dcdd-cwd +0 -1
- package/tmpclaude-dcee-cwd +0 -1
- package/tmpclaude-e16b-cwd +0 -1
- package/tmpclaude-ecd2-cwd +0 -1
- package/tmpclaude-f48d-cwd +0 -1
package/dist/index.js
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
-
import { createClient } from '@supabase/supabase-js';
|
|
6
5
|
import { randomUUID } from 'crypto';
|
|
6
|
+
import { initApiClient, getApiClient } from './api-client.js';
|
|
7
7
|
import { ValidationError, } from './validators.js';
|
|
8
8
|
import { RateLimiter, } from './utils.js';
|
|
9
|
-
import { hashApiKey } from './cli.js';
|
|
10
9
|
import { buildHandlerRegistry } from './handlers/index.js';
|
|
11
10
|
// ============================================================================
|
|
12
11
|
// Agent Instance Tracking
|
|
@@ -17,6 +16,8 @@ const INSTANCE_ID = randomUUID();
|
|
|
17
16
|
let currentSessionId = null;
|
|
18
17
|
// Assigned persona for this agent instance
|
|
19
18
|
let currentPersona = null;
|
|
19
|
+
// Current role for this agent instance
|
|
20
|
+
let currentRole = null;
|
|
20
21
|
let sessionTokenUsage = {
|
|
21
22
|
callCount: 0,
|
|
22
23
|
totalTokens: 0,
|
|
@@ -152,158 +153,29 @@ Be mindful of token costs - every tool call has a cost.
|
|
|
152
153
|
// ============================================================================
|
|
153
154
|
// Configuration
|
|
154
155
|
// ============================================================================
|
|
155
|
-
// Default Supabase URL for Vibescope production instance
|
|
156
|
-
const DEFAULT_SUPABASE_URL = 'https://uuneucmuubpgswvfijwd.supabase.co';
|
|
157
|
-
const SUPABASE_URL = process.env.SUPABASE_URL || process.env.PUBLIC_SUPABASE_URL || DEFAULT_SUPABASE_URL;
|
|
158
|
-
const SUPABASE_SERVICE_KEY = process.env.SUPABASE_SERVICE_KEY;
|
|
159
156
|
const API_KEY = process.env.VIBESCOPE_API_KEY;
|
|
160
|
-
if (!SUPABASE_SERVICE_KEY) {
|
|
161
|
-
console.error('Missing required environment variable: SUPABASE_SERVICE_KEY');
|
|
162
|
-
process.exit(1);
|
|
163
|
-
}
|
|
164
157
|
if (!API_KEY) {
|
|
165
158
|
console.error('Missing required environment variable: VIBESCOPE_API_KEY');
|
|
166
159
|
process.exit(1);
|
|
167
160
|
}
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
// ============================================================================
|
|
171
|
-
// Using untyped client for MCP server - data validation happens at runtime
|
|
172
|
-
const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_KEY);
|
|
161
|
+
// Initialize the API client
|
|
162
|
+
initApiClient({ apiKey: API_KEY });
|
|
173
163
|
// ============================================================================
|
|
174
164
|
// Authentication
|
|
175
165
|
// ============================================================================
|
|
176
|
-
async function validateApiKey(
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
.select('id, user_id, organization_id, scope, is_valid')
|
|
181
|
-
.eq('key_hash', keyHash)
|
|
182
|
-
.single();
|
|
183
|
-
if (error || !data) {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
// Check if key has been invalidated (e.g., user left org)
|
|
187
|
-
if (data.is_valid === false) {
|
|
166
|
+
async function validateApiKey() {
|
|
167
|
+
const apiClient = getApiClient();
|
|
168
|
+
const response = await apiClient.validateAuth();
|
|
169
|
+
if (!response.ok || !response.data?.valid) {
|
|
188
170
|
return null;
|
|
189
171
|
}
|
|
190
|
-
// For org-scoped keys, verify user is still a member
|
|
191
|
-
if (data.scope === 'organization' && data.organization_id) {
|
|
192
|
-
const { data: member } = await supabase
|
|
193
|
-
.from('organization_members')
|
|
194
|
-
.select('role')
|
|
195
|
-
.eq('organization_id', data.organization_id)
|
|
196
|
-
.eq('user_id', data.user_id)
|
|
197
|
-
.single();
|
|
198
|
-
if (!member) {
|
|
199
|
-
// User is no longer a member, invalidate the key
|
|
200
|
-
await supabase
|
|
201
|
-
.from('api_keys')
|
|
202
|
-
.update({ is_valid: false })
|
|
203
|
-
.eq('id', data.id);
|
|
204
|
-
return null;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
// Update last_used_at
|
|
208
|
-
await supabase
|
|
209
|
-
.from('api_keys')
|
|
210
|
-
.update({ last_used_at: new Date().toISOString() })
|
|
211
|
-
.eq('id', data.id);
|
|
212
172
|
return {
|
|
213
|
-
userId: data.user_id,
|
|
214
|
-
apiKeyId: data.
|
|
215
|
-
|
|
216
|
-
scope: data.scope || 'personal',
|
|
173
|
+
userId: response.data.user_id,
|
|
174
|
+
apiKeyId: response.data.api_key_id,
|
|
175
|
+
scope: 'personal', // API handles authorization, scope not needed locally
|
|
217
176
|
};
|
|
218
177
|
}
|
|
219
178
|
// ============================================================================
|
|
220
|
-
// Session Status Checking (Multi-Agent Coordination)
|
|
221
|
-
// ============================================================================
|
|
222
|
-
/**
|
|
223
|
-
* Check if an agent session is active or stale.
|
|
224
|
-
* A session is considered stale if:
|
|
225
|
-
* - It doesn't exist (orphaned reference)
|
|
226
|
-
* - Its status is 'disconnected'
|
|
227
|
-
* - Its last_synced_at is older than 5 minutes
|
|
228
|
-
*/
|
|
229
|
-
async function checkSessionStatus(sessionId) {
|
|
230
|
-
const { data: session } = await supabase
|
|
231
|
-
.from('agent_sessions')
|
|
232
|
-
.select('id, status, last_synced_at, agent_name, instance_id')
|
|
233
|
-
.eq('id', sessionId)
|
|
234
|
-
.single();
|
|
235
|
-
if (!session) {
|
|
236
|
-
return { exists: false, isActive: false };
|
|
237
|
-
}
|
|
238
|
-
const lastSync = new Date(session.last_synced_at).getTime();
|
|
239
|
-
const fiveMinutesAgo = Date.now() - 5 * 60 * 1000;
|
|
240
|
-
const isActive = session.status !== 'disconnected' && lastSync > fiveMinutesAgo;
|
|
241
|
-
return {
|
|
242
|
-
exists: true,
|
|
243
|
-
isActive,
|
|
244
|
-
agentName: session.agent_name || `Agent ${session.instance_id?.slice(0, 8) || sessionId.slice(0, 8)}`,
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
// ============================================================================
|
|
248
|
-
// User Updates Tracking
|
|
249
|
-
// ============================================================================
|
|
250
|
-
async function getUserUpdates(auth, projectId) {
|
|
251
|
-
// Get session's last_synced_at - prefer currentSessionId for accuracy
|
|
252
|
-
let lastSyncedAt;
|
|
253
|
-
if (currentSessionId) {
|
|
254
|
-
const { data: session } = await supabase
|
|
255
|
-
.from('agent_sessions')
|
|
256
|
-
.select('last_synced_at')
|
|
257
|
-
.eq('id', currentSessionId)
|
|
258
|
-
.single();
|
|
259
|
-
lastSyncedAt = session?.last_synced_at || new Date(0).toISOString();
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
const { data: session } = await supabase
|
|
263
|
-
.from('agent_sessions')
|
|
264
|
-
.select('last_synced_at')
|
|
265
|
-
.eq('api_key_id', auth.apiKeyId)
|
|
266
|
-
.eq('project_id', projectId)
|
|
267
|
-
.single();
|
|
268
|
-
lastSyncedAt = session?.last_synced_at || new Date(0).toISOString();
|
|
269
|
-
}
|
|
270
|
-
// Fetch user-created items since last sync (limit to 5 each for context efficiency)
|
|
271
|
-
const [tasksResult, blockersResult, ideasResult] = await Promise.all([
|
|
272
|
-
supabase
|
|
273
|
-
.from('tasks')
|
|
274
|
-
.select('id, title, created_at')
|
|
275
|
-
.eq('project_id', projectId)
|
|
276
|
-
.eq('created_by', 'user')
|
|
277
|
-
.gt('created_at', lastSyncedAt)
|
|
278
|
-
.order('created_at', { ascending: false })
|
|
279
|
-
.limit(5),
|
|
280
|
-
supabase
|
|
281
|
-
.from('blockers')
|
|
282
|
-
.select('id, description, created_at')
|
|
283
|
-
.eq('project_id', projectId)
|
|
284
|
-
.eq('created_by', 'user')
|
|
285
|
-
.gt('created_at', lastSyncedAt)
|
|
286
|
-
.order('created_at', { ascending: false })
|
|
287
|
-
.limit(5),
|
|
288
|
-
supabase
|
|
289
|
-
.from('ideas')
|
|
290
|
-
.select('id, title, created_at')
|
|
291
|
-
.eq('project_id', projectId)
|
|
292
|
-
.eq('created_by', 'user')
|
|
293
|
-
.gt('created_at', lastSyncedAt)
|
|
294
|
-
.order('created_at', { ascending: false })
|
|
295
|
-
.limit(5),
|
|
296
|
-
]);
|
|
297
|
-
const tasks = tasksResult.data || [];
|
|
298
|
-
const blockers = blockersResult.data || [];
|
|
299
|
-
const ideas = ideasResult.data || [];
|
|
300
|
-
// Return undefined if no new updates (saves context window space)
|
|
301
|
-
if (tasks.length === 0 && blockers.length === 0 && ideas.length === 0) {
|
|
302
|
-
return undefined;
|
|
303
|
-
}
|
|
304
|
-
return { tasks, blockers, ideas };
|
|
305
|
-
}
|
|
306
|
-
// ============================================================================
|
|
307
179
|
// Tool Definitions
|
|
308
180
|
// ============================================================================
|
|
309
181
|
const tools = [
|
|
@@ -343,7 +215,7 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
343
215
|
properties: {
|
|
344
216
|
topic: {
|
|
345
217
|
type: 'string',
|
|
346
|
-
enum: ['getting_started', 'tasks', 'validation', 'deployment', 'git', 'blockers', 'milestones', 'fallback', 'session', 'tokens', 'topics'],
|
|
218
|
+
enum: ['getting_started', 'tasks', 'validation', 'deployment', 'git', 'blockers', 'milestones', 'fallback', 'session', 'tokens', 'sprints', 'topics'],
|
|
347
219
|
description: 'Help topic. Use "topics" to list all available.',
|
|
348
220
|
},
|
|
349
221
|
},
|
|
@@ -669,6 +541,14 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
669
541
|
type: 'number',
|
|
670
542
|
description: 'Max number of tasks to return (default 50)',
|
|
671
543
|
},
|
|
544
|
+
offset: {
|
|
545
|
+
type: 'number',
|
|
546
|
+
description: 'Number of tasks to skip for pagination (default 0)',
|
|
547
|
+
},
|
|
548
|
+
search_query: {
|
|
549
|
+
type: 'string',
|
|
550
|
+
description: 'Search tasks by title',
|
|
551
|
+
},
|
|
672
552
|
include_subtasks: {
|
|
673
553
|
type: 'boolean',
|
|
674
554
|
description: 'Include subtasks in results (default false). Use get_subtasks for subtasks of a specific task.',
|
|
@@ -724,6 +604,11 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
724
604
|
type: 'boolean',
|
|
725
605
|
description: 'When true, this task blocks all other work until complete (used for deployment finalization)',
|
|
726
606
|
},
|
|
607
|
+
task_type: {
|
|
608
|
+
type: 'string',
|
|
609
|
+
enum: ['frontend', 'backend', 'database', 'mcp', 'testing', 'docs', 'infra', 'other'],
|
|
610
|
+
description: 'Task category for visual grouping (frontend, backend, database, mcp, testing, docs, infra, other)',
|
|
611
|
+
},
|
|
727
612
|
},
|
|
728
613
|
required: ['project_id', 'title'],
|
|
729
614
|
},
|
|
@@ -768,6 +653,11 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
768
653
|
type: 'string',
|
|
769
654
|
description: 'Git branch associated with this task',
|
|
770
655
|
},
|
|
656
|
+
task_type: {
|
|
657
|
+
type: 'string',
|
|
658
|
+
enum: ['frontend', 'backend', 'database', 'mcp', 'testing', 'docs', 'infra', 'other'],
|
|
659
|
+
description: 'Task category (frontend, backend, database, mcp, testing, docs, infra, other)',
|
|
660
|
+
},
|
|
771
661
|
},
|
|
772
662
|
required: ['task_id'],
|
|
773
663
|
},
|
|
@@ -867,6 +757,18 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
867
757
|
enum: ['open', 'resolved'],
|
|
868
758
|
description: 'Filter by status (default: open)',
|
|
869
759
|
},
|
|
760
|
+
limit: {
|
|
761
|
+
type: 'number',
|
|
762
|
+
description: 'Max number of blockers to return (default 50, max 200)',
|
|
763
|
+
},
|
|
764
|
+
offset: {
|
|
765
|
+
type: 'number',
|
|
766
|
+
description: 'Number of blockers to skip for pagination (default 0)',
|
|
767
|
+
},
|
|
768
|
+
search_query: {
|
|
769
|
+
type: 'string',
|
|
770
|
+
description: 'Search blockers by description',
|
|
771
|
+
},
|
|
870
772
|
},
|
|
871
773
|
required: ['project_id'],
|
|
872
774
|
},
|
|
@@ -912,6 +814,18 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
912
814
|
type: 'string',
|
|
913
815
|
description: 'Project UUID',
|
|
914
816
|
},
|
|
817
|
+
limit: {
|
|
818
|
+
type: 'number',
|
|
819
|
+
description: 'Max number of decisions to return (default 50, max 200)',
|
|
820
|
+
},
|
|
821
|
+
offset: {
|
|
822
|
+
type: 'number',
|
|
823
|
+
description: 'Number of decisions to skip for pagination (default 0)',
|
|
824
|
+
},
|
|
825
|
+
search_query: {
|
|
826
|
+
type: 'string',
|
|
827
|
+
description: 'Search decisions by title or description',
|
|
828
|
+
},
|
|
915
829
|
},
|
|
916
830
|
required: ['project_id'],
|
|
917
831
|
},
|
|
@@ -989,6 +903,18 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
989
903
|
enum: ['raw', 'exploring', 'planned', 'in_development', 'shipped'],
|
|
990
904
|
description: 'Filter by status (optional)',
|
|
991
905
|
},
|
|
906
|
+
limit: {
|
|
907
|
+
type: 'number',
|
|
908
|
+
description: 'Max number of ideas to return (default 50, max 100)',
|
|
909
|
+
},
|
|
910
|
+
offset: {
|
|
911
|
+
type: 'number',
|
|
912
|
+
description: 'Number of ideas to skip for pagination (default 0)',
|
|
913
|
+
},
|
|
914
|
+
search_query: {
|
|
915
|
+
type: 'string',
|
|
916
|
+
description: 'Search ideas by title or description',
|
|
917
|
+
},
|
|
992
918
|
},
|
|
993
919
|
required: ['project_id'],
|
|
994
920
|
},
|
|
@@ -1119,7 +1045,9 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
1119
1045
|
category: { type: 'string', enum: ['performance', 'security', 'code_quality', 'accessibility', 'documentation', 'architecture', 'testing', 'other'], description: 'Filter by category (optional)' },
|
|
1120
1046
|
severity: { type: 'string', enum: ['info', 'low', 'medium', 'high', 'critical'], description: 'Filter by severity (optional)' },
|
|
1121
1047
|
status: { type: 'string', enum: ['open', 'addressed', 'dismissed', 'wontfix'], description: 'Filter by status (default: all)' },
|
|
1122
|
-
limit: { type: 'number', description: 'Max number of findings to return (default 50)' },
|
|
1048
|
+
limit: { type: 'number', description: 'Max number of findings to return (default 50, max 200)' },
|
|
1049
|
+
offset: { type: 'number', description: 'Number of findings to skip for pagination (default 0)' },
|
|
1050
|
+
search_query: { type: 'string', description: 'Search findings by title or description' },
|
|
1123
1051
|
},
|
|
1124
1052
|
required: ['project_id'],
|
|
1125
1053
|
},
|
|
@@ -1165,6 +1093,119 @@ Returns session info, persona, and next task. Use mode:'full' for complete conte
|
|
|
1165
1093
|
required: ['blocker_id'],
|
|
1166
1094
|
},
|
|
1167
1095
|
},
|
|
1096
|
+
// Git Issues tools
|
|
1097
|
+
{
|
|
1098
|
+
name: 'add_git_issue',
|
|
1099
|
+
description: `Record a git-related issue (merge conflict, push failure, etc.). Auto-created by claim_validation when conflicts detected.`,
|
|
1100
|
+
inputSchema: {
|
|
1101
|
+
type: 'object',
|
|
1102
|
+
properties: {
|
|
1103
|
+
project_id: {
|
|
1104
|
+
type: 'string',
|
|
1105
|
+
description: 'Project UUID',
|
|
1106
|
+
},
|
|
1107
|
+
issue_type: {
|
|
1108
|
+
type: 'string',
|
|
1109
|
+
enum: ['merge_conflict', 'push_failed', 'rebase_needed', 'branch_diverged', 'pr_not_mergeable'],
|
|
1110
|
+
description: 'Type of git issue',
|
|
1111
|
+
},
|
|
1112
|
+
branch: {
|
|
1113
|
+
type: 'string',
|
|
1114
|
+
description: 'Branch where the issue occurred',
|
|
1115
|
+
},
|
|
1116
|
+
target_branch: {
|
|
1117
|
+
type: 'string',
|
|
1118
|
+
description: 'Target branch for merge/rebase (optional)',
|
|
1119
|
+
},
|
|
1120
|
+
pr_url: {
|
|
1121
|
+
type: 'string',
|
|
1122
|
+
description: 'Pull request URL if applicable (optional)',
|
|
1123
|
+
},
|
|
1124
|
+
conflicting_files: {
|
|
1125
|
+
type: 'array',
|
|
1126
|
+
items: { type: 'string' },
|
|
1127
|
+
description: 'List of files with conflicts (optional)',
|
|
1128
|
+
},
|
|
1129
|
+
error_message: {
|
|
1130
|
+
type: 'string',
|
|
1131
|
+
description: 'Error message from git operation (optional)',
|
|
1132
|
+
},
|
|
1133
|
+
task_id: {
|
|
1134
|
+
type: 'string',
|
|
1135
|
+
description: 'Related task UUID (optional)',
|
|
1136
|
+
},
|
|
1137
|
+
},
|
|
1138
|
+
required: ['project_id', 'issue_type', 'branch'],
|
|
1139
|
+
},
|
|
1140
|
+
},
|
|
1141
|
+
{
|
|
1142
|
+
name: 'resolve_git_issue',
|
|
1143
|
+
description: `Mark a git issue as resolved.`,
|
|
1144
|
+
inputSchema: {
|
|
1145
|
+
type: 'object',
|
|
1146
|
+
properties: {
|
|
1147
|
+
git_issue_id: {
|
|
1148
|
+
type: 'string',
|
|
1149
|
+
description: 'Git issue UUID',
|
|
1150
|
+
},
|
|
1151
|
+
resolution_note: {
|
|
1152
|
+
type: 'string',
|
|
1153
|
+
description: 'How the issue was resolved (optional)',
|
|
1154
|
+
},
|
|
1155
|
+
auto_resolved: {
|
|
1156
|
+
type: 'boolean',
|
|
1157
|
+
description: 'Whether this was auto-resolved (e.g., PR became mergeable)',
|
|
1158
|
+
},
|
|
1159
|
+
},
|
|
1160
|
+
required: ['git_issue_id'],
|
|
1161
|
+
},
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
name: 'get_git_issues',
|
|
1165
|
+
description: `Get git issues for a project, optionally filtered by status, type, or branch.`,
|
|
1166
|
+
inputSchema: {
|
|
1167
|
+
type: 'object',
|
|
1168
|
+
properties: {
|
|
1169
|
+
project_id: {
|
|
1170
|
+
type: 'string',
|
|
1171
|
+
description: 'Project UUID',
|
|
1172
|
+
},
|
|
1173
|
+
status: {
|
|
1174
|
+
type: 'string',
|
|
1175
|
+
enum: ['open', 'resolved'],
|
|
1176
|
+
description: 'Filter by status (default: open)',
|
|
1177
|
+
},
|
|
1178
|
+
issue_type: {
|
|
1179
|
+
type: 'string',
|
|
1180
|
+
enum: ['merge_conflict', 'push_failed', 'rebase_needed', 'branch_diverged', 'pr_not_mergeable'],
|
|
1181
|
+
description: 'Filter by issue type (optional)',
|
|
1182
|
+
},
|
|
1183
|
+
branch: {
|
|
1184
|
+
type: 'string',
|
|
1185
|
+
description: 'Filter by branch (optional)',
|
|
1186
|
+
},
|
|
1187
|
+
limit: {
|
|
1188
|
+
type: 'number',
|
|
1189
|
+
description: 'Max issues to return (default: 50)',
|
|
1190
|
+
},
|
|
1191
|
+
},
|
|
1192
|
+
required: ['project_id'],
|
|
1193
|
+
},
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
name: 'delete_git_issue',
|
|
1197
|
+
description: `Delete a git issue.`,
|
|
1198
|
+
inputSchema: {
|
|
1199
|
+
type: 'object',
|
|
1200
|
+
properties: {
|
|
1201
|
+
git_issue_id: {
|
|
1202
|
+
type: 'string',
|
|
1203
|
+
description: 'Git issue UUID',
|
|
1204
|
+
},
|
|
1205
|
+
},
|
|
1206
|
+
required: ['git_issue_id'],
|
|
1207
|
+
},
|
|
1208
|
+
},
|
|
1168
1209
|
{
|
|
1169
1210
|
name: 'delete_decision',
|
|
1170
1211
|
description: `Delete a decision.`,
|
|
@@ -2129,6 +2170,18 @@ Bodies of work allow organizing related tasks with optional auto-deployment on c
|
|
|
2129
2170
|
enum: ['draft', 'active', 'completed', 'cancelled'],
|
|
2130
2171
|
description: 'Filter by status (optional)',
|
|
2131
2172
|
},
|
|
2173
|
+
limit: {
|
|
2174
|
+
type: 'number',
|
|
2175
|
+
description: 'Max number of bodies of work to return (default 50, max 100)',
|
|
2176
|
+
},
|
|
2177
|
+
offset: {
|
|
2178
|
+
type: 'number',
|
|
2179
|
+
description: 'Number of items to skip for pagination (default 0)',
|
|
2180
|
+
},
|
|
2181
|
+
search_query: {
|
|
2182
|
+
type: 'string',
|
|
2183
|
+
description: 'Search bodies of work by title or description',
|
|
2184
|
+
},
|
|
2132
2185
|
},
|
|
2133
2186
|
required: ['project_id'],
|
|
2134
2187
|
},
|
|
@@ -2279,6 +2332,273 @@ Only returns tasks where all dependencies are completed.`,
|
|
|
2279
2332
|
},
|
|
2280
2333
|
},
|
|
2281
2334
|
// ============================================================================
|
|
2335
|
+
// Sprint Tools
|
|
2336
|
+
// ============================================================================
|
|
2337
|
+
{
|
|
2338
|
+
name: 'create_sprint',
|
|
2339
|
+
description: `Create a new sprint. Sprints are time-bounded bodies of work with velocity tracking.
|
|
2340
|
+
Sprints start in 'planning' status where tasks can be added with story points.`,
|
|
2341
|
+
inputSchema: {
|
|
2342
|
+
type: 'object',
|
|
2343
|
+
properties: {
|
|
2344
|
+
project_id: {
|
|
2345
|
+
type: 'string',
|
|
2346
|
+
description: 'Project UUID',
|
|
2347
|
+
},
|
|
2348
|
+
title: {
|
|
2349
|
+
type: 'string',
|
|
2350
|
+
description: 'Sprint title (e.g., "Sprint 5" or "Q1 Release")',
|
|
2351
|
+
},
|
|
2352
|
+
goal: {
|
|
2353
|
+
type: 'string',
|
|
2354
|
+
description: 'Sprint goal statement',
|
|
2355
|
+
},
|
|
2356
|
+
start_date: {
|
|
2357
|
+
type: 'string',
|
|
2358
|
+
description: 'Start date (YYYY-MM-DD)',
|
|
2359
|
+
},
|
|
2360
|
+
end_date: {
|
|
2361
|
+
type: 'string',
|
|
2362
|
+
description: 'End date (YYYY-MM-DD)',
|
|
2363
|
+
},
|
|
2364
|
+
auto_deploy_on_completion: {
|
|
2365
|
+
type: 'boolean',
|
|
2366
|
+
description: 'Automatically request deployment when sprint completes (default: false)',
|
|
2367
|
+
},
|
|
2368
|
+
deploy_environment: {
|
|
2369
|
+
type: 'string',
|
|
2370
|
+
enum: ['development', 'staging', 'production'],
|
|
2371
|
+
description: 'Target environment for auto-deploy (default: production)',
|
|
2372
|
+
},
|
|
2373
|
+
deploy_version_bump: {
|
|
2374
|
+
type: 'string',
|
|
2375
|
+
enum: ['patch', 'minor', 'major'],
|
|
2376
|
+
description: 'Version bump for auto-deploy (default: minor)',
|
|
2377
|
+
},
|
|
2378
|
+
},
|
|
2379
|
+
required: ['project_id', 'title', 'start_date', 'end_date'],
|
|
2380
|
+
},
|
|
2381
|
+
},
|
|
2382
|
+
{
|
|
2383
|
+
name: 'update_sprint',
|
|
2384
|
+
description: `Update a sprint's details. Can update title, goal, dates, and deployment settings.`,
|
|
2385
|
+
inputSchema: {
|
|
2386
|
+
type: 'object',
|
|
2387
|
+
properties: {
|
|
2388
|
+
sprint_id: {
|
|
2389
|
+
type: 'string',
|
|
2390
|
+
description: 'Sprint UUID',
|
|
2391
|
+
},
|
|
2392
|
+
title: {
|
|
2393
|
+
type: 'string',
|
|
2394
|
+
description: 'New sprint title',
|
|
2395
|
+
},
|
|
2396
|
+
goal: {
|
|
2397
|
+
type: 'string',
|
|
2398
|
+
description: 'New sprint goal',
|
|
2399
|
+
},
|
|
2400
|
+
start_date: {
|
|
2401
|
+
type: 'string',
|
|
2402
|
+
description: 'New start date (YYYY-MM-DD)',
|
|
2403
|
+
},
|
|
2404
|
+
end_date: {
|
|
2405
|
+
type: 'string',
|
|
2406
|
+
description: 'New end date (YYYY-MM-DD)',
|
|
2407
|
+
},
|
|
2408
|
+
auto_deploy_on_completion: {
|
|
2409
|
+
type: 'boolean',
|
|
2410
|
+
description: 'Auto-deploy setting',
|
|
2411
|
+
},
|
|
2412
|
+
deploy_environment: {
|
|
2413
|
+
type: 'string',
|
|
2414
|
+
enum: ['development', 'staging', 'production'],
|
|
2415
|
+
description: 'Target environment',
|
|
2416
|
+
},
|
|
2417
|
+
deploy_version_bump: {
|
|
2418
|
+
type: 'string',
|
|
2419
|
+
enum: ['patch', 'minor', 'major'],
|
|
2420
|
+
description: 'Version bump type',
|
|
2421
|
+
},
|
|
2422
|
+
},
|
|
2423
|
+
required: ['sprint_id'],
|
|
2424
|
+
},
|
|
2425
|
+
},
|
|
2426
|
+
{
|
|
2427
|
+
name: 'get_sprint',
|
|
2428
|
+
description: `Get a sprint with all its tasks organized by phase (pre/core/post).
|
|
2429
|
+
Includes progress percentage, velocity points, and committed points.`,
|
|
2430
|
+
inputSchema: {
|
|
2431
|
+
type: 'object',
|
|
2432
|
+
properties: {
|
|
2433
|
+
sprint_id: {
|
|
2434
|
+
type: 'string',
|
|
2435
|
+
description: 'Sprint UUID',
|
|
2436
|
+
},
|
|
2437
|
+
},
|
|
2438
|
+
required: ['sprint_id'],
|
|
2439
|
+
},
|
|
2440
|
+
},
|
|
2441
|
+
{
|
|
2442
|
+
name: 'get_sprints',
|
|
2443
|
+
description: `List sprints for a project with velocity metrics.
|
|
2444
|
+
Returns sprints sorted by sprint_number descending (most recent first).`,
|
|
2445
|
+
inputSchema: {
|
|
2446
|
+
type: 'object',
|
|
2447
|
+
properties: {
|
|
2448
|
+
project_id: {
|
|
2449
|
+
type: 'string',
|
|
2450
|
+
description: 'Project UUID',
|
|
2451
|
+
},
|
|
2452
|
+
status: {
|
|
2453
|
+
type: 'string',
|
|
2454
|
+
enum: ['planning', 'active', 'in_review', 'retrospective', 'completed', 'cancelled'],
|
|
2455
|
+
description: 'Filter by sprint status (optional)',
|
|
2456
|
+
},
|
|
2457
|
+
limit: {
|
|
2458
|
+
type: 'number',
|
|
2459
|
+
description: 'Max sprints to return (default: 20, max: 100)',
|
|
2460
|
+
},
|
|
2461
|
+
},
|
|
2462
|
+
required: ['project_id'],
|
|
2463
|
+
},
|
|
2464
|
+
},
|
|
2465
|
+
{
|
|
2466
|
+
name: 'delete_sprint',
|
|
2467
|
+
description: `Delete a sprint. Tasks are preserved but no longer grouped.`,
|
|
2468
|
+
inputSchema: {
|
|
2469
|
+
type: 'object',
|
|
2470
|
+
properties: {
|
|
2471
|
+
sprint_id: {
|
|
2472
|
+
type: 'string',
|
|
2473
|
+
description: 'Sprint UUID',
|
|
2474
|
+
},
|
|
2475
|
+
},
|
|
2476
|
+
required: ['sprint_id'],
|
|
2477
|
+
},
|
|
2478
|
+
},
|
|
2479
|
+
{
|
|
2480
|
+
name: 'start_sprint',
|
|
2481
|
+
description: `Start a sprint. Transitions from 'planning' to 'active' status.
|
|
2482
|
+
Locks the committed_points at the current total story points.`,
|
|
2483
|
+
inputSchema: {
|
|
2484
|
+
type: 'object',
|
|
2485
|
+
properties: {
|
|
2486
|
+
sprint_id: {
|
|
2487
|
+
type: 'string',
|
|
2488
|
+
description: 'Sprint UUID',
|
|
2489
|
+
},
|
|
2490
|
+
},
|
|
2491
|
+
required: ['sprint_id'],
|
|
2492
|
+
},
|
|
2493
|
+
},
|
|
2494
|
+
{
|
|
2495
|
+
name: 'complete_sprint',
|
|
2496
|
+
description: `Complete a sprint. Handles retrospective phase and auto-deployment if configured.
|
|
2497
|
+
Status flow: active → in_review → retrospective → completed`,
|
|
2498
|
+
inputSchema: {
|
|
2499
|
+
type: 'object',
|
|
2500
|
+
properties: {
|
|
2501
|
+
sprint_id: {
|
|
2502
|
+
type: 'string',
|
|
2503
|
+
description: 'Sprint UUID',
|
|
2504
|
+
},
|
|
2505
|
+
retrospective_notes: {
|
|
2506
|
+
type: 'string',
|
|
2507
|
+
description: 'Sprint retrospective notes',
|
|
2508
|
+
},
|
|
2509
|
+
skip_retrospective: {
|
|
2510
|
+
type: 'boolean',
|
|
2511
|
+
description: 'Skip retrospective phase and go directly to completed (default: false)',
|
|
2512
|
+
},
|
|
2513
|
+
},
|
|
2514
|
+
required: ['sprint_id'],
|
|
2515
|
+
},
|
|
2516
|
+
},
|
|
2517
|
+
{
|
|
2518
|
+
name: 'add_task_to_sprint',
|
|
2519
|
+
description: `Add a task to a sprint with optional story points.
|
|
2520
|
+
Tasks can be added during 'planning' status. Story points contribute to committed_points.`,
|
|
2521
|
+
inputSchema: {
|
|
2522
|
+
type: 'object',
|
|
2523
|
+
properties: {
|
|
2524
|
+
sprint_id: {
|
|
2525
|
+
type: 'string',
|
|
2526
|
+
description: 'Sprint UUID',
|
|
2527
|
+
},
|
|
2528
|
+
task_id: {
|
|
2529
|
+
type: 'string',
|
|
2530
|
+
description: 'Task UUID to add',
|
|
2531
|
+
},
|
|
2532
|
+
story_points: {
|
|
2533
|
+
type: 'number',
|
|
2534
|
+
description: 'Story point estimate (optional, must be non-negative integer)',
|
|
2535
|
+
},
|
|
2536
|
+
phase: {
|
|
2537
|
+
type: 'string',
|
|
2538
|
+
enum: ['pre', 'core', 'post'],
|
|
2539
|
+
description: 'Task phase (default: core)',
|
|
2540
|
+
},
|
|
2541
|
+
},
|
|
2542
|
+
required: ['sprint_id', 'task_id'],
|
|
2543
|
+
},
|
|
2544
|
+
},
|
|
2545
|
+
{
|
|
2546
|
+
name: 'remove_task_from_sprint',
|
|
2547
|
+
description: `Remove a task from a sprint. Task is preserved but returns to backlog.`,
|
|
2548
|
+
inputSchema: {
|
|
2549
|
+
type: 'object',
|
|
2550
|
+
properties: {
|
|
2551
|
+
sprint_id: {
|
|
2552
|
+
type: 'string',
|
|
2553
|
+
description: 'Sprint UUID',
|
|
2554
|
+
},
|
|
2555
|
+
task_id: {
|
|
2556
|
+
type: 'string',
|
|
2557
|
+
description: 'Task UUID to remove',
|
|
2558
|
+
},
|
|
2559
|
+
},
|
|
2560
|
+
required: ['sprint_id', 'task_id'],
|
|
2561
|
+
},
|
|
2562
|
+
},
|
|
2563
|
+
{
|
|
2564
|
+
name: 'get_sprint_backlog',
|
|
2565
|
+
description: `Get tasks from backlog/pending that can be added to a sprint.
|
|
2566
|
+
Returns tasks not already assigned to any body of work or sprint.`,
|
|
2567
|
+
inputSchema: {
|
|
2568
|
+
type: 'object',
|
|
2569
|
+
properties: {
|
|
2570
|
+
project_id: {
|
|
2571
|
+
type: 'string',
|
|
2572
|
+
description: 'Project UUID',
|
|
2573
|
+
},
|
|
2574
|
+
sprint_id: {
|
|
2575
|
+
type: 'string',
|
|
2576
|
+
description: 'Sprint UUID to exclude already-added tasks (optional)',
|
|
2577
|
+
},
|
|
2578
|
+
},
|
|
2579
|
+
required: ['project_id'],
|
|
2580
|
+
},
|
|
2581
|
+
},
|
|
2582
|
+
{
|
|
2583
|
+
name: 'get_sprint_velocity',
|
|
2584
|
+
description: `Get velocity metrics for completed sprints.
|
|
2585
|
+
Returns committed vs completed points and average velocity.`,
|
|
2586
|
+
inputSchema: {
|
|
2587
|
+
type: 'object',
|
|
2588
|
+
properties: {
|
|
2589
|
+
project_id: {
|
|
2590
|
+
type: 'string',
|
|
2591
|
+
description: 'Project UUID',
|
|
2592
|
+
},
|
|
2593
|
+
limit: {
|
|
2594
|
+
type: 'number',
|
|
2595
|
+
description: 'Number of sprints to analyze (default: 10, max: 50)',
|
|
2596
|
+
},
|
|
2597
|
+
},
|
|
2598
|
+
required: ['project_id'],
|
|
2599
|
+
},
|
|
2600
|
+
},
|
|
2601
|
+
// ============================================================================
|
|
2282
2602
|
// Organization Tools
|
|
2283
2603
|
// ============================================================================
|
|
2284
2604
|
{
|
|
@@ -2526,24 +2846,15 @@ Only returns tasks where all dependencies are completed.`,
|
|
|
2526
2846
|
// Tool Handlers
|
|
2527
2847
|
// ============================================================================
|
|
2528
2848
|
async function handleTool(auth, name, args) {
|
|
2529
|
-
// Update session on every tool call:
|
|
2849
|
+
// Update session on every tool call via API:
|
|
2530
2850
|
// - last_synced_at: keeps session alive and visible as "active" on dashboard
|
|
2531
|
-
// -
|
|
2532
|
-
// - last_tool_at: timestamp of last tool call
|
|
2851
|
+
// - token tracking: synced periodically for cost monitoring
|
|
2533
2852
|
// Skip for start_work_session since it handles its own session setup
|
|
2534
2853
|
if (currentSessionId && name !== 'start_work_session') {
|
|
2535
|
-
const
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
}).then(({ error }) => {
|
|
2540
|
-
// Fallback to direct update if RPC doesn't exist (pre-migration)
|
|
2541
|
-
if (error) {
|
|
2542
|
-
return supabase
|
|
2543
|
-
.from('agent_sessions')
|
|
2544
|
-
.update({ last_synced_at: now })
|
|
2545
|
-
.eq('id', currentSessionId);
|
|
2546
|
-
}
|
|
2854
|
+
const apiClient = getApiClient();
|
|
2855
|
+
// Fire and forget - don't block tool execution on session sync
|
|
2856
|
+
apiClient.syncSession(currentSessionId).catch(() => {
|
|
2857
|
+
// Silently ignore sync errors - session tracking is non-critical
|
|
2547
2858
|
});
|
|
2548
2859
|
}
|
|
2549
2860
|
// Check if handler exists in the modular registry
|
|
@@ -2551,12 +2862,12 @@ async function handleTool(auth, name, args) {
|
|
|
2551
2862
|
if (handler) {
|
|
2552
2863
|
// Build handler context
|
|
2553
2864
|
const ctx = {
|
|
2554
|
-
supabase,
|
|
2555
2865
|
auth,
|
|
2556
2866
|
session: {
|
|
2557
2867
|
instanceId: INSTANCE_ID,
|
|
2558
2868
|
currentSessionId,
|
|
2559
2869
|
currentPersona,
|
|
2870
|
+
currentRole,
|
|
2560
2871
|
tokenUsage: sessionTokenUsage,
|
|
2561
2872
|
},
|
|
2562
2873
|
updateSession: (updates) => {
|
|
@@ -2564,6 +2875,8 @@ async function handleTool(auth, name, args) {
|
|
|
2564
2875
|
currentSessionId = updates.currentSessionId;
|
|
2565
2876
|
if (updates.currentPersona !== undefined)
|
|
2566
2877
|
currentPersona = updates.currentPersona;
|
|
2878
|
+
if (updates.currentRole !== undefined)
|
|
2879
|
+
currentRole = updates.currentRole;
|
|
2567
2880
|
if (updates.tokenUsage !== undefined)
|
|
2568
2881
|
sessionTokenUsage = updates.tokenUsage;
|
|
2569
2882
|
},
|
|
@@ -2577,8 +2890,8 @@ async function handleTool(auth, name, args) {
|
|
|
2577
2890
|
// Server Setup
|
|
2578
2891
|
// ============================================================================
|
|
2579
2892
|
async function main() {
|
|
2580
|
-
// Validate API key on startup
|
|
2581
|
-
const auth = await validateApiKey(
|
|
2893
|
+
// Validate API key on startup via API
|
|
2894
|
+
const auth = await validateApiKey();
|
|
2582
2895
|
if (!auth) {
|
|
2583
2896
|
console.error('Invalid API key');
|
|
2584
2897
|
process.exit(1);
|