@vibescope/mcp-server 0.1.0 → 0.2.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.
- package/README.md +1 -1
- package/dist/api-client.d.ts +120 -2
- package/dist/api-client.js +51 -5
- package/dist/handlers/bodies-of-work.js +84 -50
- package/dist/handlers/cost.js +62 -54
- package/dist/handlers/decisions.js +29 -16
- package/dist/handlers/deployment.js +114 -107
- package/dist/handlers/discovery.d.ts +3 -0
- package/dist/handlers/discovery.js +55 -657
- package/dist/handlers/fallback.js +42 -28
- package/dist/handlers/file-checkouts.d.ts +18 -0
- package/dist/handlers/file-checkouts.js +101 -0
- package/dist/handlers/findings.d.ts +14 -1
- package/dist/handlers/findings.js +104 -28
- package/dist/handlers/git-issues.js +36 -32
- package/dist/handlers/ideas.js +44 -26
- package/dist/handlers/index.d.ts +2 -0
- package/dist/handlers/index.js +6 -0
- package/dist/handlers/milestones.js +34 -27
- package/dist/handlers/organizations.js +86 -78
- package/dist/handlers/progress.js +22 -11
- package/dist/handlers/project.js +62 -22
- package/dist/handlers/requests.js +15 -11
- package/dist/handlers/roles.d.ts +18 -0
- package/dist/handlers/roles.js +130 -0
- package/dist/handlers/session.js +52 -15
- package/dist/handlers/sprints.js +78 -65
- package/dist/handlers/tasks.js +135 -74
- package/dist/handlers/tool-docs.d.ts +4 -3
- package/dist/handlers/tool-docs.js +252 -5
- package/dist/handlers/validation.js +30 -14
- package/dist/index.js +25 -7
- package/dist/tools.js +417 -4
- package/package.json +1 -1
- package/src/api-client.ts +161 -8
- package/src/handlers/__test-setup__.ts +12 -0
- package/src/handlers/bodies-of-work.ts +127 -111
- package/src/handlers/cost.test.ts +34 -44
- package/src/handlers/cost.ts +77 -92
- package/src/handlers/decisions.test.ts +3 -2
- package/src/handlers/decisions.ts +32 -27
- package/src/handlers/deployment.ts +144 -190
- package/src/handlers/discovery.test.ts +4 -5
- package/src/handlers/discovery.ts +60 -746
- package/src/handlers/fallback.test.ts +78 -0
- package/src/handlers/fallback.ts +51 -38
- package/src/handlers/file-checkouts.test.ts +477 -0
- package/src/handlers/file-checkouts.ts +127 -0
- package/src/handlers/findings.test.ts +274 -2
- package/src/handlers/findings.ts +123 -57
- package/src/handlers/git-issues.ts +40 -80
- package/src/handlers/ideas.ts +56 -54
- package/src/handlers/index.ts +6 -0
- package/src/handlers/milestones.test.ts +1 -1
- package/src/handlers/milestones.ts +47 -45
- package/src/handlers/organizations.ts +104 -129
- package/src/handlers/progress.ts +24 -22
- package/src/handlers/project.ts +89 -57
- package/src/handlers/requests.ts +18 -14
- package/src/handlers/roles.test.ts +303 -0
- package/src/handlers/roles.ts +208 -0
- package/src/handlers/session.test.ts +37 -2
- package/src/handlers/session.ts +64 -21
- package/src/handlers/sprints.ts +114 -134
- package/src/handlers/tasks.test.ts +61 -0
- package/src/handlers/tasks.ts +170 -139
- package/src/handlers/tool-docs.ts +1024 -0
- package/src/handlers/validation.test.ts +53 -1
- package/src/handlers/validation.ts +32 -21
- package/src/index.ts +25 -7
- package/src/tools.ts +417 -4
- package/dist/config/tool-categories.d.ts +0 -31
- package/dist/config/tool-categories.js +0 -253
- package/dist/knowledge.d.ts +0 -6
- package/dist/knowledge.js +0 -218
- package/src/knowledge.ts +0 -230
package/dist/handlers/index.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export * from './organizations.js';
|
|
|
24
24
|
export * from './cost.js';
|
|
25
25
|
export * from './git-issues.js';
|
|
26
26
|
export * from './sprints.js';
|
|
27
|
+
export * from './file-checkouts.js';
|
|
28
|
+
export * from './roles.js';
|
|
27
29
|
import type { HandlerRegistry } from './types.js';
|
|
28
30
|
/**
|
|
29
31
|
* Build the complete handler registry from all modules
|
package/dist/handlers/index.js
CHANGED
|
@@ -24,6 +24,8 @@ export * from './organizations.js';
|
|
|
24
24
|
export * from './cost.js';
|
|
25
25
|
export * from './git-issues.js';
|
|
26
26
|
export * from './sprints.js';
|
|
27
|
+
export * from './file-checkouts.js';
|
|
28
|
+
export * from './roles.js';
|
|
27
29
|
import { milestoneHandlers } from './milestones.js';
|
|
28
30
|
import { sessionHandlers } from './session.js';
|
|
29
31
|
import { ideaHandlers } from './ideas.js';
|
|
@@ -43,6 +45,8 @@ import { organizationHandlers } from './organizations.js';
|
|
|
43
45
|
import { costHandlers } from './cost.js';
|
|
44
46
|
import { gitIssueHandlers } from './git-issues.js';
|
|
45
47
|
import { sprintHandlers } from './sprints.js';
|
|
48
|
+
import { fileCheckoutHandlers } from './file-checkouts.js';
|
|
49
|
+
import { roleHandlers } from './roles.js';
|
|
46
50
|
/**
|
|
47
51
|
* Build the complete handler registry from all modules
|
|
48
52
|
*/
|
|
@@ -67,5 +71,7 @@ export function buildHandlerRegistry() {
|
|
|
67
71
|
...costHandlers,
|
|
68
72
|
...gitIssueHandlers,
|
|
69
73
|
...sprintHandlers,
|
|
74
|
+
...fileCheckoutHandlers,
|
|
75
|
+
...roleHandlers,
|
|
70
76
|
};
|
|
71
77
|
}
|
|
@@ -10,13 +10,34 @@
|
|
|
10
10
|
*
|
|
11
11
|
* MIGRATED: Uses Vibescope API client instead of direct Supabase
|
|
12
12
|
*/
|
|
13
|
-
import {
|
|
13
|
+
import { parseArgs, uuidValidator, createEnumValidator, ValidationError, } from '../validators.js';
|
|
14
14
|
import { getApiClient } from '../api-client.js';
|
|
15
|
+
const VALID_MILESTONE_STATUSES = ['pending', 'in_progress', 'completed'];
|
|
16
|
+
// Argument schemas for type-safe parsing
|
|
17
|
+
const addMilestoneSchema = {
|
|
18
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
19
|
+
title: { type: 'string', required: true },
|
|
20
|
+
description: { type: 'string' },
|
|
21
|
+
order_index: { type: 'number' },
|
|
22
|
+
};
|
|
23
|
+
const updateMilestoneSchema = {
|
|
24
|
+
milestone_id: { type: 'string', required: true, validate: uuidValidator },
|
|
25
|
+
title: { type: 'string' },
|
|
26
|
+
description: { type: 'string' },
|
|
27
|
+
status: { type: 'string', validate: createEnumValidator(VALID_MILESTONE_STATUSES) },
|
|
28
|
+
order_index: { type: 'number' },
|
|
29
|
+
};
|
|
30
|
+
const completeMilestoneSchema = {
|
|
31
|
+
milestone_id: { type: 'string', required: true, validate: uuidValidator },
|
|
32
|
+
};
|
|
33
|
+
const deleteMilestoneSchema = {
|
|
34
|
+
milestone_id: { type: 'string', required: true, validate: uuidValidator },
|
|
35
|
+
};
|
|
36
|
+
const getMilestonesSchema = {
|
|
37
|
+
task_id: { type: 'string', required: true, validate: uuidValidator },
|
|
38
|
+
};
|
|
15
39
|
export const addMilestone = async (args, ctx) => {
|
|
16
|
-
const { task_id, title, description, order_index } = args;
|
|
17
|
-
validateRequired(task_id, 'task_id');
|
|
18
|
-
validateUUID(task_id, 'task_id');
|
|
19
|
-
validateRequired(title, 'title');
|
|
40
|
+
const { task_id, title, description, order_index } = parseArgs(args, addMilestoneSchema);
|
|
20
41
|
const { session } = ctx;
|
|
21
42
|
const apiClient = getApiClient();
|
|
22
43
|
const response = await apiClient.addMilestone(task_id, {
|
|
@@ -34,16 +55,8 @@ export const addMilestone = async (args, ctx) => {
|
|
|
34
55
|
},
|
|
35
56
|
};
|
|
36
57
|
};
|
|
37
|
-
export const updateMilestone = async (args,
|
|
38
|
-
const { milestone_id, title, description, status, order_index } = args;
|
|
39
|
-
validateRequired(milestone_id, 'milestone_id');
|
|
40
|
-
validateUUID(milestone_id, 'milestone_id');
|
|
41
|
-
// Validate status if provided
|
|
42
|
-
if (status !== undefined) {
|
|
43
|
-
if (!['pending', 'in_progress', 'completed'].includes(status)) {
|
|
44
|
-
throw new ValidationError('status must be pending, in_progress, or completed');
|
|
45
|
-
}
|
|
46
|
-
}
|
|
58
|
+
export const updateMilestone = async (args, _ctx) => {
|
|
59
|
+
const { milestone_id, title, description, status, order_index } = parseArgs(args, updateMilestoneSchema);
|
|
47
60
|
// Check that at least one field is provided
|
|
48
61
|
if (title === undefined && description === undefined && status === undefined && order_index === undefined) {
|
|
49
62
|
throw new ValidationError('At least one field to update is required');
|
|
@@ -65,10 +78,8 @@ export const updateMilestone = async (args, ctx) => {
|
|
|
65
78
|
},
|
|
66
79
|
};
|
|
67
80
|
};
|
|
68
|
-
export const completeMilestone = async (args,
|
|
69
|
-
const { milestone_id } = args;
|
|
70
|
-
validateRequired(milestone_id, 'milestone_id');
|
|
71
|
-
validateUUID(milestone_id, 'milestone_id');
|
|
81
|
+
export const completeMilestone = async (args, _ctx) => {
|
|
82
|
+
const { milestone_id } = parseArgs(args, completeMilestoneSchema);
|
|
72
83
|
const apiClient = getApiClient();
|
|
73
84
|
const response = await apiClient.completeMilestone(milestone_id);
|
|
74
85
|
if (!response.ok) {
|
|
@@ -81,10 +92,8 @@ export const completeMilestone = async (args, ctx) => {
|
|
|
81
92
|
},
|
|
82
93
|
};
|
|
83
94
|
};
|
|
84
|
-
export const deleteMilestone = async (args,
|
|
85
|
-
const { milestone_id } = args;
|
|
86
|
-
validateRequired(milestone_id, 'milestone_id');
|
|
87
|
-
validateUUID(milestone_id, 'milestone_id');
|
|
95
|
+
export const deleteMilestone = async (args, _ctx) => {
|
|
96
|
+
const { milestone_id } = parseArgs(args, deleteMilestoneSchema);
|
|
88
97
|
const apiClient = getApiClient();
|
|
89
98
|
const response = await apiClient.deleteMilestone(milestone_id);
|
|
90
99
|
if (!response.ok) {
|
|
@@ -97,10 +106,8 @@ export const deleteMilestone = async (args, ctx) => {
|
|
|
97
106
|
},
|
|
98
107
|
};
|
|
99
108
|
};
|
|
100
|
-
export const getMilestones = async (args,
|
|
101
|
-
const { task_id } = args;
|
|
102
|
-
validateRequired(task_id, 'task_id');
|
|
103
|
-
validateUUID(task_id, 'task_id');
|
|
109
|
+
export const getMilestones = async (args, _ctx) => {
|
|
110
|
+
const { task_id } = parseArgs(args, getMilestonesSchema);
|
|
104
111
|
const apiClient = getApiClient();
|
|
105
112
|
const response = await apiClient.getMilestones(task_id);
|
|
106
113
|
if (!response.ok) {
|
|
@@ -16,16 +16,71 @@
|
|
|
16
16
|
* - unshare_project
|
|
17
17
|
* - list_project_shares
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { parseArgs, uuidValidator, createEnumValidator, ValidationError } from '../validators.js';
|
|
20
20
|
import { getApiClient } from '../api-client.js';
|
|
21
21
|
// Valid roles in order of permission level
|
|
22
22
|
const ROLE_ORDER = ['viewer', 'member', 'admin', 'owner'];
|
|
23
|
+
const ASSIGNABLE_ROLES = ['viewer', 'member', 'admin'];
|
|
23
24
|
// Valid share permissions
|
|
24
25
|
const PERMISSION_ORDER = ['read', 'write', 'admin'];
|
|
25
26
|
// ============================================================================
|
|
27
|
+
// Argument Schemas
|
|
28
|
+
// ============================================================================
|
|
29
|
+
const createOrganizationSchema = {
|
|
30
|
+
name: { type: 'string', required: true },
|
|
31
|
+
description: { type: 'string' },
|
|
32
|
+
slug: { type: 'string' },
|
|
33
|
+
};
|
|
34
|
+
const updateOrganizationSchema = {
|
|
35
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
36
|
+
name: { type: 'string' },
|
|
37
|
+
description: { type: 'string' },
|
|
38
|
+
logo_url: { type: 'string' },
|
|
39
|
+
};
|
|
40
|
+
const deleteOrganizationSchema = {
|
|
41
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
42
|
+
};
|
|
43
|
+
const listOrgMembersSchema = {
|
|
44
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
45
|
+
};
|
|
46
|
+
const inviteMemberSchema = {
|
|
47
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
48
|
+
email: { type: 'string', required: true },
|
|
49
|
+
role: { type: 'string', default: 'member', validate: createEnumValidator(ASSIGNABLE_ROLES) },
|
|
50
|
+
};
|
|
51
|
+
const updateMemberRoleSchema = {
|
|
52
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
53
|
+
user_id: { type: 'string', required: true, validate: uuidValidator },
|
|
54
|
+
role: { type: 'string', required: true, validate: createEnumValidator(ROLE_ORDER) },
|
|
55
|
+
};
|
|
56
|
+
const removeMemberSchema = {
|
|
57
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
58
|
+
user_id: { type: 'string', required: true, validate: uuidValidator },
|
|
59
|
+
};
|
|
60
|
+
const leaveOrganizationSchema = {
|
|
61
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
62
|
+
};
|
|
63
|
+
const shareProjectWithOrgSchema = {
|
|
64
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
65
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
66
|
+
permission: { type: 'string', default: 'read', validate: createEnumValidator(PERMISSION_ORDER) },
|
|
67
|
+
};
|
|
68
|
+
const updateProjectShareSchema = {
|
|
69
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
70
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
71
|
+
permission: { type: 'string', required: true, validate: createEnumValidator(PERMISSION_ORDER) },
|
|
72
|
+
};
|
|
73
|
+
const unshareProjectSchema = {
|
|
74
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
75
|
+
organization_id: { type: 'string', required: true, validate: uuidValidator },
|
|
76
|
+
};
|
|
77
|
+
const listProjectSharesSchema = {
|
|
78
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
79
|
+
};
|
|
80
|
+
// ============================================================================
|
|
26
81
|
// Organization Management
|
|
27
82
|
// ============================================================================
|
|
28
|
-
export const listOrganizations = async (_args,
|
|
83
|
+
export const listOrganizations = async (_args, _ctx) => {
|
|
29
84
|
const apiClient = getApiClient();
|
|
30
85
|
const response = await apiClient.listOrganizations();
|
|
31
86
|
if (!response.ok) {
|
|
@@ -33,9 +88,8 @@ export const listOrganizations = async (_args, ctx) => {
|
|
|
33
88
|
}
|
|
34
89
|
return { result: response.data };
|
|
35
90
|
};
|
|
36
|
-
export const createOrganization = async (args,
|
|
37
|
-
const { name, description, slug } = args;
|
|
38
|
-
validateRequired(name, 'name');
|
|
91
|
+
export const createOrganization = async (args, _ctx) => {
|
|
92
|
+
const { name, description, slug } = parseArgs(args, createOrganizationSchema);
|
|
39
93
|
const apiClient = getApiClient();
|
|
40
94
|
const response = await apiClient.createOrganization({
|
|
41
95
|
name,
|
|
@@ -47,10 +101,12 @@ export const createOrganization = async (args, ctx) => {
|
|
|
47
101
|
}
|
|
48
102
|
return { result: response.data };
|
|
49
103
|
};
|
|
50
|
-
export const updateOrganization = async (args,
|
|
51
|
-
const { organization_id, name, description, logo_url } = args;
|
|
52
|
-
|
|
53
|
-
|
|
104
|
+
export const updateOrganization = async (args, _ctx) => {
|
|
105
|
+
const { organization_id, name, description, logo_url } = parseArgs(args, updateOrganizationSchema);
|
|
106
|
+
// Check that at least one update is provided
|
|
107
|
+
if (name === undefined && description === undefined && logo_url === undefined) {
|
|
108
|
+
throw new ValidationError('No updates provided');
|
|
109
|
+
}
|
|
54
110
|
const updates = {};
|
|
55
111
|
if (name !== undefined)
|
|
56
112
|
updates.name = name;
|
|
@@ -58,9 +114,6 @@ export const updateOrganization = async (args, ctx) => {
|
|
|
58
114
|
updates.description = description;
|
|
59
115
|
if (logo_url !== undefined)
|
|
60
116
|
updates.logo_url = logo_url;
|
|
61
|
-
if (Object.keys(updates).length === 0) {
|
|
62
|
-
throw new Error('No updates provided');
|
|
63
|
-
}
|
|
64
117
|
const apiClient = getApiClient();
|
|
65
118
|
const response = await apiClient.updateOrganization(organization_id, updates);
|
|
66
119
|
if (!response.ok) {
|
|
@@ -68,10 +121,8 @@ export const updateOrganization = async (args, ctx) => {
|
|
|
68
121
|
}
|
|
69
122
|
return { result: response.data };
|
|
70
123
|
};
|
|
71
|
-
export const deleteOrganization = async (args,
|
|
72
|
-
const { organization_id } = args;
|
|
73
|
-
validateRequired(organization_id, 'organization_id');
|
|
74
|
-
validateUUID(organization_id, 'organization_id');
|
|
124
|
+
export const deleteOrganization = async (args, _ctx) => {
|
|
125
|
+
const { organization_id } = parseArgs(args, deleteOrganizationSchema);
|
|
75
126
|
const apiClient = getApiClient();
|
|
76
127
|
const response = await apiClient.deleteOrganization(organization_id);
|
|
77
128
|
if (!response.ok) {
|
|
@@ -82,10 +133,8 @@ export const deleteOrganization = async (args, ctx) => {
|
|
|
82
133
|
// ============================================================================
|
|
83
134
|
// Member Management
|
|
84
135
|
// ============================================================================
|
|
85
|
-
export const listOrgMembers = async (args,
|
|
86
|
-
const { organization_id } = args;
|
|
87
|
-
validateRequired(organization_id, 'organization_id');
|
|
88
|
-
validateUUID(organization_id, 'organization_id');
|
|
136
|
+
export const listOrgMembers = async (args, _ctx) => {
|
|
137
|
+
const { organization_id } = parseArgs(args, listOrgMembersSchema);
|
|
89
138
|
const apiClient = getApiClient();
|
|
90
139
|
const response = await apiClient.listOrgMembers(organization_id);
|
|
91
140
|
if (!response.ok) {
|
|
@@ -93,14 +142,8 @@ export const listOrgMembers = async (args, ctx) => {
|
|
|
93
142
|
}
|
|
94
143
|
return { result: response.data };
|
|
95
144
|
};
|
|
96
|
-
export const inviteMember = async (args,
|
|
97
|
-
const { organization_id, email, role
|
|
98
|
-
validateRequired(organization_id, 'organization_id');
|
|
99
|
-
validateRequired(email, 'email');
|
|
100
|
-
validateUUID(organization_id, 'organization_id');
|
|
101
|
-
if (!['admin', 'member', 'viewer'].includes(role)) {
|
|
102
|
-
throw new Error('Invalid role. Must be admin, member, or viewer.');
|
|
103
|
-
}
|
|
145
|
+
export const inviteMember = async (args, _ctx) => {
|
|
146
|
+
const { organization_id, email, role } = parseArgs(args, inviteMemberSchema);
|
|
104
147
|
const apiClient = getApiClient();
|
|
105
148
|
const response = await apiClient.inviteMember(organization_id, email, role);
|
|
106
149
|
if (!response.ok) {
|
|
@@ -108,18 +151,10 @@ export const inviteMember = async (args, ctx) => {
|
|
|
108
151
|
}
|
|
109
152
|
return { result: response.data };
|
|
110
153
|
};
|
|
111
|
-
export const updateMemberRole = async (args,
|
|
112
|
-
const { organization_id, user_id, role } = args;
|
|
113
|
-
validateRequired(organization_id, 'organization_id');
|
|
114
|
-
validateRequired(user_id, 'user_id');
|
|
115
|
-
validateRequired(role, 'role');
|
|
116
|
-
validateUUID(organization_id, 'organization_id');
|
|
117
|
-
validateUUID(user_id, 'user_id');
|
|
118
|
-
if (!ROLE_ORDER.includes(role)) {
|
|
119
|
-
throw new Error(`Invalid role. Must be one of: ${ROLE_ORDER.join(', ')}`);
|
|
120
|
-
}
|
|
154
|
+
export const updateMemberRole = async (args, _ctx) => {
|
|
155
|
+
const { organization_id, user_id, role } = parseArgs(args, updateMemberRoleSchema);
|
|
121
156
|
if (role === 'owner') {
|
|
122
|
-
throw new
|
|
157
|
+
throw new ValidationError('Cannot assign owner role. Use transfer ownership instead.');
|
|
123
158
|
}
|
|
124
159
|
const apiClient = getApiClient();
|
|
125
160
|
const response = await apiClient.updateMemberRole(organization_id, user_id, role);
|
|
@@ -128,12 +163,8 @@ export const updateMemberRole = async (args, ctx) => {
|
|
|
128
163
|
}
|
|
129
164
|
return { result: response.data };
|
|
130
165
|
};
|
|
131
|
-
export const removeMember = async (args,
|
|
132
|
-
const { organization_id, user_id } = args;
|
|
133
|
-
validateRequired(organization_id, 'organization_id');
|
|
134
|
-
validateRequired(user_id, 'user_id');
|
|
135
|
-
validateUUID(organization_id, 'organization_id');
|
|
136
|
-
validateUUID(user_id, 'user_id');
|
|
166
|
+
export const removeMember = async (args, _ctx) => {
|
|
167
|
+
const { organization_id, user_id } = parseArgs(args, removeMemberSchema);
|
|
137
168
|
const apiClient = getApiClient();
|
|
138
169
|
const response = await apiClient.removeMember(organization_id, user_id);
|
|
139
170
|
if (!response.ok) {
|
|
@@ -141,10 +172,8 @@ export const removeMember = async (args, ctx) => {
|
|
|
141
172
|
}
|
|
142
173
|
return { result: response.data };
|
|
143
174
|
};
|
|
144
|
-
export const leaveOrganization = async (args,
|
|
145
|
-
const { organization_id } = args;
|
|
146
|
-
validateRequired(organization_id, 'organization_id');
|
|
147
|
-
validateUUID(organization_id, 'organization_id');
|
|
175
|
+
export const leaveOrganization = async (args, _ctx) => {
|
|
176
|
+
const { organization_id } = parseArgs(args, leaveOrganizationSchema);
|
|
148
177
|
const apiClient = getApiClient();
|
|
149
178
|
const response = await apiClient.leaveOrganization(organization_id);
|
|
150
179
|
if (!response.ok) {
|
|
@@ -155,15 +184,8 @@ export const leaveOrganization = async (args, ctx) => {
|
|
|
155
184
|
// ============================================================================
|
|
156
185
|
// Project Sharing
|
|
157
186
|
// ============================================================================
|
|
158
|
-
export const shareProjectWithOrg = async (args,
|
|
159
|
-
const { project_id, organization_id, permission
|
|
160
|
-
validateRequired(project_id, 'project_id');
|
|
161
|
-
validateRequired(organization_id, 'organization_id');
|
|
162
|
-
validateUUID(project_id, 'project_id');
|
|
163
|
-
validateUUID(organization_id, 'organization_id');
|
|
164
|
-
if (!PERMISSION_ORDER.includes(permission)) {
|
|
165
|
-
throw new Error(`Invalid permission. Must be one of: ${PERMISSION_ORDER.join(', ')}`);
|
|
166
|
-
}
|
|
187
|
+
export const shareProjectWithOrg = async (args, _ctx) => {
|
|
188
|
+
const { project_id, organization_id, permission } = parseArgs(args, shareProjectWithOrgSchema);
|
|
167
189
|
const apiClient = getApiClient();
|
|
168
190
|
const response = await apiClient.shareProjectWithOrg(project_id, organization_id, permission);
|
|
169
191
|
if (!response.ok) {
|
|
@@ -171,16 +193,8 @@ export const shareProjectWithOrg = async (args, ctx) => {
|
|
|
171
193
|
}
|
|
172
194
|
return { result: response.data };
|
|
173
195
|
};
|
|
174
|
-
export const updateProjectShare = async (args,
|
|
175
|
-
const { project_id, organization_id, permission } = args;
|
|
176
|
-
validateRequired(project_id, 'project_id');
|
|
177
|
-
validateRequired(organization_id, 'organization_id');
|
|
178
|
-
validateRequired(permission, 'permission');
|
|
179
|
-
validateUUID(project_id, 'project_id');
|
|
180
|
-
validateUUID(organization_id, 'organization_id');
|
|
181
|
-
if (!PERMISSION_ORDER.includes(permission)) {
|
|
182
|
-
throw new Error(`Invalid permission. Must be one of: ${PERMISSION_ORDER.join(', ')}`);
|
|
183
|
-
}
|
|
196
|
+
export const updateProjectShare = async (args, _ctx) => {
|
|
197
|
+
const { project_id, organization_id, permission } = parseArgs(args, updateProjectShareSchema);
|
|
184
198
|
const apiClient = getApiClient();
|
|
185
199
|
const response = await apiClient.updateProjectShare(project_id, organization_id, permission);
|
|
186
200
|
if (!response.ok) {
|
|
@@ -188,12 +202,8 @@ export const updateProjectShare = async (args, ctx) => {
|
|
|
188
202
|
}
|
|
189
203
|
return { result: response.data };
|
|
190
204
|
};
|
|
191
|
-
export const unshareProject = async (args,
|
|
192
|
-
const { project_id, organization_id } = args;
|
|
193
|
-
validateRequired(project_id, 'project_id');
|
|
194
|
-
validateRequired(organization_id, 'organization_id');
|
|
195
|
-
validateUUID(project_id, 'project_id');
|
|
196
|
-
validateUUID(organization_id, 'organization_id');
|
|
205
|
+
export const unshareProject = async (args, _ctx) => {
|
|
206
|
+
const { project_id, organization_id } = parseArgs(args, unshareProjectSchema);
|
|
197
207
|
const apiClient = getApiClient();
|
|
198
208
|
const response = await apiClient.unshareProject(project_id, organization_id);
|
|
199
209
|
if (!response.ok) {
|
|
@@ -201,10 +211,8 @@ export const unshareProject = async (args, ctx) => {
|
|
|
201
211
|
}
|
|
202
212
|
return { result: response.data };
|
|
203
213
|
};
|
|
204
|
-
export const listProjectShares = async (args,
|
|
205
|
-
const { project_id } = args;
|
|
206
|
-
validateRequired(project_id, 'project_id');
|
|
207
|
-
validateUUID(project_id, 'project_id');
|
|
214
|
+
export const listProjectShares = async (args, _ctx) => {
|
|
215
|
+
const { project_id } = parseArgs(args, listProjectSharesSchema);
|
|
208
216
|
const apiClient = getApiClient();
|
|
209
217
|
const response = await apiClient.listProjectShares(project_id);
|
|
210
218
|
if (!response.ok) {
|
|
@@ -7,13 +7,24 @@
|
|
|
7
7
|
*
|
|
8
8
|
* MIGRATED: Uses Vibescope API client instead of direct Supabase
|
|
9
9
|
*/
|
|
10
|
-
import {
|
|
10
|
+
import { parseArgs, uuidValidator } from '../validators.js';
|
|
11
11
|
import { getApiClient } from '../api-client.js';
|
|
12
|
+
// Argument schemas for type-safe parsing
|
|
13
|
+
const logProgressSchema = {
|
|
14
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
15
|
+
task_id: { type: 'string', validate: uuidValidator },
|
|
16
|
+
summary: { type: 'string', required: true },
|
|
17
|
+
details: { type: 'string' },
|
|
18
|
+
};
|
|
19
|
+
const getActivityFeedSchema = {
|
|
20
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
21
|
+
limit: { type: 'number', default: 50 },
|
|
22
|
+
since: { type: 'string' },
|
|
23
|
+
types: { type: 'array' },
|
|
24
|
+
created_by: { type: 'string' },
|
|
25
|
+
};
|
|
12
26
|
export const logProgress = async (args, ctx) => {
|
|
13
|
-
const { project_id, task_id, summary, details } = args;
|
|
14
|
-
validateRequired(project_id, 'project_id');
|
|
15
|
-
validateUUID(project_id, 'project_id');
|
|
16
|
-
validateRequired(summary, 'summary');
|
|
27
|
+
const { project_id, task_id, summary, details } = parseArgs(args, logProgressSchema);
|
|
17
28
|
const { session } = ctx;
|
|
18
29
|
const apiClient = getApiClient();
|
|
19
30
|
const response = await apiClient.logProgress(project_id, {
|
|
@@ -27,15 +38,15 @@ export const logProgress = async (args, ctx) => {
|
|
|
27
38
|
}
|
|
28
39
|
return { result: { success: true, progress_id: response.data?.progress_id } };
|
|
29
40
|
};
|
|
30
|
-
export const getActivityFeed = async (args,
|
|
31
|
-
const { project_id, limit
|
|
32
|
-
validateRequired(project_id, 'project_id');
|
|
33
|
-
validateUUID(project_id, 'project_id');
|
|
41
|
+
export const getActivityFeed = async (args, _ctx) => {
|
|
42
|
+
const { project_id, limit, since, types, created_by } = parseArgs(args, getActivityFeedSchema);
|
|
34
43
|
const apiClient = getApiClient();
|
|
35
|
-
const effectiveLimit = Math.min(limit, 200);
|
|
44
|
+
const effectiveLimit = Math.min(limit ?? 50, 200);
|
|
36
45
|
const response = await apiClient.getActivityFeed(project_id, {
|
|
37
46
|
limit: effectiveLimit,
|
|
38
|
-
since
|
|
47
|
+
since,
|
|
48
|
+
types: types,
|
|
49
|
+
created_by
|
|
39
50
|
});
|
|
40
51
|
if (!response.ok) {
|
|
41
52
|
throw new Error(`Failed to fetch activity feed: ${response.error}`);
|
package/dist/handlers/project.js
CHANGED
|
@@ -8,10 +8,46 @@
|
|
|
8
8
|
* - update_project
|
|
9
9
|
* - update_project_readme
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { parseArgs, uuidValidator, projectStatusValidator, createEnumValidator, } from '../validators.js';
|
|
12
12
|
import { getApiClient } from '../api-client.js';
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const VALID_GIT_WORKFLOWS = ['none', 'trunk-based', 'github-flow', 'git-flow'];
|
|
14
|
+
// Argument schemas for type-safe parsing
|
|
15
|
+
const getProjectContextSchema = {
|
|
16
|
+
project_id: { type: 'string', validate: uuidValidator },
|
|
17
|
+
git_url: { type: 'string' },
|
|
18
|
+
};
|
|
19
|
+
const getGitWorkflowSchema = {
|
|
20
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
21
|
+
task_id: { type: 'string', validate: uuidValidator },
|
|
22
|
+
};
|
|
23
|
+
const createProjectSchema = {
|
|
24
|
+
name: { type: 'string', required: true },
|
|
25
|
+
description: { type: 'string' },
|
|
26
|
+
goal: { type: 'string' },
|
|
27
|
+
git_url: { type: 'string' },
|
|
28
|
+
tech_stack: { type: 'array' },
|
|
29
|
+
};
|
|
30
|
+
const updateProjectSchema = {
|
|
31
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
32
|
+
name: { type: 'string' },
|
|
33
|
+
description: { type: 'string' },
|
|
34
|
+
goal: { type: 'string' },
|
|
35
|
+
git_url: { type: 'string' },
|
|
36
|
+
tech_stack: { type: 'array' },
|
|
37
|
+
status: { type: 'string', validate: projectStatusValidator },
|
|
38
|
+
git_workflow: { type: 'string', validate: createEnumValidator(VALID_GIT_WORKFLOWS) },
|
|
39
|
+
git_main_branch: { type: 'string' },
|
|
40
|
+
git_develop_branch: { type: 'string' },
|
|
41
|
+
git_auto_branch: { type: 'boolean' },
|
|
42
|
+
git_auto_tag: { type: 'boolean' },
|
|
43
|
+
deployment_instructions: { type: 'string' },
|
|
44
|
+
};
|
|
45
|
+
const updateProjectReadmeSchema = {
|
|
46
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
47
|
+
readme_content: { type: 'string', required: true },
|
|
48
|
+
};
|
|
49
|
+
export const getProjectContext = async (args, _ctx) => {
|
|
50
|
+
const { project_id, git_url } = parseArgs(args, getProjectContextSchema);
|
|
15
51
|
const apiClient = getApiClient();
|
|
16
52
|
// If no project_id or git_url, list all projects
|
|
17
53
|
if (!project_id && !git_url) {
|
|
@@ -36,10 +72,8 @@ export const getProjectContext = async (args, ctx) => {
|
|
|
36
72
|
}
|
|
37
73
|
return { result: response.data };
|
|
38
74
|
};
|
|
39
|
-
export const getGitWorkflow = async (args,
|
|
40
|
-
const { project_id, task_id } = args;
|
|
41
|
-
validateRequired(project_id, 'project_id');
|
|
42
|
-
validateUUID(project_id, 'project_id');
|
|
75
|
+
export const getGitWorkflow = async (args, _ctx) => {
|
|
76
|
+
const { project_id, task_id } = parseArgs(args, getGitWorkflowSchema);
|
|
43
77
|
const apiClient = getApiClient();
|
|
44
78
|
const response = await apiClient.getGitWorkflow(project_id, task_id);
|
|
45
79
|
if (!response.ok) {
|
|
@@ -47,39 +81,45 @@ export const getGitWorkflow = async (args, ctx) => {
|
|
|
47
81
|
}
|
|
48
82
|
return { result: response.data };
|
|
49
83
|
};
|
|
50
|
-
export const createProject = async (args,
|
|
51
|
-
const { name, description, goal, git_url, tech_stack } = args;
|
|
52
|
-
validateRequired(name, 'name');
|
|
84
|
+
export const createProject = async (args, _ctx) => {
|
|
85
|
+
const { name, description, goal, git_url, tech_stack } = parseArgs(args, createProjectSchema);
|
|
53
86
|
const apiClient = getApiClient();
|
|
54
87
|
const response = await apiClient.createProject({
|
|
55
88
|
name,
|
|
56
89
|
description,
|
|
57
90
|
goal,
|
|
58
91
|
git_url,
|
|
59
|
-
tech_stack
|
|
92
|
+
tech_stack: tech_stack
|
|
60
93
|
});
|
|
61
94
|
if (!response.ok) {
|
|
62
95
|
throw new Error(response.error || 'Failed to create project');
|
|
63
96
|
}
|
|
64
97
|
return { result: response.data };
|
|
65
98
|
};
|
|
66
|
-
export const updateProject = async (args,
|
|
67
|
-
const { project_id,
|
|
68
|
-
validateRequired(project_id, 'project_id');
|
|
69
|
-
validateUUID(project_id, 'project_id');
|
|
70
|
-
validateProjectStatus(updates.status);
|
|
99
|
+
export const updateProject = async (args, _ctx) => {
|
|
100
|
+
const { project_id, name, description, goal, git_url, tech_stack, status, git_workflow, git_main_branch, git_develop_branch, git_auto_branch, git_auto_tag, deployment_instructions } = parseArgs(args, updateProjectSchema);
|
|
71
101
|
const apiClient = getApiClient();
|
|
72
|
-
const response = await apiClient.updateProject(project_id,
|
|
102
|
+
const response = await apiClient.updateProject(project_id, {
|
|
103
|
+
name,
|
|
104
|
+
description,
|
|
105
|
+
goal,
|
|
106
|
+
git_url,
|
|
107
|
+
tech_stack: tech_stack,
|
|
108
|
+
status: status,
|
|
109
|
+
git_workflow: git_workflow,
|
|
110
|
+
git_main_branch,
|
|
111
|
+
git_develop_branch,
|
|
112
|
+
git_auto_branch,
|
|
113
|
+
git_auto_tag,
|
|
114
|
+
deployment_instructions
|
|
115
|
+
});
|
|
73
116
|
if (!response.ok) {
|
|
74
117
|
throw new Error(response.error || 'Failed to update project');
|
|
75
118
|
}
|
|
76
119
|
return { result: response.data };
|
|
77
120
|
};
|
|
78
|
-
export const updateProjectReadme = async (args,
|
|
79
|
-
const { project_id, readme_content } = args;
|
|
80
|
-
validateRequired(project_id, 'project_id');
|
|
81
|
-
validateUUID(project_id, 'project_id');
|
|
82
|
-
validateRequired(readme_content, 'readme_content');
|
|
121
|
+
export const updateProjectReadme = async (args, _ctx) => {
|
|
122
|
+
const { project_id, readme_content } = parseArgs(args, updateProjectReadmeSchema);
|
|
83
123
|
const apiClient = getApiClient();
|
|
84
124
|
const response = await apiClient.updateProjectReadme(project_id, readme_content);
|
|
85
125
|
if (!response.ok) {
|
|
@@ -8,12 +8,21 @@
|
|
|
8
8
|
*
|
|
9
9
|
* MIGRATED: Uses Vibescope API client instead of direct Supabase
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { parseArgs, uuidValidator } from '../validators.js';
|
|
12
12
|
import { getApiClient } from '../api-client.js';
|
|
13
|
+
// Argument schemas for type-safe parsing
|
|
14
|
+
const getPendingRequestsSchema = {
|
|
15
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
16
|
+
};
|
|
17
|
+
const acknowledgeRequestSchema = {
|
|
18
|
+
request_id: { type: 'string', required: true, validate: uuidValidator },
|
|
19
|
+
};
|
|
20
|
+
const answerQuestionSchema = {
|
|
21
|
+
request_id: { type: 'string', required: true, validate: uuidValidator },
|
|
22
|
+
answer: { type: 'string', required: true },
|
|
23
|
+
};
|
|
13
24
|
export const getPendingRequests = async (args, ctx) => {
|
|
14
|
-
const { project_id } = args;
|
|
15
|
-
validateRequired(project_id, 'project_id');
|
|
16
|
-
validateUUID(project_id, 'project_id');
|
|
25
|
+
const { project_id } = parseArgs(args, getPendingRequestsSchema);
|
|
17
26
|
const { session } = ctx;
|
|
18
27
|
const apiClient = getApiClient();
|
|
19
28
|
const response = await apiClient.getPendingRequests(project_id, session.currentSessionId || undefined);
|
|
@@ -28,9 +37,7 @@ export const getPendingRequests = async (args, ctx) => {
|
|
|
28
37
|
};
|
|
29
38
|
};
|
|
30
39
|
export const acknowledgeRequest = async (args, ctx) => {
|
|
31
|
-
const { request_id } = args;
|
|
32
|
-
validateRequired(request_id, 'request_id');
|
|
33
|
-
validateUUID(request_id, 'request_id');
|
|
40
|
+
const { request_id } = parseArgs(args, acknowledgeRequestSchema);
|
|
34
41
|
const { session } = ctx;
|
|
35
42
|
const apiClient = getApiClient();
|
|
36
43
|
const response = await apiClient.acknowledgeRequest(request_id, session.currentSessionId || undefined);
|
|
@@ -44,10 +51,7 @@ export const acknowledgeRequest = async (args, ctx) => {
|
|
|
44
51
|
};
|
|
45
52
|
};
|
|
46
53
|
export const answerQuestion = async (args, ctx) => {
|
|
47
|
-
const { request_id, answer } = args;
|
|
48
|
-
validateRequired(request_id, 'request_id');
|
|
49
|
-
validateRequired(answer, 'answer');
|
|
50
|
-
validateUUID(request_id, 'request_id');
|
|
54
|
+
const { request_id, answer } = parseArgs(args, answerQuestionSchema);
|
|
51
55
|
const { session } = ctx;
|
|
52
56
|
const apiClient = getApiClient();
|
|
53
57
|
const response = await apiClient.answerQuestion(request_id, answer, session.currentSessionId || undefined);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Management Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handles agent role configuration and assignment:
|
|
5
|
+
* - get_role_settings: Get role configuration for a project
|
|
6
|
+
* - update_role_settings: Update role settings for a project
|
|
7
|
+
* - set_session_role: Set the role for the current session
|
|
8
|
+
* - get_agents_by_role: Get active agents grouped by their assigned roles
|
|
9
|
+
*/
|
|
10
|
+
import type { Handler, HandlerRegistry } from './types.js';
|
|
11
|
+
export declare const getRoleSettings: Handler;
|
|
12
|
+
export declare const updateRoleSettings: Handler;
|
|
13
|
+
export declare const setSessionRole: Handler;
|
|
14
|
+
export declare const getAgentsByRole: Handler;
|
|
15
|
+
/**
|
|
16
|
+
* Role handlers registry
|
|
17
|
+
*/
|
|
18
|
+
export declare const roleHandlers: HandlerRegistry;
|