@vibescope/mcp-server 0.2.1 → 0.2.2
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 +60 -7
- package/dist/api-client.d.ts +187 -0
- package/dist/api-client.js +48 -0
- package/dist/handlers/blockers.js +9 -8
- package/dist/handlers/bodies-of-work.js +14 -14
- package/dist/handlers/connectors.d.ts +45 -0
- package/dist/handlers/connectors.js +183 -0
- package/dist/handlers/cost.d.ts +10 -0
- package/dist/handlers/cost.js +54 -0
- package/dist/handlers/decisions.js +3 -3
- package/dist/handlers/deployment.js +35 -19
- package/dist/handlers/discovery.d.ts +7 -0
- package/dist/handlers/discovery.js +61 -2
- package/dist/handlers/fallback.js +5 -4
- package/dist/handlers/file-checkouts.d.ts +2 -0
- package/dist/handlers/file-checkouts.js +38 -6
- package/dist/handlers/findings.js +13 -12
- package/dist/handlers/git-issues.js +4 -4
- package/dist/handlers/ideas.js +5 -5
- package/dist/handlers/index.d.ts +1 -0
- package/dist/handlers/index.js +3 -0
- package/dist/handlers/milestones.js +5 -5
- package/dist/handlers/organizations.js +13 -13
- package/dist/handlers/progress.js +2 -2
- package/dist/handlers/project.js +6 -6
- package/dist/handlers/requests.js +3 -3
- package/dist/handlers/session.js +28 -9
- package/dist/handlers/sprints.js +17 -17
- package/dist/handlers/tasks.d.ts +2 -0
- package/dist/handlers/tasks.js +78 -20
- package/dist/handlers/types.d.ts +64 -2
- package/dist/handlers/types.js +48 -1
- package/dist/handlers/validation.js +3 -3
- package/dist/index.js +7 -2716
- package/dist/token-tracking.d.ts +74 -0
- package/dist/token-tracking.js +122 -0
- package/dist/tools.js +298 -9
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +17 -0
- package/docs/TOOLS.md +2053 -0
- package/package.json +4 -1
- package/scripts/generate-docs.ts +212 -0
- package/src/api-client.test.ts +718 -0
- package/src/api-client.ts +231 -0
- package/src/handlers/__test-setup__.ts +9 -0
- package/src/handlers/blockers.test.ts +31 -19
- package/src/handlers/blockers.ts +9 -8
- package/src/handlers/bodies-of-work.test.ts +55 -32
- package/src/handlers/bodies-of-work.ts +14 -14
- package/src/handlers/connectors.test.ts +834 -0
- package/src/handlers/connectors.ts +229 -0
- package/src/handlers/cost.ts +66 -0
- package/src/handlers/decisions.test.ts +34 -25
- package/src/handlers/decisions.ts +3 -3
- package/src/handlers/deployment.ts +39 -19
- package/src/handlers/discovery.ts +61 -2
- package/src/handlers/fallback.test.ts +26 -22
- package/src/handlers/fallback.ts +5 -4
- package/src/handlers/file-checkouts.test.ts +242 -49
- package/src/handlers/file-checkouts.ts +44 -6
- package/src/handlers/findings.test.ts +38 -24
- package/src/handlers/findings.ts +13 -12
- package/src/handlers/git-issues.test.ts +51 -43
- package/src/handlers/git-issues.ts +4 -4
- package/src/handlers/ideas.test.ts +28 -23
- package/src/handlers/ideas.ts +5 -5
- package/src/handlers/index.ts +3 -0
- package/src/handlers/milestones.test.ts +33 -28
- package/src/handlers/milestones.ts +5 -5
- package/src/handlers/organizations.test.ts +104 -83
- package/src/handlers/organizations.ts +13 -13
- package/src/handlers/progress.test.ts +20 -14
- package/src/handlers/progress.ts +2 -2
- package/src/handlers/project.test.ts +34 -27
- package/src/handlers/project.ts +6 -6
- package/src/handlers/requests.test.ts +27 -18
- package/src/handlers/requests.ts +3 -3
- package/src/handlers/session.test.ts +47 -0
- package/src/handlers/session.ts +32 -9
- package/src/handlers/sprints.test.ts +71 -50
- package/src/handlers/sprints.ts +17 -17
- package/src/handlers/tasks.test.ts +77 -15
- package/src/handlers/tasks.ts +90 -21
- package/src/handlers/tool-categories.test.ts +66 -0
- package/src/handlers/types.ts +81 -2
- package/src/handlers/validation.test.ts +78 -45
- package/src/handlers/validation.ts +3 -3
- package/src/index.ts +12 -2732
- package/src/token-tracking.test.ts +453 -0
- package/src/token-tracking.ts +164 -0
- package/src/tools.ts +298 -9
- package/src/utils.test.ts +2 -2
- package/src/utils.ts +17 -0
|
@@ -6,12 +6,14 @@
|
|
|
6
6
|
* - checkin_file: Check in a file after editing
|
|
7
7
|
* - get_file_checkouts: Get active checkouts for a project
|
|
8
8
|
* - abandon_checkout: Force release a checkout
|
|
9
|
+
* - is_file_available: Check if a file is available for checkout
|
|
9
10
|
*/
|
|
10
11
|
import type { Handler, HandlerRegistry } from './types.js';
|
|
11
12
|
export declare const checkoutFile: Handler;
|
|
12
13
|
export declare const checkinFile: Handler;
|
|
13
14
|
export declare const getFileCheckouts: Handler;
|
|
14
15
|
export declare const abandonCheckout: Handler;
|
|
16
|
+
export declare const isFileAvailable: Handler;
|
|
15
17
|
/**
|
|
16
18
|
* File Checkouts handlers registry
|
|
17
19
|
*/
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* - checkin_file: Check in a file after editing
|
|
7
7
|
* - get_file_checkouts: Get active checkouts for a project
|
|
8
8
|
* - abandon_checkout: Force release a checkout
|
|
9
|
+
* - is_file_available: Check if a file is available for checkout
|
|
9
10
|
*/
|
|
10
11
|
import { parseArgs, uuidValidator, createEnumValidator } from '../validators.js';
|
|
11
12
|
import { getApiClient } from '../api-client.js';
|
|
@@ -33,12 +34,16 @@ const abandonCheckoutSchema = {
|
|
|
33
34
|
project_id: { type: 'string', validate: uuidValidator },
|
|
34
35
|
file_path: { type: 'string' },
|
|
35
36
|
};
|
|
37
|
+
const isFileAvailableSchema = {
|
|
38
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
39
|
+
file_path: { type: 'string', required: true },
|
|
40
|
+
};
|
|
36
41
|
export const checkoutFile = async (args, ctx) => {
|
|
37
42
|
const { project_id, file_path, reason } = parseArgs(args, checkoutFileSchema);
|
|
38
43
|
const apiClient = getApiClient();
|
|
39
44
|
const response = await apiClient.checkoutFile(project_id, file_path, reason, ctx.session.currentSessionId || undefined);
|
|
40
45
|
if (!response.ok) {
|
|
41
|
-
|
|
46
|
+
return { result: { error: response.error || 'Failed to checkout file' }, isError: true };
|
|
42
47
|
}
|
|
43
48
|
return { result: response.data };
|
|
44
49
|
};
|
|
@@ -46,7 +51,7 @@ export const checkinFile = async (args, ctx) => {
|
|
|
46
51
|
const { checkout_id, project_id, file_path, summary } = parseArgs(args, checkinFileSchema);
|
|
47
52
|
// Validate that either checkout_id or both project_id and file_path are provided
|
|
48
53
|
if (!checkout_id && (!project_id || !file_path)) {
|
|
49
|
-
|
|
54
|
+
return { result: { error: 'Either checkout_id or both project_id and file_path are required' }, isError: true };
|
|
50
55
|
}
|
|
51
56
|
const apiClient = getApiClient();
|
|
52
57
|
const response = await apiClient.checkinFile({
|
|
@@ -56,7 +61,7 @@ export const checkinFile = async (args, ctx) => {
|
|
|
56
61
|
summary
|
|
57
62
|
}, ctx.session.currentSessionId || undefined);
|
|
58
63
|
if (!response.ok) {
|
|
59
|
-
|
|
64
|
+
return { result: { error: response.error || 'Failed to checkin file' }, isError: true };
|
|
60
65
|
}
|
|
61
66
|
return { result: response.data };
|
|
62
67
|
};
|
|
@@ -69,7 +74,7 @@ export const getFileCheckouts = async (args, _ctx) => {
|
|
|
69
74
|
limit
|
|
70
75
|
});
|
|
71
76
|
if (!response.ok) {
|
|
72
|
-
|
|
77
|
+
return { result: { error: response.error || 'Failed to get file checkouts' }, isError: true };
|
|
73
78
|
}
|
|
74
79
|
return { result: response.data };
|
|
75
80
|
};
|
|
@@ -77,7 +82,7 @@ export const abandonCheckout = async (args, _ctx) => {
|
|
|
77
82
|
const { checkout_id, project_id, file_path } = parseArgs(args, abandonCheckoutSchema);
|
|
78
83
|
// Validate that either checkout_id or both project_id and file_path are provided
|
|
79
84
|
if (!checkout_id && (!project_id || !file_path)) {
|
|
80
|
-
|
|
85
|
+
return { result: { error: 'Either checkout_id or both project_id and file_path are required' }, isError: true };
|
|
81
86
|
}
|
|
82
87
|
const apiClient = getApiClient();
|
|
83
88
|
const response = await apiClient.abandonCheckout({
|
|
@@ -86,10 +91,36 @@ export const abandonCheckout = async (args, _ctx) => {
|
|
|
86
91
|
file_path
|
|
87
92
|
});
|
|
88
93
|
if (!response.ok) {
|
|
89
|
-
|
|
94
|
+
return { result: { error: response.error || 'Failed to abandon checkout' }, isError: true };
|
|
90
95
|
}
|
|
91
96
|
return { result: response.data };
|
|
92
97
|
};
|
|
98
|
+
export const isFileAvailable = async (args, _ctx) => {
|
|
99
|
+
const { project_id, file_path } = parseArgs(args, isFileAvailableSchema);
|
|
100
|
+
const apiClient = getApiClient();
|
|
101
|
+
const response = await apiClient.getFileCheckouts(project_id, {
|
|
102
|
+
status: 'checked_out',
|
|
103
|
+
file_path,
|
|
104
|
+
limit: 1
|
|
105
|
+
});
|
|
106
|
+
if (!response.ok) {
|
|
107
|
+
return { result: { error: response.error || 'Failed to check file availability' }, isError: true };
|
|
108
|
+
}
|
|
109
|
+
const checkouts = response.data?.checkouts || [];
|
|
110
|
+
const activeCheckout = checkouts.length > 0 ? checkouts[0] : null;
|
|
111
|
+
return {
|
|
112
|
+
result: {
|
|
113
|
+
available: !activeCheckout,
|
|
114
|
+
file_path,
|
|
115
|
+
checked_out_by: activeCheckout ? {
|
|
116
|
+
checkout_id: activeCheckout.id,
|
|
117
|
+
checked_out_by: activeCheckout.checked_out_by,
|
|
118
|
+
checked_out_at: activeCheckout.checked_out_at,
|
|
119
|
+
reason: activeCheckout.checkout_reason
|
|
120
|
+
} : null
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
};
|
|
93
124
|
/**
|
|
94
125
|
* File Checkouts handlers registry
|
|
95
126
|
*/
|
|
@@ -98,4 +129,5 @@ export const fileCheckoutHandlers = {
|
|
|
98
129
|
checkin_file: checkinFile,
|
|
99
130
|
get_file_checkouts: getFileCheckouts,
|
|
100
131
|
abandon_checkout: abandonCheckout,
|
|
132
|
+
is_file_available: isFileAvailable,
|
|
101
133
|
};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - update_finding
|
|
9
9
|
* - delete_finding
|
|
10
10
|
*/
|
|
11
|
+
import { success, error } from './types.js';
|
|
11
12
|
import { parseArgs, uuidValidator, createEnumValidator } from '../validators.js';
|
|
12
13
|
import { getApiClient } from '../api-client.js';
|
|
13
14
|
const VALID_FINDING_CATEGORIES = ['performance', 'security', 'code_quality', 'accessibility', 'documentation', 'architecture', 'testing', 'other'];
|
|
@@ -69,9 +70,9 @@ export const addFinding = async (args, ctx) => {
|
|
|
69
70
|
related_task_id
|
|
70
71
|
}, ctx.session.currentSessionId || undefined);
|
|
71
72
|
if (!response.ok) {
|
|
72
|
-
|
|
73
|
+
return error(response.error || 'Failed to add finding');
|
|
73
74
|
}
|
|
74
|
-
return
|
|
75
|
+
return success(response.data);
|
|
75
76
|
};
|
|
76
77
|
export const getFindings = async (args, _ctx) => {
|
|
77
78
|
const { project_id, category, severity, status, limit, offset, search_query, summary_only } = parseArgs(args, getFindingsSchema);
|
|
@@ -86,9 +87,9 @@ export const getFindings = async (args, _ctx) => {
|
|
|
86
87
|
summary_only
|
|
87
88
|
});
|
|
88
89
|
if (!response.ok) {
|
|
89
|
-
|
|
90
|
+
return error(response.error || 'Failed to get findings');
|
|
90
91
|
}
|
|
91
|
-
return
|
|
92
|
+
return success(response.data);
|
|
92
93
|
};
|
|
93
94
|
/**
|
|
94
95
|
* Get aggregate statistics about findings for a project.
|
|
@@ -100,9 +101,9 @@ export const getFindingsStats = async (args, _ctx) => {
|
|
|
100
101
|
const apiClient = getApiClient();
|
|
101
102
|
const response = await apiClient.getFindingsStats(project_id);
|
|
102
103
|
if (!response.ok) {
|
|
103
|
-
|
|
104
|
+
return error(response.error || 'Failed to get findings stats');
|
|
104
105
|
}
|
|
105
|
-
return
|
|
106
|
+
return success(response.data);
|
|
106
107
|
};
|
|
107
108
|
export const updateFinding = async (args, _ctx) => {
|
|
108
109
|
const { finding_id, title, description, severity, status, resolution_note } = parseArgs(args, updateFindingSchema);
|
|
@@ -115,18 +116,18 @@ export const updateFinding = async (args, _ctx) => {
|
|
|
115
116
|
resolution_note
|
|
116
117
|
});
|
|
117
118
|
if (!response.ok) {
|
|
118
|
-
|
|
119
|
+
return error(response.error || 'Failed to update finding');
|
|
119
120
|
}
|
|
120
|
-
return
|
|
121
|
+
return success(response.data);
|
|
121
122
|
};
|
|
122
123
|
export const deleteFinding = async (args, _ctx) => {
|
|
123
124
|
const { finding_id } = parseArgs(args, deleteFindingSchema);
|
|
124
125
|
const apiClient = getApiClient();
|
|
125
126
|
const response = await apiClient.deleteFinding(finding_id);
|
|
126
127
|
if (!response.ok) {
|
|
127
|
-
|
|
128
|
+
return error(response.error || 'Failed to delete finding');
|
|
128
129
|
}
|
|
129
|
-
return
|
|
130
|
+
return success(response.data);
|
|
130
131
|
};
|
|
131
132
|
/**
|
|
132
133
|
* Query aggregated project knowledge in a single call.
|
|
@@ -145,9 +146,9 @@ export const queryKnowledgeBase = async (args, _ctx) => {
|
|
|
145
146
|
search_query
|
|
146
147
|
});
|
|
147
148
|
if (!response.ok) {
|
|
148
|
-
|
|
149
|
+
return error(response.error || 'Failed to query knowledge base');
|
|
149
150
|
}
|
|
150
|
-
return
|
|
151
|
+
return success(response.data);
|
|
151
152
|
};
|
|
152
153
|
/**
|
|
153
154
|
* Findings handlers registry
|
|
@@ -56,7 +56,7 @@ export const addGitIssue = async (args, ctx) => {
|
|
|
56
56
|
task_id
|
|
57
57
|
}, ctx.session.currentSessionId || undefined);
|
|
58
58
|
if (!response.ok) {
|
|
59
|
-
|
|
59
|
+
return { result: { error: response.error || 'Failed to add git issue' }, isError: true };
|
|
60
60
|
}
|
|
61
61
|
return { result: response.data };
|
|
62
62
|
};
|
|
@@ -68,7 +68,7 @@ export const resolveGitIssue = async (args, ctx) => {
|
|
|
68
68
|
auto_resolved
|
|
69
69
|
}, ctx.session.currentSessionId || undefined);
|
|
70
70
|
if (!response.ok) {
|
|
71
|
-
|
|
71
|
+
return { result: { error: response.error || 'Failed to resolve git issue' }, isError: true };
|
|
72
72
|
}
|
|
73
73
|
return { result: response.data };
|
|
74
74
|
};
|
|
@@ -82,7 +82,7 @@ export const getGitIssues = async (args, _ctx) => {
|
|
|
82
82
|
limit
|
|
83
83
|
});
|
|
84
84
|
if (!response.ok) {
|
|
85
|
-
|
|
85
|
+
return { result: { error: response.error || 'Failed to fetch git issues' }, isError: true };
|
|
86
86
|
}
|
|
87
87
|
return { result: response.data };
|
|
88
88
|
};
|
|
@@ -91,7 +91,7 @@ export const deleteGitIssue = async (args, _ctx) => {
|
|
|
91
91
|
const apiClient = getApiClient();
|
|
92
92
|
const response = await apiClient.deleteGitIssue(git_issue_id);
|
|
93
93
|
if (!response.ok) {
|
|
94
|
-
|
|
94
|
+
return { result: { error: response.error || 'Failed to delete git issue' }, isError: true };
|
|
95
95
|
}
|
|
96
96
|
return { result: response.data };
|
|
97
97
|
};
|
package/dist/handlers/ideas.js
CHANGED
|
@@ -53,7 +53,7 @@ export const addIdea = async (args, ctx) => {
|
|
|
53
53
|
status: status
|
|
54
54
|
}, session.currentSessionId || undefined);
|
|
55
55
|
if (!response.ok) {
|
|
56
|
-
|
|
56
|
+
return { result: { error: response.error || 'Failed to add idea' }, isError: true };
|
|
57
57
|
}
|
|
58
58
|
return { result: { success: true, idea_id: response.data?.idea_id, title } };
|
|
59
59
|
};
|
|
@@ -67,7 +67,7 @@ export const updateIdea = async (args, _ctx) => {
|
|
|
67
67
|
doc_url
|
|
68
68
|
});
|
|
69
69
|
if (!response.ok) {
|
|
70
|
-
|
|
70
|
+
return { result: { error: response.error || 'Failed to update idea' }, isError: true };
|
|
71
71
|
}
|
|
72
72
|
return { result: { success: true, idea_id } };
|
|
73
73
|
};
|
|
@@ -81,7 +81,7 @@ export const getIdeas = async (args, _ctx) => {
|
|
|
81
81
|
search_query
|
|
82
82
|
});
|
|
83
83
|
if (!response.ok) {
|
|
84
|
-
|
|
84
|
+
return { result: { error: response.error || 'Failed to fetch ideas' }, isError: true };
|
|
85
85
|
}
|
|
86
86
|
return {
|
|
87
87
|
result: {
|
|
@@ -94,7 +94,7 @@ export const deleteIdea = async (args, _ctx) => {
|
|
|
94
94
|
const apiClient = getApiClient();
|
|
95
95
|
const response = await apiClient.deleteIdea(idea_id);
|
|
96
96
|
if (!response.ok) {
|
|
97
|
-
|
|
97
|
+
return { result: { error: response.error || 'Failed to delete idea' }, isError: true };
|
|
98
98
|
}
|
|
99
99
|
return { result: { success: true } };
|
|
100
100
|
};
|
|
@@ -109,7 +109,7 @@ export const convertIdeaToTask = async (args, _ctx) => {
|
|
|
109
109
|
update_status
|
|
110
110
|
});
|
|
111
111
|
if (!response.ok) {
|
|
112
|
-
|
|
112
|
+
return { result: { error: response.error || 'Failed to convert idea' }, isError: true };
|
|
113
113
|
}
|
|
114
114
|
return { result: response.data };
|
|
115
115
|
};
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export * from './git-issues.js';
|
|
|
26
26
|
export * from './sprints.js';
|
|
27
27
|
export * from './file-checkouts.js';
|
|
28
28
|
export * from './roles.js';
|
|
29
|
+
export * from './connectors.js';
|
|
29
30
|
import type { HandlerRegistry } from './types.js';
|
|
30
31
|
/**
|
|
31
32
|
* Build the complete handler registry from all modules
|
package/dist/handlers/index.js
CHANGED
|
@@ -26,6 +26,7 @@ export * from './git-issues.js';
|
|
|
26
26
|
export * from './sprints.js';
|
|
27
27
|
export * from './file-checkouts.js';
|
|
28
28
|
export * from './roles.js';
|
|
29
|
+
export * from './connectors.js';
|
|
29
30
|
import { milestoneHandlers } from './milestones.js';
|
|
30
31
|
import { sessionHandlers } from './session.js';
|
|
31
32
|
import { ideaHandlers } from './ideas.js';
|
|
@@ -47,6 +48,7 @@ import { gitIssueHandlers } from './git-issues.js';
|
|
|
47
48
|
import { sprintHandlers } from './sprints.js';
|
|
48
49
|
import { fileCheckoutHandlers } from './file-checkouts.js';
|
|
49
50
|
import { roleHandlers } from './roles.js';
|
|
51
|
+
import { connectorHandlers } from './connectors.js';
|
|
50
52
|
/**
|
|
51
53
|
* Build the complete handler registry from all modules
|
|
52
54
|
*/
|
|
@@ -73,5 +75,6 @@ export function buildHandlerRegistry() {
|
|
|
73
75
|
...sprintHandlers,
|
|
74
76
|
...fileCheckoutHandlers,
|
|
75
77
|
...roleHandlers,
|
|
78
|
+
...connectorHandlers,
|
|
76
79
|
};
|
|
77
80
|
}
|
|
@@ -46,7 +46,7 @@ export const addMilestone = async (args, ctx) => {
|
|
|
46
46
|
order_index
|
|
47
47
|
}, session.currentSessionId || undefined);
|
|
48
48
|
if (!response.ok) {
|
|
49
|
-
|
|
49
|
+
return { result: { error: response.error || 'Failed to add milestone' }, isError: true };
|
|
50
50
|
}
|
|
51
51
|
return {
|
|
52
52
|
result: {
|
|
@@ -69,7 +69,7 @@ export const updateMilestone = async (args, _ctx) => {
|
|
|
69
69
|
order_index
|
|
70
70
|
});
|
|
71
71
|
if (!response.ok) {
|
|
72
|
-
|
|
72
|
+
return { result: { error: response.error || 'Failed to update milestone' }, isError: true };
|
|
73
73
|
}
|
|
74
74
|
return {
|
|
75
75
|
result: {
|
|
@@ -83,7 +83,7 @@ export const completeMilestone = async (args, _ctx) => {
|
|
|
83
83
|
const apiClient = getApiClient();
|
|
84
84
|
const response = await apiClient.completeMilestone(milestone_id);
|
|
85
85
|
if (!response.ok) {
|
|
86
|
-
|
|
86
|
+
return { result: { error: response.error || 'Failed to complete milestone' }, isError: true };
|
|
87
87
|
}
|
|
88
88
|
return {
|
|
89
89
|
result: {
|
|
@@ -97,7 +97,7 @@ export const deleteMilestone = async (args, _ctx) => {
|
|
|
97
97
|
const apiClient = getApiClient();
|
|
98
98
|
const response = await apiClient.deleteMilestone(milestone_id);
|
|
99
99
|
if (!response.ok) {
|
|
100
|
-
|
|
100
|
+
return { result: { error: response.error || 'Failed to delete milestone' }, isError: true };
|
|
101
101
|
}
|
|
102
102
|
return {
|
|
103
103
|
result: {
|
|
@@ -111,7 +111,7 @@ export const getMilestones = async (args, _ctx) => {
|
|
|
111
111
|
const apiClient = getApiClient();
|
|
112
112
|
const response = await apiClient.getMilestones(task_id);
|
|
113
113
|
if (!response.ok) {
|
|
114
|
-
|
|
114
|
+
return { result: { error: response.error || 'Failed to get milestones' }, isError: true };
|
|
115
115
|
}
|
|
116
116
|
// Stats are calculated server-side now
|
|
117
117
|
return {
|
|
@@ -84,7 +84,7 @@ export const listOrganizations = async (_args, _ctx) => {
|
|
|
84
84
|
const apiClient = getApiClient();
|
|
85
85
|
const response = await apiClient.listOrganizations();
|
|
86
86
|
if (!response.ok) {
|
|
87
|
-
|
|
87
|
+
return { result: { error: response.error || 'Failed to list organizations' }, isError: true };
|
|
88
88
|
}
|
|
89
89
|
return { result: response.data };
|
|
90
90
|
};
|
|
@@ -97,7 +97,7 @@ export const createOrganization = async (args, _ctx) => {
|
|
|
97
97
|
slug
|
|
98
98
|
});
|
|
99
99
|
if (!response.ok) {
|
|
100
|
-
|
|
100
|
+
return { result: { error: response.error || 'Failed to create organization' }, isError: true };
|
|
101
101
|
}
|
|
102
102
|
return { result: response.data };
|
|
103
103
|
};
|
|
@@ -117,7 +117,7 @@ export const updateOrganization = async (args, _ctx) => {
|
|
|
117
117
|
const apiClient = getApiClient();
|
|
118
118
|
const response = await apiClient.updateOrganization(organization_id, updates);
|
|
119
119
|
if (!response.ok) {
|
|
120
|
-
|
|
120
|
+
return { result: { error: response.error || 'Failed to update organization' }, isError: true };
|
|
121
121
|
}
|
|
122
122
|
return { result: response.data };
|
|
123
123
|
};
|
|
@@ -126,7 +126,7 @@ export const deleteOrganization = async (args, _ctx) => {
|
|
|
126
126
|
const apiClient = getApiClient();
|
|
127
127
|
const response = await apiClient.deleteOrganization(organization_id);
|
|
128
128
|
if (!response.ok) {
|
|
129
|
-
|
|
129
|
+
return { result: { error: response.error || 'Failed to delete organization' }, isError: true };
|
|
130
130
|
}
|
|
131
131
|
return { result: response.data };
|
|
132
132
|
};
|
|
@@ -138,7 +138,7 @@ export const listOrgMembers = async (args, _ctx) => {
|
|
|
138
138
|
const apiClient = getApiClient();
|
|
139
139
|
const response = await apiClient.listOrgMembers(organization_id);
|
|
140
140
|
if (!response.ok) {
|
|
141
|
-
|
|
141
|
+
return { result: { error: response.error || 'Failed to list members' }, isError: true };
|
|
142
142
|
}
|
|
143
143
|
return { result: response.data };
|
|
144
144
|
};
|
|
@@ -147,7 +147,7 @@ export const inviteMember = async (args, _ctx) => {
|
|
|
147
147
|
const apiClient = getApiClient();
|
|
148
148
|
const response = await apiClient.inviteMember(organization_id, email, role);
|
|
149
149
|
if (!response.ok) {
|
|
150
|
-
|
|
150
|
+
return { result: { error: response.error || 'Failed to create invite' }, isError: true };
|
|
151
151
|
}
|
|
152
152
|
return { result: response.data };
|
|
153
153
|
};
|
|
@@ -159,7 +159,7 @@ export const updateMemberRole = async (args, _ctx) => {
|
|
|
159
159
|
const apiClient = getApiClient();
|
|
160
160
|
const response = await apiClient.updateMemberRole(organization_id, user_id, role);
|
|
161
161
|
if (!response.ok) {
|
|
162
|
-
|
|
162
|
+
return { result: { error: response.error || 'Failed to update member role' }, isError: true };
|
|
163
163
|
}
|
|
164
164
|
return { result: response.data };
|
|
165
165
|
};
|
|
@@ -168,7 +168,7 @@ export const removeMember = async (args, _ctx) => {
|
|
|
168
168
|
const apiClient = getApiClient();
|
|
169
169
|
const response = await apiClient.removeMember(organization_id, user_id);
|
|
170
170
|
if (!response.ok) {
|
|
171
|
-
|
|
171
|
+
return { result: { error: response.error || 'Failed to remove member' }, isError: true };
|
|
172
172
|
}
|
|
173
173
|
return { result: response.data };
|
|
174
174
|
};
|
|
@@ -177,7 +177,7 @@ export const leaveOrganization = async (args, _ctx) => {
|
|
|
177
177
|
const apiClient = getApiClient();
|
|
178
178
|
const response = await apiClient.leaveOrganization(organization_id);
|
|
179
179
|
if (!response.ok) {
|
|
180
|
-
|
|
180
|
+
return { result: { error: response.error || 'Failed to leave organization' }, isError: true };
|
|
181
181
|
}
|
|
182
182
|
return { result: response.data };
|
|
183
183
|
};
|
|
@@ -189,7 +189,7 @@ export const shareProjectWithOrg = async (args, _ctx) => {
|
|
|
189
189
|
const apiClient = getApiClient();
|
|
190
190
|
const response = await apiClient.shareProjectWithOrg(project_id, organization_id, permission);
|
|
191
191
|
if (!response.ok) {
|
|
192
|
-
|
|
192
|
+
return { result: { error: response.error || 'Failed to share project' }, isError: true };
|
|
193
193
|
}
|
|
194
194
|
return { result: response.data };
|
|
195
195
|
};
|
|
@@ -198,7 +198,7 @@ export const updateProjectShare = async (args, _ctx) => {
|
|
|
198
198
|
const apiClient = getApiClient();
|
|
199
199
|
const response = await apiClient.updateProjectShare(project_id, organization_id, permission);
|
|
200
200
|
if (!response.ok) {
|
|
201
|
-
|
|
201
|
+
return { result: { error: response.error || 'Failed to update share' }, isError: true };
|
|
202
202
|
}
|
|
203
203
|
return { result: response.data };
|
|
204
204
|
};
|
|
@@ -207,7 +207,7 @@ export const unshareProject = async (args, _ctx) => {
|
|
|
207
207
|
const apiClient = getApiClient();
|
|
208
208
|
const response = await apiClient.unshareProject(project_id, organization_id);
|
|
209
209
|
if (!response.ok) {
|
|
210
|
-
|
|
210
|
+
return { result: { error: response.error || 'Failed to unshare project' }, isError: true };
|
|
211
211
|
}
|
|
212
212
|
return { result: response.data };
|
|
213
213
|
};
|
|
@@ -216,7 +216,7 @@ export const listProjectShares = async (args, _ctx) => {
|
|
|
216
216
|
const apiClient = getApiClient();
|
|
217
217
|
const response = await apiClient.listProjectShares(project_id);
|
|
218
218
|
if (!response.ok) {
|
|
219
|
-
|
|
219
|
+
return { result: { error: response.error || 'Failed to list shares' }, isError: true };
|
|
220
220
|
}
|
|
221
221
|
return { result: response.data };
|
|
222
222
|
};
|
|
@@ -34,7 +34,7 @@ export const logProgress = async (args, ctx) => {
|
|
|
34
34
|
session_id: session.currentSessionId || undefined
|
|
35
35
|
});
|
|
36
36
|
if (!response.ok) {
|
|
37
|
-
|
|
37
|
+
return { result: { error: response.error || 'Failed to log progress' }, isError: true };
|
|
38
38
|
}
|
|
39
39
|
return { result: { success: true, progress_id: response.data?.progress_id } };
|
|
40
40
|
};
|
|
@@ -49,7 +49,7 @@ export const getActivityFeed = async (args, _ctx) => {
|
|
|
49
49
|
created_by
|
|
50
50
|
});
|
|
51
51
|
if (!response.ok) {
|
|
52
|
-
|
|
52
|
+
return { result: { error: response.error || 'Failed to fetch activity feed' }, isError: true };
|
|
53
53
|
}
|
|
54
54
|
return { result: { activities: response.data?.activities || [] } };
|
|
55
55
|
};
|
package/dist/handlers/project.js
CHANGED
|
@@ -53,14 +53,14 @@ export const getProjectContext = async (args, _ctx) => {
|
|
|
53
53
|
if (!project_id && !git_url) {
|
|
54
54
|
const response = await apiClient.listProjects();
|
|
55
55
|
if (!response.ok) {
|
|
56
|
-
|
|
56
|
+
return { result: { error: response.error || 'Failed to fetch projects' }, isError: true };
|
|
57
57
|
}
|
|
58
58
|
return { result: { projects: response.data?.projects || [] } };
|
|
59
59
|
}
|
|
60
60
|
// Find project by ID or git_url
|
|
61
61
|
const response = await apiClient.getProject(project_id || 'by-git-url', git_url);
|
|
62
62
|
if (!response.ok) {
|
|
63
|
-
|
|
63
|
+
return { result: { error: response.error || 'Failed to fetch project' }, isError: true };
|
|
64
64
|
}
|
|
65
65
|
if (!response.data?.found) {
|
|
66
66
|
return {
|
|
@@ -77,7 +77,7 @@ export const getGitWorkflow = async (args, _ctx) => {
|
|
|
77
77
|
const apiClient = getApiClient();
|
|
78
78
|
const response = await apiClient.getGitWorkflow(project_id, task_id);
|
|
79
79
|
if (!response.ok) {
|
|
80
|
-
|
|
80
|
+
return { result: { error: response.error || 'Failed to get git workflow' }, isError: true };
|
|
81
81
|
}
|
|
82
82
|
return { result: response.data };
|
|
83
83
|
};
|
|
@@ -92,7 +92,7 @@ export const createProject = async (args, _ctx) => {
|
|
|
92
92
|
tech_stack: tech_stack
|
|
93
93
|
});
|
|
94
94
|
if (!response.ok) {
|
|
95
|
-
|
|
95
|
+
return { result: { error: response.error || 'Failed to create project' }, isError: true };
|
|
96
96
|
}
|
|
97
97
|
return { result: response.data };
|
|
98
98
|
};
|
|
@@ -114,7 +114,7 @@ export const updateProject = async (args, _ctx) => {
|
|
|
114
114
|
deployment_instructions
|
|
115
115
|
});
|
|
116
116
|
if (!response.ok) {
|
|
117
|
-
|
|
117
|
+
return { result: { error: response.error || 'Failed to update project' }, isError: true };
|
|
118
118
|
}
|
|
119
119
|
return { result: response.data };
|
|
120
120
|
};
|
|
@@ -123,7 +123,7 @@ export const updateProjectReadme = async (args, _ctx) => {
|
|
|
123
123
|
const apiClient = getApiClient();
|
|
124
124
|
const response = await apiClient.updateProjectReadme(project_id, readme_content);
|
|
125
125
|
if (!response.ok) {
|
|
126
|
-
|
|
126
|
+
return { result: { error: response.error || 'Failed to update README' }, isError: true };
|
|
127
127
|
}
|
|
128
128
|
return { result: response.data };
|
|
129
129
|
};
|
|
@@ -27,7 +27,7 @@ export const getPendingRequests = async (args, ctx) => {
|
|
|
27
27
|
const apiClient = getApiClient();
|
|
28
28
|
const response = await apiClient.getPendingRequests(project_id, session.currentSessionId || undefined);
|
|
29
29
|
if (!response.ok) {
|
|
30
|
-
|
|
30
|
+
return { result: { error: response.error || 'Failed to get pending requests' }, isError: true };
|
|
31
31
|
}
|
|
32
32
|
return {
|
|
33
33
|
result: {
|
|
@@ -42,7 +42,7 @@ export const acknowledgeRequest = async (args, ctx) => {
|
|
|
42
42
|
const apiClient = getApiClient();
|
|
43
43
|
const response = await apiClient.acknowledgeRequest(request_id, session.currentSessionId || undefined);
|
|
44
44
|
if (!response.ok) {
|
|
45
|
-
|
|
45
|
+
return { result: { error: response.error || 'Failed to acknowledge request' }, isError: true };
|
|
46
46
|
}
|
|
47
47
|
return {
|
|
48
48
|
result: {
|
|
@@ -56,7 +56,7 @@ export const answerQuestion = async (args, ctx) => {
|
|
|
56
56
|
const apiClient = getApiClient();
|
|
57
57
|
const response = await apiClient.answerQuestion(request_id, answer, session.currentSessionId || undefined);
|
|
58
58
|
if (!response.ok) {
|
|
59
|
-
|
|
59
|
+
return { result: { error: response.error || 'Failed to answer question' }, isError: true };
|
|
60
60
|
}
|
|
61
61
|
return {
|
|
62
62
|
result: {
|
package/dist/handlers/session.js
CHANGED
|
@@ -83,20 +83,33 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
83
83
|
currentPersona: data.persona || null,
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
|
-
//
|
|
86
|
+
// Check for urgent questions - these MUST be handled first
|
|
87
|
+
const hasUrgentQuestions = data.URGENT_QUESTIONS || (data.pending_requests && data.pending_requests.length > 0);
|
|
88
|
+
// Build result - URGENT_QUESTIONS at absolute top for maximum visibility
|
|
87
89
|
const result = {
|
|
88
90
|
session_started: true,
|
|
89
|
-
directive: data.directive || 'ACTION_REQUIRED: Start working immediately.',
|
|
90
|
-
auto_continue: true,
|
|
91
|
-
session_id: data.session_id,
|
|
92
|
-
persona: data.persona,
|
|
93
|
-
role: data.role,
|
|
94
|
-
project: data.project,
|
|
95
91
|
};
|
|
92
|
+
// URGENT_QUESTIONS must be the FIRST thing the agent sees
|
|
93
|
+
if (data.URGENT_QUESTIONS) {
|
|
94
|
+
result.URGENT_QUESTIONS = data.URGENT_QUESTIONS;
|
|
95
|
+
}
|
|
96
|
+
// Directive comes right after urgent questions
|
|
97
|
+
result.directive = data.directive || 'ACTION_REQUIRED: Start working immediately.';
|
|
98
|
+
result.auto_continue = true;
|
|
99
|
+
// Session info
|
|
100
|
+
result.session_id = data.session_id;
|
|
101
|
+
result.persona = data.persona;
|
|
102
|
+
result.role = data.role;
|
|
103
|
+
result.project = data.project;
|
|
96
104
|
// Add task data
|
|
97
105
|
if (data.next_task) {
|
|
98
106
|
result.next_task = data.next_task;
|
|
99
107
|
}
|
|
108
|
+
// Add pending requests (questions from user) - these take priority
|
|
109
|
+
if (data.pending_requests && data.pending_requests.length > 0) {
|
|
110
|
+
result.pending_requests = data.pending_requests;
|
|
111
|
+
result.pending_requests_count = data.pending_requests.length;
|
|
112
|
+
}
|
|
100
113
|
// Add active tasks for full mode
|
|
101
114
|
if (data.active_tasks) {
|
|
102
115
|
result.active_tasks = data.active_tasks;
|
|
@@ -125,8 +138,14 @@ export const startWorkSession = async (args, ctx) => {
|
|
|
125
138
|
worktree_hint: 'CRITICAL: Create a git worktree before starting work. Run get_help("git") for instructions.',
|
|
126
139
|
};
|
|
127
140
|
}
|
|
128
|
-
// Add next action at end
|
|
129
|
-
if (
|
|
141
|
+
// Add next action at end - pending requests take priority over tasks
|
|
142
|
+
if (hasUrgentQuestions) {
|
|
143
|
+
const firstQuestion = data.URGENT_QUESTIONS?.requests?.[0] || data.pending_requests?.[0];
|
|
144
|
+
result.next_action = firstQuestion
|
|
145
|
+
? `answer_question(request_id: "${firstQuestion.id}", answer: "...")`
|
|
146
|
+
: 'Check pending_requests and respond using answer_question(request_id, answer)';
|
|
147
|
+
}
|
|
148
|
+
else if (data.next_task) {
|
|
130
149
|
result.next_action = `update_task(task_id: "${data.next_task.id}", status: "in_progress")`;
|
|
131
150
|
}
|
|
132
151
|
else if (data.project) {
|