@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.
- package/README.md +113 -98
- package/dist/api-client.d.ts +1169 -0
- package/dist/api-client.js +713 -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 +108 -477
- 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 +113 -828
- package/dist/handlers/discovery.d.ts +3 -0
- package/dist/handlers/discovery.js +26 -627
- package/dist/handlers/fallback.d.ts +2 -0
- package/dist/handlers/fallback.js +56 -142
- package/dist/handlers/findings.d.ts +8 -1
- package/dist/handlers/findings.js +65 -68
- 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 +119 -590
- package/dist/handlers/sprints.d.ts +32 -0
- package/dist/handlers/sprints.js +275 -0
- package/dist/handlers/tasks.d.ts +7 -10
- package/dist/handlers/tasks.js +245 -894
- package/dist/handlers/tool-docs.d.ts +9 -0
- package/dist/handlers/tool-docs.js +904 -0
- package/dist/handlers/types.d.ts +11 -3
- package/dist/handlers/validation.d.ts +1 -1
- package/dist/handlers/validation.js +38 -153
- package/dist/index.js +493 -162
- package/dist/knowledge.js +106 -9
- package/dist/tools.js +34 -4
- package/dist/validators.d.ts +21 -0
- package/dist/validators.js +91 -0
- package/package.json +2 -3
- package/src/api-client.ts +1822 -0
- package/src/cli.test.ts +128 -302
- package/src/cli.ts +41 -285
- package/src/handlers/__test-setup__.ts +215 -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 +210 -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 +143 -896
- package/src/handlers/discovery.test.ts +20 -67
- package/src/handlers/discovery.ts +29 -714
- package/src/handlers/fallback.test.ts +206 -361
- package/src/handlers/fallback.ts +81 -156
- package/src/handlers/findings.test.ts +229 -320
- package/src/handlers/findings.ts +76 -64
- 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 +276 -206
- package/src/handlers/session.ts +136 -662
- package/src/handlers/sprints.test.ts +711 -0
- package/src/handlers/sprints.ts +510 -0
- package/src/handlers/tasks.test.ts +669 -353
- package/src/handlers/tasks.ts +263 -1015
- package/src/handlers/tool-docs.ts +1024 -0
- package/src/handlers/types.ts +12 -4
- package/src/handlers/validation.test.ts +237 -568
- package/src/handlers/validation.ts +43 -167
- package/src/index.ts +493 -186
- package/src/tools.ts +2532 -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/knowledge.ts +0 -132
- 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
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Knowledge Handlers
|
|
3
|
-
*
|
|
4
|
-
* Unified knowledge query to reduce tool calls and token costs.
|
|
5
|
-
* Aggregates decisions, findings, blockers, Q&A, and task history.
|
|
6
|
-
*/
|
|
7
|
-
import { validateRequired, validateUUID } from '../validators.js';
|
|
8
|
-
const VALID_QUERY_TYPES = ['context', 'architecture', 'issues', 'history', 'qa'];
|
|
9
|
-
const QUERY_TYPE_DESCRIPTIONS = {
|
|
10
|
-
context: 'Key decisions, open blockers, recent Q&As, critical findings - use when starting work',
|
|
11
|
-
architecture: 'All decisions + architecture-related findings - use when understanding codebase',
|
|
12
|
-
issues: 'Open findings + blockers sorted by severity - use when fixing bugs',
|
|
13
|
-
history: 'Completed tasks with summaries - use when understanding what was done',
|
|
14
|
-
qa: 'Answered questions as Q&A pairs - use when looking for common questions',
|
|
15
|
-
};
|
|
16
|
-
export const queryKnowledge = async (args, ctx) => {
|
|
17
|
-
const { project_id, query_type = 'context', limit = 20 } = args;
|
|
18
|
-
validateRequired(project_id, 'project_id');
|
|
19
|
-
validateUUID(project_id, 'project_id');
|
|
20
|
-
if (!VALID_QUERY_TYPES.includes(query_type)) {
|
|
21
|
-
throw new Error(`Invalid query_type '${query_type}'. Must be one of: ${VALID_QUERY_TYPES.join(', ')}`);
|
|
22
|
-
}
|
|
23
|
-
const { supabase } = ctx;
|
|
24
|
-
// Call the database function
|
|
25
|
-
const { data, error } = await supabase.rpc('query_knowledge', {
|
|
26
|
-
p_project_id: project_id,
|
|
27
|
-
p_query_type: query_type,
|
|
28
|
-
p_limit: Math.min(limit, 50), // Cap at 50 to limit response size
|
|
29
|
-
});
|
|
30
|
-
if (error) {
|
|
31
|
-
throw new Error(`Failed to query knowledge: ${error.message}`);
|
|
32
|
-
}
|
|
33
|
-
// Map database results to typed items
|
|
34
|
-
const items = (data || []).map((row) => ({
|
|
35
|
-
type: row.item_type,
|
|
36
|
-
id: row.id,
|
|
37
|
-
title: row.title,
|
|
38
|
-
content: row.content,
|
|
39
|
-
...(row.severity && { severity: row.severity }),
|
|
40
|
-
...(row.status && { status: row.status }),
|
|
41
|
-
created_at: row.created_at,
|
|
42
|
-
}));
|
|
43
|
-
// Generate summary based on query type and results
|
|
44
|
-
const summary = generateSummary(query_type, items);
|
|
45
|
-
// Estimate tokens (rough: ~4 chars per token)
|
|
46
|
-
const responseJson = JSON.stringify({ items, summary });
|
|
47
|
-
const tokenEstimate = Math.ceil(responseJson.length / 4);
|
|
48
|
-
return {
|
|
49
|
-
result: {
|
|
50
|
-
query_type,
|
|
51
|
-
project_id,
|
|
52
|
-
description: QUERY_TYPE_DESCRIPTIONS[query_type],
|
|
53
|
-
summary,
|
|
54
|
-
items,
|
|
55
|
-
count: items.length,
|
|
56
|
-
token_estimate: tokenEstimate,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
};
|
|
60
|
-
function generateSummary(queryType, items) {
|
|
61
|
-
const counts = items.reduce((acc, item) => {
|
|
62
|
-
acc[item.type] = (acc[item.type] || 0) + 1;
|
|
63
|
-
return acc;
|
|
64
|
-
}, {});
|
|
65
|
-
const parts = [];
|
|
66
|
-
switch (queryType) {
|
|
67
|
-
case 'context':
|
|
68
|
-
if (counts.blocker)
|
|
69
|
-
parts.push(`${counts.blocker} open blocker(s)`);
|
|
70
|
-
if (counts.finding)
|
|
71
|
-
parts.push(`${counts.finding} critical/high finding(s)`);
|
|
72
|
-
if (counts.decision)
|
|
73
|
-
parts.push(`${counts.decision} recent decision(s)`);
|
|
74
|
-
if (counts.qa)
|
|
75
|
-
parts.push(`${counts.qa} answered question(s)`);
|
|
76
|
-
break;
|
|
77
|
-
case 'architecture':
|
|
78
|
-
if (counts.decision)
|
|
79
|
-
parts.push(`${counts.decision} architectural decision(s)`);
|
|
80
|
-
if (counts.finding)
|
|
81
|
-
parts.push(`${counts.finding} architecture finding(s)`);
|
|
82
|
-
break;
|
|
83
|
-
case 'issues':
|
|
84
|
-
if (counts.blocker)
|
|
85
|
-
parts.push(`${counts.blocker} blocker(s)`);
|
|
86
|
-
if (counts.finding)
|
|
87
|
-
parts.push(`${counts.finding} open finding(s)`);
|
|
88
|
-
break;
|
|
89
|
-
case 'history':
|
|
90
|
-
if (counts.task)
|
|
91
|
-
parts.push(`${counts.task} completed task(s)`);
|
|
92
|
-
break;
|
|
93
|
-
case 'qa':
|
|
94
|
-
if (counts.qa)
|
|
95
|
-
parts.push(`${counts.qa} Q&A pair(s)`);
|
|
96
|
-
break;
|
|
97
|
-
}
|
|
98
|
-
if (parts.length === 0) {
|
|
99
|
-
return `No ${queryType} items found.`;
|
|
100
|
-
}
|
|
101
|
-
return `Found ${parts.join(', ')}.`;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Knowledge handlers registry
|
|
105
|
-
*/
|
|
106
|
-
export const knowledgeHandlers = {
|
|
107
|
-
query_knowledge: queryKnowledge,
|
|
108
|
-
};
|
package/dist/handlers/roles.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Role Handlers
|
|
3
|
-
*
|
|
4
|
-
* Manages agent roles for specialized work:
|
|
5
|
-
* - get_role_settings: Get role configuration for a project
|
|
6
|
-
* - update_role_settings: Update role settings
|
|
7
|
-
* - set_session_role: Change the current session's role
|
|
8
|
-
* - get_agents_by_role: Get active agents grouped by role
|
|
9
|
-
*/
|
|
10
|
-
import type { Handler, HandlerRegistry } from './types.js';
|
|
11
|
-
/**
|
|
12
|
-
* Get role settings for a project
|
|
13
|
-
*/
|
|
14
|
-
export declare const getRoleSettings: Handler;
|
|
15
|
-
/**
|
|
16
|
-
* Update role settings for a project
|
|
17
|
-
*/
|
|
18
|
-
export declare const updateRoleSettings: Handler;
|
|
19
|
-
/**
|
|
20
|
-
* Set the current session's role
|
|
21
|
-
*/
|
|
22
|
-
export declare const setSessionRole: Handler;
|
|
23
|
-
/**
|
|
24
|
-
* Get active agents grouped by role
|
|
25
|
-
*/
|
|
26
|
-
export declare const getAgentsByRole: Handler;
|
|
27
|
-
/**
|
|
28
|
-
* Role handlers registry
|
|
29
|
-
*/
|
|
30
|
-
export declare const roleHandlers: HandlerRegistry;
|
package/dist/handlers/roles.js
DELETED
|
@@ -1,281 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Role Handlers
|
|
3
|
-
*
|
|
4
|
-
* Manages agent roles for specialized work:
|
|
5
|
-
* - get_role_settings: Get role configuration for a project
|
|
6
|
-
* - update_role_settings: Update role settings
|
|
7
|
-
* - set_session_role: Change the current session's role
|
|
8
|
-
* - get_agents_by_role: Get active agents grouped by role
|
|
9
|
-
*/
|
|
10
|
-
import { validateUUID, validateRequired } from '../validators.js';
|
|
11
|
-
// Valid agent roles - must match AgentRole type in types.ts and database enum
|
|
12
|
-
const VALID_ROLES = ['developer', 'validator', 'deployer', 'reviewer', 'maintainer'];
|
|
13
|
-
function isValidRole(role) {
|
|
14
|
-
return VALID_ROLES.includes(role);
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Verify the user owns or has access to the project
|
|
18
|
-
* This is needed because MCP server uses service_role which bypasses RLS
|
|
19
|
-
*/
|
|
20
|
-
async function verifyProjectAccess(ctx, projectId) {
|
|
21
|
-
const { supabase, auth } = ctx;
|
|
22
|
-
// Check if user owns the project
|
|
23
|
-
const { data: ownedProject } = await supabase
|
|
24
|
-
.from('projects')
|
|
25
|
-
.select('id')
|
|
26
|
-
.eq('id', projectId)
|
|
27
|
-
.eq('user_id', auth.userId)
|
|
28
|
-
.single();
|
|
29
|
-
if (ownedProject)
|
|
30
|
-
return;
|
|
31
|
-
// Check if project is shared with user's organization (for org-scoped keys)
|
|
32
|
-
if (auth.scope === 'organization' && auth.organizationId) {
|
|
33
|
-
const { data: sharedProject } = await supabase
|
|
34
|
-
.from('project_shares')
|
|
35
|
-
.select('project_id')
|
|
36
|
-
.eq('project_id', projectId)
|
|
37
|
-
.eq('organization_id', auth.organizationId)
|
|
38
|
-
.single();
|
|
39
|
-
if (sharedProject)
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
throw new Error('Project not found or access denied');
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Get role settings for a project
|
|
46
|
-
*/
|
|
47
|
-
export const getRoleSettings = async (args, ctx) => {
|
|
48
|
-
const { project_id } = args;
|
|
49
|
-
const { supabase } = ctx;
|
|
50
|
-
validateRequired(project_id, 'project_id');
|
|
51
|
-
validateUUID(project_id, 'project_id');
|
|
52
|
-
// Verify user has access to this project
|
|
53
|
-
await verifyProjectAccess(ctx, project_id);
|
|
54
|
-
const { data: settings, error } = await supabase
|
|
55
|
-
.from('project_role_settings')
|
|
56
|
-
.select('*')
|
|
57
|
-
.eq('project_id', project_id)
|
|
58
|
-
.order('role');
|
|
59
|
-
if (error) {
|
|
60
|
-
throw new Error(`Failed to get role settings: ${error.message}`);
|
|
61
|
-
}
|
|
62
|
-
// If no settings exist, return defaults
|
|
63
|
-
if (!settings || settings.length === 0) {
|
|
64
|
-
return {
|
|
65
|
-
result: {
|
|
66
|
-
project_id,
|
|
67
|
-
settings: VALID_ROLES.map(role => ({
|
|
68
|
-
role,
|
|
69
|
-
enabled: true,
|
|
70
|
-
display_name: role.charAt(0).toUpperCase() + role.slice(1),
|
|
71
|
-
description: getRoleDescription(role),
|
|
72
|
-
})),
|
|
73
|
-
note: 'Using default settings. Call update_role_settings to customize.',
|
|
74
|
-
},
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
return {
|
|
78
|
-
result: {
|
|
79
|
-
project_id,
|
|
80
|
-
settings,
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
};
|
|
84
|
-
function getRoleDescription(role) {
|
|
85
|
-
const descriptions = {
|
|
86
|
-
developer: 'General development work, picks up any available task',
|
|
87
|
-
validator: 'Focuses on validating completed tasks',
|
|
88
|
-
deployer: 'Handles deployment coordination and monitoring',
|
|
89
|
-
reviewer: 'Code review and quality checks',
|
|
90
|
-
maintainer: 'Task management, git orchestration, housekeeping',
|
|
91
|
-
};
|
|
92
|
-
return descriptions[role];
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Update role settings for a project
|
|
96
|
-
*/
|
|
97
|
-
export const updateRoleSettings = async (args, ctx) => {
|
|
98
|
-
const { project_id, role, enabled, display_name, description, priority_filter, fallback_activities, auto_assign_validation, auto_assign_deployment, } = args;
|
|
99
|
-
const { supabase } = ctx;
|
|
100
|
-
validateRequired(project_id, 'project_id');
|
|
101
|
-
validateUUID(project_id, 'project_id');
|
|
102
|
-
validateRequired(role, 'role');
|
|
103
|
-
if (!isValidRole(role)) {
|
|
104
|
-
throw new Error(`Invalid role: ${role}. Valid roles: ${VALID_ROLES.join(', ')}`);
|
|
105
|
-
}
|
|
106
|
-
// Verify user has access to this project
|
|
107
|
-
await verifyProjectAccess(ctx, project_id);
|
|
108
|
-
const updates = {
|
|
109
|
-
updated_at: new Date().toISOString(),
|
|
110
|
-
};
|
|
111
|
-
if (enabled !== undefined)
|
|
112
|
-
updates.enabled = enabled;
|
|
113
|
-
if (display_name !== undefined)
|
|
114
|
-
updates.display_name = display_name;
|
|
115
|
-
if (description !== undefined)
|
|
116
|
-
updates.description = description;
|
|
117
|
-
if (priority_filter !== undefined)
|
|
118
|
-
updates.priority_filter = priority_filter;
|
|
119
|
-
if (fallback_activities !== undefined)
|
|
120
|
-
updates.fallback_activities = fallback_activities;
|
|
121
|
-
if (auto_assign_validation !== undefined)
|
|
122
|
-
updates.auto_assign_validation = auto_assign_validation;
|
|
123
|
-
if (auto_assign_deployment !== undefined)
|
|
124
|
-
updates.auto_assign_deployment = auto_assign_deployment;
|
|
125
|
-
// Upsert the role settings
|
|
126
|
-
const { data, error } = await supabase
|
|
127
|
-
.from('project_role_settings')
|
|
128
|
-
.upsert({
|
|
129
|
-
project_id,
|
|
130
|
-
role,
|
|
131
|
-
...updates,
|
|
132
|
-
}, {
|
|
133
|
-
onConflict: 'project_id,role',
|
|
134
|
-
})
|
|
135
|
-
.select()
|
|
136
|
-
.single();
|
|
137
|
-
if (error) {
|
|
138
|
-
throw new Error(`Failed to update role settings: ${error.message}`);
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
result: {
|
|
142
|
-
success: true,
|
|
143
|
-
settings: data,
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
};
|
|
147
|
-
/**
|
|
148
|
-
* Set the current session's role
|
|
149
|
-
*/
|
|
150
|
-
export const setSessionRole = async (args, ctx) => {
|
|
151
|
-
const { role, role_config } = args;
|
|
152
|
-
const { supabase, session, updateSession } = ctx;
|
|
153
|
-
validateRequired(role, 'role');
|
|
154
|
-
if (!isValidRole(role)) {
|
|
155
|
-
throw new Error(`Invalid role: ${role}. Valid roles: ${VALID_ROLES.join(', ')}`);
|
|
156
|
-
}
|
|
157
|
-
const sessionId = session.currentSessionId;
|
|
158
|
-
if (!sessionId) {
|
|
159
|
-
throw new Error('No active session. Call start_work_session first.');
|
|
160
|
-
}
|
|
161
|
-
const updates = {
|
|
162
|
-
role,
|
|
163
|
-
updated_at: new Date().toISOString(),
|
|
164
|
-
};
|
|
165
|
-
// Allow role_config for custom configurations (e.g., maintainer with specific focus areas)
|
|
166
|
-
if (role_config) {
|
|
167
|
-
updates.role_config = role_config;
|
|
168
|
-
}
|
|
169
|
-
const { error } = await supabase
|
|
170
|
-
.from('agent_sessions')
|
|
171
|
-
.update(updates)
|
|
172
|
-
.eq('id', sessionId);
|
|
173
|
-
if (error) {
|
|
174
|
-
throw new Error(`Failed to set role: ${error.message}`);
|
|
175
|
-
}
|
|
176
|
-
// Update session state
|
|
177
|
-
updateSession({ currentRole: role });
|
|
178
|
-
// Get role-specific guidance
|
|
179
|
-
const guidance = getRoleGuidance(role);
|
|
180
|
-
return {
|
|
181
|
-
result: {
|
|
182
|
-
success: true,
|
|
183
|
-
role,
|
|
184
|
-
persona: session.currentPersona,
|
|
185
|
-
guidance,
|
|
186
|
-
},
|
|
187
|
-
};
|
|
188
|
-
};
|
|
189
|
-
function getRoleGuidance(role) {
|
|
190
|
-
const guidance = {
|
|
191
|
-
developer: 'Focus on implementing features and fixing bugs. Use get_next_task to find work.',
|
|
192
|
-
validator: 'Prioritize validation tasks. Use get_tasks_awaiting_validation to find completed tasks to review.',
|
|
193
|
-
deployer: 'Monitor deployment status with check_deployment_status. Handle deployment requests and coordination.',
|
|
194
|
-
reviewer: 'Run code reviews using code_review fallback activity. Check for security and quality issues.',
|
|
195
|
-
maintainer: 'Handle task management, git orchestration. Run performance_audit, dependency_audit when idle.',
|
|
196
|
-
};
|
|
197
|
-
return guidance[role];
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Get active agents grouped by role
|
|
201
|
-
*/
|
|
202
|
-
export const getAgentsByRole = async (args, ctx) => {
|
|
203
|
-
const { project_id } = args;
|
|
204
|
-
const { supabase } = ctx;
|
|
205
|
-
validateRequired(project_id, 'project_id');
|
|
206
|
-
validateUUID(project_id, 'project_id');
|
|
207
|
-
// Verify user has access to this project
|
|
208
|
-
await verifyProjectAccess(ctx, project_id);
|
|
209
|
-
const { data: agents, error } = await supabase
|
|
210
|
-
.from('agent_sessions')
|
|
211
|
-
.select(`
|
|
212
|
-
id,
|
|
213
|
-
agent_name,
|
|
214
|
-
role,
|
|
215
|
-
status,
|
|
216
|
-
current_task_id,
|
|
217
|
-
last_synced_at,
|
|
218
|
-
role_config
|
|
219
|
-
`)
|
|
220
|
-
.eq('project_id', project_id)
|
|
221
|
-
.neq('status', 'disconnected')
|
|
222
|
-
.gte('last_synced_at', new Date(Date.now() - 5 * 60 * 1000).toISOString());
|
|
223
|
-
if (error) {
|
|
224
|
-
throw new Error(`Failed to get agents: ${error.message}`);
|
|
225
|
-
}
|
|
226
|
-
// Group by role
|
|
227
|
-
const byRole = {};
|
|
228
|
-
for (const agent of agents || []) {
|
|
229
|
-
const role = agent.role || 'developer';
|
|
230
|
-
if (!byRole[role]) {
|
|
231
|
-
byRole[role] = [];
|
|
232
|
-
}
|
|
233
|
-
byRole[role].push(agent);
|
|
234
|
-
}
|
|
235
|
-
// Get current task titles
|
|
236
|
-
const taskIds = (agents || [])
|
|
237
|
-
.map(a => a.current_task_id)
|
|
238
|
-
.filter((id) => !!id);
|
|
239
|
-
let taskTitles = {};
|
|
240
|
-
if (taskIds.length > 0) {
|
|
241
|
-
const { data: tasks } = await supabase
|
|
242
|
-
.from('tasks')
|
|
243
|
-
.select('id, title')
|
|
244
|
-
.in('id', taskIds);
|
|
245
|
-
taskTitles = (tasks || []).reduce((acc, t) => {
|
|
246
|
-
acc[t.id] = t.title;
|
|
247
|
-
return acc;
|
|
248
|
-
}, {});
|
|
249
|
-
}
|
|
250
|
-
// Enrich agents with task titles
|
|
251
|
-
const enrichedByRole = {};
|
|
252
|
-
for (const [role, roleAgents] of Object.entries(byRole)) {
|
|
253
|
-
enrichedByRole[role] = roleAgents.map(agent => ({
|
|
254
|
-
id: agent.id,
|
|
255
|
-
agent_name: agent.agent_name,
|
|
256
|
-
role: agent.role || 'developer',
|
|
257
|
-
status: agent.status,
|
|
258
|
-
current_task: agent.current_task_id
|
|
259
|
-
? { id: agent.current_task_id, title: taskTitles[agent.current_task_id] || 'Unknown' }
|
|
260
|
-
: null,
|
|
261
|
-
last_synced_at: agent.last_synced_at,
|
|
262
|
-
}));
|
|
263
|
-
}
|
|
264
|
-
return {
|
|
265
|
-
result: {
|
|
266
|
-
project_id,
|
|
267
|
-
total_agents: agents?.length || 0,
|
|
268
|
-
by_role: enrichedByRole,
|
|
269
|
-
available_roles: VALID_ROLES,
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
};
|
|
273
|
-
/**
|
|
274
|
-
* Role handlers registry
|
|
275
|
-
*/
|
|
276
|
-
export const roleHandlers = {
|
|
277
|
-
get_role_settings: getRoleSettings,
|
|
278
|
-
update_role_settings: updateRoleSettings,
|
|
279
|
-
set_session_role: setSessionRole,
|
|
280
|
-
get_agents_by_role: getAgentsByRole,
|
|
281
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|