@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,247 +1,102 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Git Issues Handlers
|
|
3
3
|
*
|
|
4
|
-
* Handles git
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
4
|
+
* Handles git issue management:
|
|
5
|
+
* - add_git_issue: Record a git-related issue (conflicts, push failures, etc.)
|
|
6
|
+
* - resolve_git_issue: Mark a git issue as resolved
|
|
7
|
+
* - get_git_issues: List git issues for a project
|
|
8
|
+
* - delete_git_issue: Remove a git issue
|
|
9
9
|
*/
|
|
10
10
|
import { validateRequired, validateUUID } from '../validators.js';
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
import { getApiClient } from '../api-client.js';
|
|
12
|
+
const VALID_GIT_ISSUE_TYPES = [
|
|
13
|
+
'merge_conflict',
|
|
14
|
+
'push_failed',
|
|
15
|
+
'rebase_needed',
|
|
16
|
+
'branch_diverged',
|
|
17
|
+
'pr_not_mergeable',
|
|
18
|
+
];
|
|
19
|
+
const VALID_GIT_ISSUE_STATUSES = ['open', 'resolved'];
|
|
20
|
+
export const addGitIssue = async (args, ctx) => {
|
|
21
|
+
const { project_id, issue_type, branch, target_branch, pr_url, conflicting_files, error_message, task_id, } = args;
|
|
13
22
|
validateRequired(project_id, 'project_id');
|
|
14
23
|
validateUUID(project_id, 'project_id');
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.
|
|
19
|
-
id,
|
|
20
|
-
task_id,
|
|
21
|
-
issue_type,
|
|
22
|
-
severity,
|
|
23
|
-
branch_name,
|
|
24
|
-
pr_number,
|
|
25
|
-
pr_url,
|
|
26
|
-
target_branch,
|
|
27
|
-
conflicting_files,
|
|
28
|
-
error_message,
|
|
29
|
-
status,
|
|
30
|
-
created_at,
|
|
31
|
-
resolved_at,
|
|
32
|
-
auto_resolved,
|
|
33
|
-
resolution_note
|
|
34
|
-
`)
|
|
35
|
-
.eq('project_id', project_id)
|
|
36
|
-
.order('created_at', { ascending: false });
|
|
37
|
-
if (status !== 'all' && !include_resolved) {
|
|
38
|
-
query = query.eq('status', status);
|
|
24
|
+
validateRequired(issue_type, 'issue_type');
|
|
25
|
+
validateRequired(branch, 'branch');
|
|
26
|
+
if (!VALID_GIT_ISSUE_TYPES.includes(issue_type)) {
|
|
27
|
+
throw new Error(`Invalid issue_type. Valid types: ${VALID_GIT_ISSUE_TYPES.join(', ')}`);
|
|
39
28
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
return {
|
|
57
|
-
result: {
|
|
58
|
-
issues: issues || [],
|
|
59
|
-
open_count: openIssues.length,
|
|
60
|
-
severity_summary: summary,
|
|
61
|
-
has_critical: summary.critical > 0,
|
|
62
|
-
has_blocking: summary.critical > 0 || summary.high > 0,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
29
|
+
if (task_id) {
|
|
30
|
+
validateUUID(task_id, 'task_id');
|
|
31
|
+
}
|
|
32
|
+
const apiClient = getApiClient();
|
|
33
|
+
const response = await apiClient.addGitIssue(project_id, {
|
|
34
|
+
issue_type: issue_type,
|
|
35
|
+
branch,
|
|
36
|
+
target_branch,
|
|
37
|
+
pr_url,
|
|
38
|
+
conflicting_files,
|
|
39
|
+
error_message,
|
|
40
|
+
task_id
|
|
41
|
+
}, ctx.session.currentSessionId || undefined);
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(response.error || 'Failed to add git issue');
|
|
44
|
+
}
|
|
45
|
+
return { result: response.data };
|
|
65
46
|
};
|
|
66
|
-
export const
|
|
67
|
-
const {
|
|
47
|
+
export const resolveGitIssue = async (args, ctx) => {
|
|
48
|
+
const { git_issue_id, resolution_note, auto_resolved } = args;
|
|
49
|
+
validateRequired(git_issue_id, 'git_issue_id');
|
|
50
|
+
validateUUID(git_issue_id, 'git_issue_id');
|
|
51
|
+
const apiClient = getApiClient();
|
|
52
|
+
const response = await apiClient.resolveGitIssue(git_issue_id, {
|
|
53
|
+
resolution_note,
|
|
54
|
+
auto_resolved
|
|
55
|
+
}, ctx.session.currentSessionId || undefined);
|
|
56
|
+
if (!response.ok) {
|
|
57
|
+
throw new Error(response.error || 'Failed to resolve git issue');
|
|
58
|
+
}
|
|
59
|
+
return { result: response.data };
|
|
60
|
+
};
|
|
61
|
+
export const getGitIssues = async (args, ctx) => {
|
|
62
|
+
const { project_id, status = 'open', issue_type, branch, limit = 50, } = args;
|
|
68
63
|
validateRequired(project_id, 'project_id');
|
|
69
64
|
validateUUID(project_id, 'project_id');
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// Check if similar issue already exists (avoid duplicates)
|
|
73
|
-
if (branch_name || pr_number) {
|
|
74
|
-
const { data: existing } = await supabase
|
|
75
|
-
.from('git_issues')
|
|
76
|
-
.select('id')
|
|
77
|
-
.eq('project_id', project_id)
|
|
78
|
-
.eq('status', 'open')
|
|
79
|
-
.eq('issue_type', issue_type)
|
|
80
|
-
.or(`branch_name.eq.${branch_name},pr_number.eq.${pr_number}`)
|
|
81
|
-
.limit(1)
|
|
82
|
-
.maybeSingle();
|
|
83
|
-
if (existing) {
|
|
84
|
-
return {
|
|
85
|
-
result: {
|
|
86
|
-
success: false,
|
|
87
|
-
already_exists: true,
|
|
88
|
-
existing_issue_id: existing.id,
|
|
89
|
-
message: 'A similar git issue already exists for this branch/PR',
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
}
|
|
65
|
+
if (status && !VALID_GIT_ISSUE_STATUSES.includes(status)) {
|
|
66
|
+
throw new Error(`Invalid status. Valid statuses: ${VALID_GIT_ISSUE_STATUSES.join(', ')}`);
|
|
93
67
|
}
|
|
94
|
-
|
|
95
|
-
.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
68
|
+
if (issue_type && !VALID_GIT_ISSUE_TYPES.includes(issue_type)) {
|
|
69
|
+
throw new Error(`Invalid issue_type. Valid types: ${VALID_GIT_ISSUE_TYPES.join(', ')}`);
|
|
70
|
+
}
|
|
71
|
+
const apiClient = getApiClient();
|
|
72
|
+
const response = await apiClient.getGitIssues(project_id, {
|
|
73
|
+
status,
|
|
99
74
|
issue_type,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
pr_number: pr_number || null,
|
|
103
|
-
pr_url: pr_url || null,
|
|
104
|
-
target_branch: target_branch || null,
|
|
105
|
-
conflicting_files: conflicting_files || [],
|
|
106
|
-
error_message: error_message || null,
|
|
107
|
-
created_by: 'agent',
|
|
108
|
-
created_by_session_id: session.currentSessionId,
|
|
109
|
-
})
|
|
110
|
-
.select('id, issue_type, severity, branch_name, pr_number')
|
|
111
|
-
.single();
|
|
112
|
-
if (error)
|
|
113
|
-
throw new Error(`Failed to create git issue: ${error.message}`);
|
|
114
|
-
// Log progress
|
|
115
|
-
await supabase.from('progress_logs').insert({
|
|
116
|
-
project_id,
|
|
117
|
-
task_id: task_id || null,
|
|
118
|
-
summary: `Git issue created: ${issue_type} on ${branch_name || `PR #${pr_number}`}`,
|
|
119
|
-
details: error_message || null,
|
|
120
|
-
created_by: 'agent',
|
|
121
|
-
created_by_session_id: session.currentSessionId,
|
|
75
|
+
branch,
|
|
76
|
+
limit
|
|
122
77
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
success: true,
|
|
126
|
-
issue_id: issue.id,
|
|
127
|
-
issue_type: issue.issue_type,
|
|
128
|
-
severity: issue.severity,
|
|
129
|
-
branch: issue.branch_name,
|
|
130
|
-
pr_number: issue.pr_number,
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
export const resolveGitIssue = async (args, ctx) => {
|
|
135
|
-
const { issue_id, resolution_note, auto_resolved = false } = args;
|
|
136
|
-
validateRequired(issue_id, 'issue_id');
|
|
137
|
-
validateUUID(issue_id, 'issue_id');
|
|
138
|
-
const { supabase, session } = ctx;
|
|
139
|
-
// Get the issue first
|
|
140
|
-
const { data: issue, error: fetchError } = await supabase
|
|
141
|
-
.from('git_issues')
|
|
142
|
-
.select('id, project_id, task_id, issue_type, branch_name, pr_number, status')
|
|
143
|
-
.eq('id', issue_id)
|
|
144
|
-
.single();
|
|
145
|
-
if (fetchError || !issue)
|
|
146
|
-
throw new Error('Git issue not found');
|
|
147
|
-
if (issue.status !== 'open') {
|
|
148
|
-
return {
|
|
149
|
-
result: {
|
|
150
|
-
success: false,
|
|
151
|
-
error: `Issue is already ${issue.status}`,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
throw new Error(response.error || 'Failed to fetch git issues');
|
|
154
80
|
}
|
|
155
|
-
|
|
156
|
-
.from('git_issues')
|
|
157
|
-
.update({
|
|
158
|
-
status: 'resolved',
|
|
159
|
-
resolved_at: new Date().toISOString(),
|
|
160
|
-
resolved_by_session_id: session.currentSessionId,
|
|
161
|
-
auto_resolved,
|
|
162
|
-
resolution_note: resolution_note || null,
|
|
163
|
-
})
|
|
164
|
-
.eq('id', issue_id);
|
|
165
|
-
if (updateError)
|
|
166
|
-
throw new Error(`Failed to resolve git issue: ${updateError.message}`);
|
|
167
|
-
// Log progress
|
|
168
|
-
await supabase.from('progress_logs').insert({
|
|
169
|
-
project_id: issue.project_id,
|
|
170
|
-
task_id: issue.task_id,
|
|
171
|
-
summary: `Git issue resolved: ${issue.issue_type} on ${issue.branch_name || `PR #${issue.pr_number}`}${auto_resolved ? ' (auto)' : ''}`,
|
|
172
|
-
details: resolution_note || null,
|
|
173
|
-
created_by: 'agent',
|
|
174
|
-
created_by_session_id: session.currentSessionId,
|
|
175
|
-
});
|
|
176
|
-
return {
|
|
177
|
-
result: {
|
|
178
|
-
success: true,
|
|
179
|
-
resolved_issue_id: issue_id,
|
|
180
|
-
auto_resolved,
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
export const dismissGitIssue = async (args, ctx) => {
|
|
185
|
-
const { issue_id, reason } = args;
|
|
186
|
-
validateRequired(issue_id, 'issue_id');
|
|
187
|
-
validateUUID(issue_id, 'issue_id');
|
|
188
|
-
const { supabase, session } = ctx;
|
|
189
|
-
const { error } = await supabase
|
|
190
|
-
.from('git_issues')
|
|
191
|
-
.update({
|
|
192
|
-
status: 'dismissed',
|
|
193
|
-
resolved_at: new Date().toISOString(),
|
|
194
|
-
resolved_by_session_id: session.currentSessionId,
|
|
195
|
-
resolution_note: reason || 'Dismissed',
|
|
196
|
-
})
|
|
197
|
-
.eq('id', issue_id);
|
|
198
|
-
if (error)
|
|
199
|
-
throw new Error(`Failed to dismiss git issue: ${error.message}`);
|
|
200
|
-
return {
|
|
201
|
-
result: {
|
|
202
|
-
success: true,
|
|
203
|
-
dismissed_issue_id: issue_id,
|
|
204
|
-
},
|
|
205
|
-
};
|
|
81
|
+
return { result: response.data };
|
|
206
82
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
.
|
|
215
|
-
.eq('branch_name', branchName)
|
|
216
|
-
.eq('status', 'open')
|
|
217
|
-
.in('issue_type', ['merge_conflict', 'rebase_needed']);
|
|
218
|
-
if (!issues || issues.length === 0)
|
|
219
|
-
return 0;
|
|
220
|
-
const { error } = await supabase
|
|
221
|
-
.from('git_issues')
|
|
222
|
-
.update({
|
|
223
|
-
status: 'resolved',
|
|
224
|
-
resolved_at: new Date().toISOString(),
|
|
225
|
-
resolved_by_session_id: sessionId,
|
|
226
|
-
auto_resolved: true,
|
|
227
|
-
resolution_note: 'Auto-resolved: branch is now mergeable',
|
|
228
|
-
})
|
|
229
|
-
.eq('project_id', projectId)
|
|
230
|
-
.eq('branch_name', branchName)
|
|
231
|
-
.eq('status', 'open')
|
|
232
|
-
.in('issue_type', ['merge_conflict', 'rebase_needed']);
|
|
233
|
-
if (error) {
|
|
234
|
-
console.error('Failed to auto-resolve git issues:', error);
|
|
235
|
-
return 0;
|
|
83
|
+
export const deleteGitIssue = async (args, ctx) => {
|
|
84
|
+
const { git_issue_id } = args;
|
|
85
|
+
validateRequired(git_issue_id, 'git_issue_id');
|
|
86
|
+
validateUUID(git_issue_id, 'git_issue_id');
|
|
87
|
+
const apiClient = getApiClient();
|
|
88
|
+
const response = await apiClient.deleteGitIssue(git_issue_id);
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
throw new Error(response.error || 'Failed to delete git issue');
|
|
236
91
|
}
|
|
237
|
-
return
|
|
238
|
-
}
|
|
92
|
+
return { result: response.data };
|
|
93
|
+
};
|
|
239
94
|
/**
|
|
240
95
|
* Git Issues handlers registry
|
|
241
96
|
*/
|
|
242
|
-
export const
|
|
243
|
-
|
|
244
|
-
create_git_issue: createGitIssue,
|
|
97
|
+
export const gitIssueHandlers = {
|
|
98
|
+
add_git_issue: addGitIssue,
|
|
245
99
|
resolve_git_issue: resolveGitIssue,
|
|
246
|
-
|
|
100
|
+
get_git_issues: getGitIssues,
|
|
101
|
+
delete_git_issue: deleteGitIssue,
|
|
247
102
|
};
|
package/dist/handlers/ideas.d.ts
CHANGED
package/dist/handlers/ideas.js
CHANGED
|
@@ -6,94 +6,74 @@
|
|
|
6
6
|
* - update_idea
|
|
7
7
|
* - get_ideas
|
|
8
8
|
* - delete_idea
|
|
9
|
+
* - convert_idea_to_task
|
|
10
|
+
*
|
|
11
|
+
* MIGRATED: Uses Vibescope API client instead of direct Supabase
|
|
9
12
|
*/
|
|
10
13
|
import { validateRequired, validateUUID, validatePriority, validateEstimatedMinutes } from '../validators.js';
|
|
14
|
+
import { getApiClient } from '../api-client.js';
|
|
11
15
|
export const addIdea = async (args, ctx) => {
|
|
12
16
|
const { project_id, title, description, status } = args;
|
|
13
17
|
validateRequired(project_id, 'project_id');
|
|
14
18
|
validateUUID(project_id, 'project_id');
|
|
15
19
|
validateRequired(title, 'title');
|
|
16
|
-
const {
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
.insert({
|
|
20
|
-
project_id,
|
|
20
|
+
const { session } = ctx;
|
|
21
|
+
const apiClient = getApiClient();
|
|
22
|
+
const response = await apiClient.addIdea(project_id, {
|
|
21
23
|
title,
|
|
22
|
-
description
|
|
23
|
-
status
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (error)
|
|
30
|
-
throw new Error(`Failed to add idea: ${error.message}`);
|
|
31
|
-
return { result: { success: true, idea_id: data.id, title } };
|
|
24
|
+
description,
|
|
25
|
+
status
|
|
26
|
+
}, session.currentSessionId || undefined);
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
throw new Error(`Failed to add idea: ${response.error}`);
|
|
29
|
+
}
|
|
30
|
+
return { result: { success: true, idea_id: response.data?.idea_id, title } };
|
|
32
31
|
};
|
|
33
32
|
export const updateIdea = async (args, ctx) => {
|
|
34
33
|
const { idea_id, title, description, status, doc_url } = args;
|
|
35
34
|
validateRequired(idea_id, 'idea_id');
|
|
36
35
|
validateUUID(idea_id, 'idea_id');
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!
|
|
45
|
-
throw new Error(`
|
|
46
|
-
}
|
|
47
|
-
// Build update object
|
|
48
|
-
const updates = { updated_at: new Date().toISOString() };
|
|
49
|
-
if (title !== undefined)
|
|
50
|
-
updates.title = title;
|
|
51
|
-
if (description !== undefined)
|
|
52
|
-
updates.description = description;
|
|
53
|
-
if (doc_url !== undefined)
|
|
54
|
-
updates.doc_url = doc_url;
|
|
55
|
-
if (status !== undefined) {
|
|
56
|
-
updates.status = status;
|
|
57
|
-
// Set planned_at when transitioning to planned status
|
|
58
|
-
if (status === 'planned' && existingIdea.status !== 'planned') {
|
|
59
|
-
updates.planned_at = new Date().toISOString();
|
|
60
|
-
}
|
|
36
|
+
const apiClient = getApiClient();
|
|
37
|
+
const response = await apiClient.updateIdea(idea_id, {
|
|
38
|
+
title,
|
|
39
|
+
description,
|
|
40
|
+
status,
|
|
41
|
+
doc_url
|
|
42
|
+
});
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
throw new Error(`Failed to update idea: ${response.error}`);
|
|
61
45
|
}
|
|
62
|
-
const { error } = await supabase
|
|
63
|
-
.from('ideas')
|
|
64
|
-
.update(updates)
|
|
65
|
-
.eq('id', idea_id);
|
|
66
|
-
if (error)
|
|
67
|
-
throw new Error(`Failed to update idea: ${error.message}`);
|
|
68
46
|
return { result: { success: true, idea_id } };
|
|
69
47
|
};
|
|
70
48
|
export const getIdeas = async (args, ctx) => {
|
|
71
|
-
const { project_id, status } = args;
|
|
49
|
+
const { project_id, status, limit = 50, offset = 0, search_query } = args;
|
|
72
50
|
validateRequired(project_id, 'project_id');
|
|
73
51
|
validateUUID(project_id, 'project_id');
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
52
|
+
const apiClient = getApiClient();
|
|
53
|
+
const response = await apiClient.getIdeas(project_id, {
|
|
54
|
+
status,
|
|
55
|
+
limit,
|
|
56
|
+
offset,
|
|
57
|
+
search_query
|
|
58
|
+
});
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
throw new Error(`Failed to fetch ideas: ${response.error}`);
|
|
81
61
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
62
|
+
return {
|
|
63
|
+
result: {
|
|
64
|
+
ideas: response.data?.ideas || [],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
86
67
|
};
|
|
87
68
|
export const deleteIdea = async (args, ctx) => {
|
|
88
69
|
const { idea_id } = args;
|
|
89
70
|
validateRequired(idea_id, 'idea_id');
|
|
90
71
|
validateUUID(idea_id, 'idea_id');
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
throw new Error(`Failed to delete idea: ${error.message}`);
|
|
72
|
+
const apiClient = getApiClient();
|
|
73
|
+
const response = await apiClient.deleteIdea(idea_id);
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw new Error(`Failed to delete idea: ${response.error}`);
|
|
76
|
+
}
|
|
97
77
|
return { result: { success: true } };
|
|
98
78
|
};
|
|
99
79
|
export const convertIdeaToTask = async (args, ctx) => {
|
|
@@ -102,79 +82,18 @@ export const convertIdeaToTask = async (args, ctx) => {
|
|
|
102
82
|
validateUUID(idea_id, 'idea_id');
|
|
103
83
|
validatePriority(priority);
|
|
104
84
|
validateEstimatedMinutes(estimated_minutes);
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.from('ideas')
|
|
110
|
-
.select('id, project_id, title, description, status, converted_to_task_id')
|
|
111
|
-
.eq('id', idea_id)
|
|
112
|
-
.single();
|
|
113
|
-
if (fetchError || !idea) {
|
|
114
|
-
throw new Error(`Idea not found: ${idea_id}`);
|
|
115
|
-
}
|
|
116
|
-
// Check if already converted
|
|
117
|
-
if (idea.converted_to_task_id) {
|
|
118
|
-
return {
|
|
119
|
-
result: {
|
|
120
|
-
success: false,
|
|
121
|
-
error: 'Idea has already been converted to a task',
|
|
122
|
-
existing_task_id: idea.converted_to_task_id,
|
|
123
|
-
hint: 'Use get_tasks to find the existing task',
|
|
124
|
-
},
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
// Create the task
|
|
128
|
-
const { data: task, error: taskError } = await supabase
|
|
129
|
-
.from('tasks')
|
|
130
|
-
.insert({
|
|
131
|
-
project_id: idea.project_id,
|
|
132
|
-
title: idea.title,
|
|
133
|
-
description: idea.description || `Converted from idea: ${idea.title}`,
|
|
85
|
+
const apiClient = getApiClient();
|
|
86
|
+
// Use proxy for convert_idea_to_task operation
|
|
87
|
+
const response = await apiClient.proxy('convert_idea_to_task', {
|
|
88
|
+
idea_id,
|
|
134
89
|
priority,
|
|
135
|
-
estimated_minutes
|
|
136
|
-
|
|
137
|
-
created_by_session_id: currentSessionId,
|
|
138
|
-
})
|
|
139
|
-
.select('id, title')
|
|
140
|
-
.single();
|
|
141
|
-
if (taskError || !task) {
|
|
142
|
-
throw new Error(`Failed to create task: ${taskError?.message}`);
|
|
143
|
-
}
|
|
144
|
-
// Update the idea with the task reference and optionally update status
|
|
145
|
-
const ideaUpdates = {
|
|
146
|
-
converted_to_task_id: task.id,
|
|
147
|
-
updated_at: new Date().toISOString(),
|
|
148
|
-
};
|
|
149
|
-
if (update_status && idea.status !== 'shipped') {
|
|
150
|
-
ideaUpdates.status = 'in_development';
|
|
151
|
-
}
|
|
152
|
-
const { error: updateError } = await supabase
|
|
153
|
-
.from('ideas')
|
|
154
|
-
.update(ideaUpdates)
|
|
155
|
-
.eq('id', idea_id);
|
|
156
|
-
if (updateError) {
|
|
157
|
-
// Log but don't fail - task was created successfully
|
|
158
|
-
console.error(`Failed to update idea after conversion: ${updateError.message}`);
|
|
159
|
-
}
|
|
160
|
-
// Log progress
|
|
161
|
-
await supabase.from('progress_logs').insert({
|
|
162
|
-
project_id: idea.project_id,
|
|
163
|
-
task_id: task.id,
|
|
164
|
-
summary: `Converted idea "${idea.title}" to task`,
|
|
165
|
-
created_by: 'agent',
|
|
166
|
-
created_by_session_id: currentSessionId,
|
|
90
|
+
estimated_minutes,
|
|
91
|
+
update_status
|
|
167
92
|
});
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
task_title: task.title,
|
|
173
|
-
idea_id: idea.id,
|
|
174
|
-
idea_status: update_status ? 'in_development' : idea.status,
|
|
175
|
-
message: `Created task from idea. Start with: update_task(task_id: "${task.id}", status: "in_progress")`,
|
|
176
|
-
},
|
|
177
|
-
};
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw new Error(`Failed to convert idea: ${response.error}`);
|
|
95
|
+
}
|
|
96
|
+
return { result: response.data };
|
|
178
97
|
};
|
|
179
98
|
/**
|
|
180
99
|
* Ideas handlers registry
|
package/dist/handlers/index.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export * from './bodies-of-work.js';
|
|
|
22
22
|
export * from './discovery.js';
|
|
23
23
|
export * from './organizations.js';
|
|
24
24
|
export * from './cost.js';
|
|
25
|
+
export * from './git-issues.js';
|
|
26
|
+
export * from './sprints.js';
|
|
25
27
|
import type { HandlerRegistry } from './types.js';
|
|
26
28
|
/**
|
|
27
29
|
* Build the complete handler registry from all modules
|
package/dist/handlers/index.js
CHANGED
|
@@ -22,6 +22,8 @@ export * from './bodies-of-work.js';
|
|
|
22
22
|
export * from './discovery.js';
|
|
23
23
|
export * from './organizations.js';
|
|
24
24
|
export * from './cost.js';
|
|
25
|
+
export * from './git-issues.js';
|
|
26
|
+
export * from './sprints.js';
|
|
25
27
|
import { milestoneHandlers } from './milestones.js';
|
|
26
28
|
import { sessionHandlers } from './session.js';
|
|
27
29
|
import { ideaHandlers } from './ideas.js';
|
|
@@ -39,6 +41,8 @@ import { bodiesOfWorkHandlers } from './bodies-of-work.js';
|
|
|
39
41
|
import { discoveryHandlers } from './discovery.js';
|
|
40
42
|
import { organizationHandlers } from './organizations.js';
|
|
41
43
|
import { costHandlers } from './cost.js';
|
|
44
|
+
import { gitIssueHandlers } from './git-issues.js';
|
|
45
|
+
import { sprintHandlers } from './sprints.js';
|
|
42
46
|
/**
|
|
43
47
|
* Build the complete handler registry from all modules
|
|
44
48
|
*/
|
|
@@ -61,5 +65,7 @@ export function buildHandlerRegistry() {
|
|
|
61
65
|
...discoveryHandlers,
|
|
62
66
|
...organizationHandlers,
|
|
63
67
|
...costHandlers,
|
|
68
|
+
...gitIssueHandlers,
|
|
69
|
+
...sprintHandlers,
|
|
64
70
|
};
|
|
65
71
|
}
|