@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/cost.js
CHANGED
|
@@ -9,20 +9,55 @@
|
|
|
9
9
|
* - delete_cost_alert
|
|
10
10
|
* - get_task_costs
|
|
11
11
|
*/
|
|
12
|
+
import { parseArgs, uuidValidator, createEnumValidator, ValidationError } from '../validators.js';
|
|
12
13
|
import { getApiClient } from '../api-client.js';
|
|
14
|
+
const VALID_PERIODS = ['daily', 'weekly', 'monthly'];
|
|
15
|
+
const VALID_ALERT_TYPES = ['warning', 'critical'];
|
|
16
|
+
// Argument schemas for type-safe parsing
|
|
17
|
+
const getCostSummarySchema = {
|
|
18
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
19
|
+
period: { type: 'string', default: 'daily', validate: createEnumValidator(VALID_PERIODS) },
|
|
20
|
+
limit: { type: 'number', default: 30 },
|
|
21
|
+
};
|
|
22
|
+
const getCostAlertsSchema = {
|
|
23
|
+
project_id: { type: 'string', validate: uuidValidator },
|
|
24
|
+
};
|
|
25
|
+
const addCostAlertSchema = {
|
|
26
|
+
project_id: { type: 'string', validate: uuidValidator },
|
|
27
|
+
threshold_amount: { type: 'number', required: true },
|
|
28
|
+
threshold_period: { type: 'string', required: true, validate: createEnumValidator(VALID_PERIODS) },
|
|
29
|
+
alert_type: { type: 'string', default: 'warning', validate: createEnumValidator(VALID_ALERT_TYPES) },
|
|
30
|
+
};
|
|
31
|
+
const updateCostAlertSchema = {
|
|
32
|
+
alert_id: { type: 'string', required: true, validate: uuidValidator },
|
|
33
|
+
threshold_amount: { type: 'number' },
|
|
34
|
+
threshold_period: { type: 'string', validate: createEnumValidator(VALID_PERIODS) },
|
|
35
|
+
alert_type: { type: 'string', validate: createEnumValidator(VALID_ALERT_TYPES) },
|
|
36
|
+
enabled: { type: 'boolean' },
|
|
37
|
+
};
|
|
38
|
+
const deleteCostAlertSchema = {
|
|
39
|
+
alert_id: { type: 'string', required: true, validate: uuidValidator },
|
|
40
|
+
};
|
|
41
|
+
const getTaskCostsSchema = {
|
|
42
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
43
|
+
limit: { type: 'number', default: 20 },
|
|
44
|
+
};
|
|
45
|
+
// Custom validator for positive numbers
|
|
46
|
+
function validatePositiveNumber(value, fieldName) {
|
|
47
|
+
if (value !== undefined && value <= 0) {
|
|
48
|
+
throw new ValidationError(`${fieldName} must be a positive number`, { field: fieldName });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
13
51
|
/**
|
|
14
52
|
* Get cost summary for a project (daily, weekly, or monthly)
|
|
15
53
|
*/
|
|
16
|
-
export const getCostSummary = async (args,
|
|
17
|
-
const { project_id, period
|
|
18
|
-
if (!project_id) {
|
|
19
|
-
return {
|
|
20
|
-
result: { error: 'project_id is required' },
|
|
21
|
-
isError: true,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
54
|
+
export const getCostSummary = async (args, _ctx) => {
|
|
55
|
+
const { project_id, period, limit } = parseArgs(args, getCostSummarySchema);
|
|
24
56
|
const apiClient = getApiClient();
|
|
25
|
-
const response = await apiClient.getCostSummary(project_id, {
|
|
57
|
+
const response = await apiClient.getCostSummary(project_id, {
|
|
58
|
+
period: period,
|
|
59
|
+
limit
|
|
60
|
+
});
|
|
26
61
|
if (!response.ok) {
|
|
27
62
|
return {
|
|
28
63
|
result: { error: response.error || 'Failed to get cost summary' },
|
|
@@ -34,8 +69,8 @@ export const getCostSummary = async (args, ctx) => {
|
|
|
34
69
|
/**
|
|
35
70
|
* Get cost alerts for the current user
|
|
36
71
|
*/
|
|
37
|
-
export const getCostAlerts = async (args,
|
|
38
|
-
const { project_id } = args;
|
|
72
|
+
export const getCostAlerts = async (args, _ctx) => {
|
|
73
|
+
const { project_id } = parseArgs(args, getCostAlertsSchema);
|
|
39
74
|
const apiClient = getApiClient();
|
|
40
75
|
const response = await apiClient.getCostAlerts();
|
|
41
76
|
if (!response.ok) {
|
|
@@ -49,26 +84,16 @@ export const getCostAlerts = async (args, ctx) => {
|
|
|
49
84
|
/**
|
|
50
85
|
* Add a cost alert
|
|
51
86
|
*/
|
|
52
|
-
export const addCostAlert = async (args,
|
|
53
|
-
const { project_id, threshold_amount, threshold_period, alert_type
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
result: { error: 'threshold_amount must be a positive number' },
|
|
57
|
-
isError: true,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
if (!threshold_period || !['daily', 'weekly', 'monthly'].includes(threshold_period)) {
|
|
61
|
-
return {
|
|
62
|
-
result: { error: 'threshold_period must be "daily", "weekly", or "monthly"' },
|
|
63
|
-
isError: true,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
87
|
+
export const addCostAlert = async (args, _ctx) => {
|
|
88
|
+
const { project_id, threshold_amount, threshold_period, alert_type } = parseArgs(args, addCostAlertSchema);
|
|
89
|
+
// Additional validation for positive amount
|
|
90
|
+
validatePositiveNumber(threshold_amount, 'threshold_amount');
|
|
66
91
|
const apiClient = getApiClient();
|
|
67
92
|
const response = await apiClient.addCostAlert({
|
|
68
93
|
project_id,
|
|
69
|
-
threshold_amount,
|
|
70
|
-
threshold_period,
|
|
71
|
-
alert_type
|
|
94
|
+
threshold_amount: threshold_amount,
|
|
95
|
+
threshold_period: threshold_period,
|
|
96
|
+
alert_type: alert_type
|
|
72
97
|
});
|
|
73
98
|
if (!response.ok) {
|
|
74
99
|
return {
|
|
@@ -81,11 +106,12 @@ export const addCostAlert = async (args, ctx) => {
|
|
|
81
106
|
/**
|
|
82
107
|
* Update a cost alert
|
|
83
108
|
*/
|
|
84
|
-
export const updateCostAlert = async (args,
|
|
85
|
-
const { alert_id, threshold_amount, threshold_period, alert_type, enabled
|
|
86
|
-
|
|
109
|
+
export const updateCostAlert = async (args, _ctx) => {
|
|
110
|
+
const { alert_id, threshold_amount, threshold_period, alert_type, enabled } = parseArgs(args, updateCostAlertSchema);
|
|
111
|
+
// Check that at least one update is provided
|
|
112
|
+
if (threshold_amount === undefined && threshold_period === undefined && alert_type === undefined && enabled === undefined) {
|
|
87
113
|
return {
|
|
88
|
-
result: { error: '
|
|
114
|
+
result: { error: 'No updates provided' },
|
|
89
115
|
isError: true,
|
|
90
116
|
};
|
|
91
117
|
}
|
|
@@ -98,12 +124,6 @@ export const updateCostAlert = async (args, ctx) => {
|
|
|
98
124
|
updates.alert_type = alert_type;
|
|
99
125
|
if (enabled !== undefined)
|
|
100
126
|
updates.enabled = enabled;
|
|
101
|
-
if (Object.keys(updates).length === 0) {
|
|
102
|
-
return {
|
|
103
|
-
result: { error: 'No updates provided' },
|
|
104
|
-
isError: true,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
127
|
const apiClient = getApiClient();
|
|
108
128
|
const response = await apiClient.updateCostAlert(alert_id, updates);
|
|
109
129
|
if (!response.ok) {
|
|
@@ -117,14 +137,8 @@ export const updateCostAlert = async (args, ctx) => {
|
|
|
117
137
|
/**
|
|
118
138
|
* Delete a cost alert
|
|
119
139
|
*/
|
|
120
|
-
export const deleteCostAlert = async (args,
|
|
121
|
-
const { alert_id } = args;
|
|
122
|
-
if (!alert_id) {
|
|
123
|
-
return {
|
|
124
|
-
result: { error: 'alert_id is required' },
|
|
125
|
-
isError: true,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
140
|
+
export const deleteCostAlert = async (args, _ctx) => {
|
|
141
|
+
const { alert_id } = parseArgs(args, deleteCostAlertSchema);
|
|
128
142
|
const apiClient = getApiClient();
|
|
129
143
|
const response = await apiClient.deleteCostAlert(alert_id);
|
|
130
144
|
if (!response.ok) {
|
|
@@ -138,14 +152,8 @@ export const deleteCostAlert = async (args, ctx) => {
|
|
|
138
152
|
/**
|
|
139
153
|
* Get task costs for a project
|
|
140
154
|
*/
|
|
141
|
-
export const getTaskCosts = async (args,
|
|
142
|
-
const { project_id, limit
|
|
143
|
-
if (!project_id) {
|
|
144
|
-
return {
|
|
145
|
-
result: { error: 'project_id is required' },
|
|
146
|
-
isError: true,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
155
|
+
export const getTaskCosts = async (args, _ctx) => {
|
|
156
|
+
const { project_id, limit } = parseArgs(args, getTaskCostsSchema);
|
|
149
157
|
const apiClient = getApiClient();
|
|
150
158
|
const response = await apiClient.getTaskCosts(project_id, limit);
|
|
151
159
|
if (!response.ok) {
|
|
@@ -8,33 +8,48 @@
|
|
|
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 logDecisionSchema = {
|
|
15
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
16
|
+
title: { type: 'string', required: true },
|
|
17
|
+
description: { type: 'string', required: true },
|
|
18
|
+
rationale: { type: 'string' },
|
|
19
|
+
alternatives_considered: { type: 'array' },
|
|
20
|
+
};
|
|
21
|
+
const getDecisionsSchema = {
|
|
22
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
23
|
+
limit: { type: 'number', default: 50 },
|
|
24
|
+
offset: { type: 'number', default: 0 },
|
|
25
|
+
search_query: { type: 'string' },
|
|
26
|
+
};
|
|
27
|
+
const deleteDecisionSchema = {
|
|
28
|
+
decision_id: { type: 'string', required: true, validate: uuidValidator },
|
|
29
|
+
};
|
|
13
30
|
export const logDecision = async (args, ctx) => {
|
|
14
|
-
const { project_id, title, description, rationale, alternatives_considered } = args;
|
|
15
|
-
validateRequired(project_id, 'project_id');
|
|
16
|
-
validateUUID(project_id, 'project_id');
|
|
17
|
-
validateRequired(title, 'title');
|
|
18
|
-
validateRequired(description, 'description');
|
|
31
|
+
const { project_id, title, description, rationale, alternatives_considered } = parseArgs(args, logDecisionSchema);
|
|
19
32
|
const { session } = ctx;
|
|
20
33
|
const apiClient = getApiClient();
|
|
21
34
|
const response = await apiClient.logDecision(project_id, {
|
|
22
35
|
title,
|
|
23
36
|
description,
|
|
24
37
|
rationale,
|
|
25
|
-
alternatives_considered
|
|
38
|
+
alternatives_considered: alternatives_considered
|
|
26
39
|
}, session.currentSessionId || undefined);
|
|
27
40
|
if (!response.ok) {
|
|
28
41
|
throw new Error(`Failed to log decision: ${response.error}`);
|
|
29
42
|
}
|
|
30
43
|
return { result: { success: true, title, decision_id: response.data?.decision_id } };
|
|
31
44
|
};
|
|
32
|
-
export const getDecisions = async (args,
|
|
33
|
-
const { project_id } = args;
|
|
34
|
-
validateRequired(project_id, 'project_id');
|
|
35
|
-
validateUUID(project_id, 'project_id');
|
|
45
|
+
export const getDecisions = async (args, _ctx) => {
|
|
46
|
+
const { project_id, limit, offset, search_query } = parseArgs(args, getDecisionsSchema);
|
|
36
47
|
const apiClient = getApiClient();
|
|
37
|
-
const response = await apiClient.getDecisions(project_id
|
|
48
|
+
const response = await apiClient.getDecisions(project_id, {
|
|
49
|
+
limit,
|
|
50
|
+
offset,
|
|
51
|
+
search_query
|
|
52
|
+
});
|
|
38
53
|
if (!response.ok) {
|
|
39
54
|
throw new Error(`Failed to fetch decisions: ${response.error}`);
|
|
40
55
|
}
|
|
@@ -44,10 +59,8 @@ export const getDecisions = async (args, ctx) => {
|
|
|
44
59
|
},
|
|
45
60
|
};
|
|
46
61
|
};
|
|
47
|
-
export const deleteDecision = async (args,
|
|
48
|
-
const { decision_id } = args;
|
|
49
|
-
validateRequired(decision_id, 'decision_id');
|
|
50
|
-
validateUUID(decision_id, 'decision_id');
|
|
62
|
+
export const deleteDecision = async (args, _ctx) => {
|
|
63
|
+
const { decision_id } = parseArgs(args, deleteDecisionSchema);
|
|
51
64
|
const apiClient = getApiClient();
|
|
52
65
|
const response = await apiClient.deleteDecision(decision_id);
|
|
53
66
|
if (!response.ok) {
|
|
@@ -13,21 +13,103 @@
|
|
|
13
13
|
* - complete_deployment_requirement
|
|
14
14
|
* - get_deployment_requirements
|
|
15
15
|
*/
|
|
16
|
-
import { ValidationError,
|
|
16
|
+
import { ValidationError, parseArgs, uuidValidator, createEnumValidator, } from '../validators.js';
|
|
17
17
|
import { getApiClient } from '../api-client.js';
|
|
18
|
+
const ENVIRONMENTS = ['development', 'staging', 'production'];
|
|
19
|
+
const VERSION_BUMPS = ['patch', 'minor', 'major'];
|
|
20
|
+
const REQUIREMENT_TYPES = ['migration', 'env_var', 'config', 'manual', 'breaking_change', 'agent_task'];
|
|
21
|
+
const REQUIREMENT_STAGES = ['preparation', 'deployment', 'verification'];
|
|
22
|
+
const REQUIREMENT_STATUSES = ['pending', 'completed', 'converted_to_task', 'all'];
|
|
23
|
+
const SCHEDULE_TYPES = ['once', 'daily', 'weekly', 'monthly'];
|
|
24
|
+
// ============================================================================
|
|
25
|
+
// Argument Schemas
|
|
26
|
+
// ============================================================================
|
|
27
|
+
const requestDeploymentSchema = {
|
|
28
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
29
|
+
environment: { type: 'string', default: 'production', validate: createEnumValidator(ENVIRONMENTS) },
|
|
30
|
+
version_bump: { type: 'string', default: 'patch', validate: createEnumValidator(VERSION_BUMPS) },
|
|
31
|
+
notes: { type: 'string' },
|
|
32
|
+
git_ref: { type: 'string' },
|
|
33
|
+
};
|
|
34
|
+
const claimDeploymentValidationSchema = {
|
|
35
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
36
|
+
};
|
|
37
|
+
const reportValidationSchema = {
|
|
38
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
39
|
+
build_passed: { type: 'boolean', required: true },
|
|
40
|
+
tests_passed: { type: 'boolean' },
|
|
41
|
+
error_message: { type: 'string' },
|
|
42
|
+
};
|
|
43
|
+
const checkDeploymentStatusSchema = {
|
|
44
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
45
|
+
};
|
|
46
|
+
const startDeploymentSchema = {
|
|
47
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
48
|
+
};
|
|
49
|
+
const completeDeploymentSchema = {
|
|
50
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
51
|
+
success: { type: 'boolean', required: true },
|
|
52
|
+
summary: { type: 'string' },
|
|
53
|
+
};
|
|
54
|
+
const cancelDeploymentSchema = {
|
|
55
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
56
|
+
reason: { type: 'string' },
|
|
57
|
+
};
|
|
58
|
+
const addDeploymentRequirementSchema = {
|
|
59
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
60
|
+
type: { type: 'string', required: true, validate: createEnumValidator(REQUIREMENT_TYPES) },
|
|
61
|
+
title: { type: 'string', required: true },
|
|
62
|
+
description: { type: 'string' },
|
|
63
|
+
file_path: { type: 'string' },
|
|
64
|
+
stage: { type: 'string', default: 'preparation', validate: createEnumValidator(REQUIREMENT_STAGES) },
|
|
65
|
+
blocking: { type: 'boolean', default: false },
|
|
66
|
+
recurring: { type: 'boolean', default: false },
|
|
67
|
+
};
|
|
68
|
+
const completeDeploymentRequirementSchema = {
|
|
69
|
+
requirement_id: { type: 'string', required: true, validate: uuidValidator },
|
|
70
|
+
};
|
|
71
|
+
const getDeploymentRequirementsSchema = {
|
|
72
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
73
|
+
status: { type: 'string', default: 'pending', validate: createEnumValidator(REQUIREMENT_STATUSES) },
|
|
74
|
+
stage: { type: 'string', validate: createEnumValidator([...REQUIREMENT_STAGES, 'all']) },
|
|
75
|
+
};
|
|
76
|
+
const scheduleDeploymentSchema = {
|
|
77
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
78
|
+
environment: { type: 'string', default: 'production', validate: createEnumValidator(ENVIRONMENTS) },
|
|
79
|
+
version_bump: { type: 'string', default: 'patch', validate: createEnumValidator(VERSION_BUMPS) },
|
|
80
|
+
schedule_type: { type: 'string', default: 'once', validate: createEnumValidator(SCHEDULE_TYPES) },
|
|
81
|
+
scheduled_at: { type: 'string', required: true },
|
|
82
|
+
auto_trigger: { type: 'boolean', default: true },
|
|
83
|
+
notes: { type: 'string' },
|
|
84
|
+
git_ref: { type: 'string' },
|
|
85
|
+
};
|
|
86
|
+
const getScheduledDeploymentsSchema = {
|
|
87
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
88
|
+
include_disabled: { type: 'boolean', default: false },
|
|
89
|
+
};
|
|
90
|
+
const updateScheduledDeploymentSchema = {
|
|
91
|
+
schedule_id: { type: 'string', required: true, validate: uuidValidator },
|
|
92
|
+
environment: { type: 'string', validate: createEnumValidator(ENVIRONMENTS) },
|
|
93
|
+
version_bump: { type: 'string', validate: createEnumValidator(VERSION_BUMPS) },
|
|
94
|
+
schedule_type: { type: 'string', validate: createEnumValidator(SCHEDULE_TYPES) },
|
|
95
|
+
scheduled_at: { type: 'string' },
|
|
96
|
+
auto_trigger: { type: 'boolean' },
|
|
97
|
+
enabled: { type: 'boolean' },
|
|
98
|
+
notes: { type: 'string' },
|
|
99
|
+
git_ref: { type: 'string' },
|
|
100
|
+
};
|
|
101
|
+
const deleteScheduledDeploymentSchema = {
|
|
102
|
+
schedule_id: { type: 'string', required: true, validate: uuidValidator },
|
|
103
|
+
};
|
|
104
|
+
const triggerScheduledDeploymentSchema = {
|
|
105
|
+
schedule_id: { type: 'string', required: true, validate: uuidValidator },
|
|
106
|
+
};
|
|
107
|
+
const checkDueDeploymentsSchema = {
|
|
108
|
+
project_id: { type: 'string', required: true, validate: uuidValidator },
|
|
109
|
+
};
|
|
18
110
|
export const requestDeployment = async (args, ctx) => {
|
|
19
|
-
const { project_id, environment
|
|
111
|
+
const { project_id, environment, version_bump, notes, git_ref } = parseArgs(args, requestDeploymentSchema);
|
|
20
112
|
const { session } = ctx;
|
|
21
|
-
validateRequired(project_id, 'project_id');
|
|
22
|
-
validateUUID(project_id, 'project_id');
|
|
23
|
-
validateEnvironment(environment);
|
|
24
|
-
if (version_bump && !['patch', 'minor', 'major'].includes(version_bump)) {
|
|
25
|
-
throw new ValidationError('Invalid version_bump value', {
|
|
26
|
-
field: 'version_bump',
|
|
27
|
-
validValues: ['patch', 'minor', 'major'],
|
|
28
|
-
hint: 'Must be one of: patch, minor, major',
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
113
|
const apiClient = getApiClient();
|
|
32
114
|
const response = await apiClient.requestDeployment(project_id, {
|
|
33
115
|
environment,
|
|
@@ -41,10 +123,8 @@ export const requestDeployment = async (args, ctx) => {
|
|
|
41
123
|
return { result: response.data };
|
|
42
124
|
};
|
|
43
125
|
export const claimDeploymentValidation = async (args, ctx) => {
|
|
44
|
-
const { project_id } = args;
|
|
126
|
+
const { project_id } = parseArgs(args, claimDeploymentValidationSchema);
|
|
45
127
|
const { session } = ctx;
|
|
46
|
-
validateRequired(project_id, 'project_id');
|
|
47
|
-
validateUUID(project_id, 'project_id');
|
|
48
128
|
const apiClient = getApiClient();
|
|
49
129
|
const response = await apiClient.claimDeploymentValidation(project_id, session.currentSessionId || undefined);
|
|
50
130
|
if (!response.ok) {
|
|
@@ -53,16 +133,8 @@ export const claimDeploymentValidation = async (args, ctx) => {
|
|
|
53
133
|
return { result: response.data };
|
|
54
134
|
};
|
|
55
135
|
export const reportValidation = async (args, ctx) => {
|
|
56
|
-
const { project_id, build_passed, tests_passed, error_message } = args;
|
|
136
|
+
const { project_id, build_passed, tests_passed, error_message } = parseArgs(args, reportValidationSchema);
|
|
57
137
|
const { session } = ctx;
|
|
58
|
-
validateRequired(project_id, 'project_id');
|
|
59
|
-
validateUUID(project_id, 'project_id');
|
|
60
|
-
if (build_passed === undefined) {
|
|
61
|
-
throw new ValidationError('build_passed is required', {
|
|
62
|
-
field: 'build_passed',
|
|
63
|
-
hint: 'Set to true if the build succeeded, false otherwise',
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
138
|
const apiClient = getApiClient();
|
|
67
139
|
const response = await apiClient.reportValidation(project_id, {
|
|
68
140
|
build_passed,
|
|
@@ -75,9 +147,7 @@ export const reportValidation = async (args, ctx) => {
|
|
|
75
147
|
return { result: response.data };
|
|
76
148
|
};
|
|
77
149
|
export const checkDeploymentStatus = async (args, ctx) => {
|
|
78
|
-
const { project_id } = args;
|
|
79
|
-
validateRequired(project_id, 'project_id');
|
|
80
|
-
validateUUID(project_id, 'project_id');
|
|
150
|
+
const { project_id } = parseArgs(args, checkDeploymentStatusSchema);
|
|
81
151
|
const apiClient = getApiClient();
|
|
82
152
|
const response = await apiClient.checkDeploymentStatus(project_id);
|
|
83
153
|
if (!response.ok) {
|
|
@@ -86,10 +156,8 @@ export const checkDeploymentStatus = async (args, ctx) => {
|
|
|
86
156
|
return { result: response.data };
|
|
87
157
|
};
|
|
88
158
|
export const startDeployment = async (args, ctx) => {
|
|
89
|
-
const { project_id } = args;
|
|
159
|
+
const { project_id } = parseArgs(args, startDeploymentSchema);
|
|
90
160
|
const { session } = ctx;
|
|
91
|
-
validateRequired(project_id, 'project_id');
|
|
92
|
-
validateUUID(project_id, 'project_id');
|
|
93
161
|
const apiClient = getApiClient();
|
|
94
162
|
const response = await apiClient.startDeployment(project_id, session.currentSessionId || undefined);
|
|
95
163
|
if (!response.ok) {
|
|
@@ -98,16 +166,8 @@ export const startDeployment = async (args, ctx) => {
|
|
|
98
166
|
return { result: response.data };
|
|
99
167
|
};
|
|
100
168
|
export const completeDeployment = async (args, ctx) => {
|
|
101
|
-
const { project_id, success, summary } = args;
|
|
169
|
+
const { project_id, success, summary } = parseArgs(args, completeDeploymentSchema);
|
|
102
170
|
const { session } = ctx;
|
|
103
|
-
validateRequired(project_id, 'project_id');
|
|
104
|
-
validateUUID(project_id, 'project_id');
|
|
105
|
-
if (success === undefined) {
|
|
106
|
-
throw new ValidationError('success is required', {
|
|
107
|
-
field: 'success',
|
|
108
|
-
hint: 'Set to true if deployment succeeded, false otherwise',
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
171
|
const apiClient = getApiClient();
|
|
112
172
|
const response = await apiClient.completeDeployment(project_id, {
|
|
113
173
|
success,
|
|
@@ -119,9 +179,7 @@ export const completeDeployment = async (args, ctx) => {
|
|
|
119
179
|
return { result: response.data };
|
|
120
180
|
};
|
|
121
181
|
export const cancelDeployment = async (args, ctx) => {
|
|
122
|
-
const { project_id, reason } = args;
|
|
123
|
-
validateRequired(project_id, 'project_id');
|
|
124
|
-
validateUUID(project_id, 'project_id');
|
|
182
|
+
const { project_id, reason } = parseArgs(args, cancelDeploymentSchema);
|
|
125
183
|
const apiClient = getApiClient();
|
|
126
184
|
const response = await apiClient.cancelDeployment(project_id, reason);
|
|
127
185
|
if (!response.ok) {
|
|
@@ -130,19 +188,7 @@ export const cancelDeployment = async (args, ctx) => {
|
|
|
130
188
|
return { result: response.data };
|
|
131
189
|
};
|
|
132
190
|
export const addDeploymentRequirement = async (args, ctx) => {
|
|
133
|
-
const { project_id, type, title, description, file_path, stage
|
|
134
|
-
validateRequired(project_id, 'project_id');
|
|
135
|
-
validateUUID(project_id, 'project_id');
|
|
136
|
-
validateRequired(type, 'type');
|
|
137
|
-
validateRequired(title, 'title');
|
|
138
|
-
const validTypes = ['migration', 'env_var', 'config', 'manual', 'breaking_change', 'agent_task'];
|
|
139
|
-
if (!validTypes.includes(type)) {
|
|
140
|
-
throw new ValidationError(`type must be one of: ${validTypes.join(', ')}`);
|
|
141
|
-
}
|
|
142
|
-
const validStages = ['preparation', 'deployment', 'verification'];
|
|
143
|
-
if (!validStages.includes(stage)) {
|
|
144
|
-
throw new ValidationError(`stage must be one of: ${validStages.join(', ')}`);
|
|
145
|
-
}
|
|
191
|
+
const { project_id, type, title, description, file_path, stage, blocking, recurring } = parseArgs(args, addDeploymentRequirementSchema);
|
|
146
192
|
const apiClient = getApiClient();
|
|
147
193
|
const response = await apiClient.addDeploymentRequirement(project_id, {
|
|
148
194
|
type: type,
|
|
@@ -150,7 +196,8 @@ export const addDeploymentRequirement = async (args, ctx) => {
|
|
|
150
196
|
description,
|
|
151
197
|
file_path,
|
|
152
198
|
stage: stage,
|
|
153
|
-
blocking
|
|
199
|
+
blocking,
|
|
200
|
+
recurring
|
|
154
201
|
});
|
|
155
202
|
if (!response.ok) {
|
|
156
203
|
throw new Error(response.error || 'Failed to add deployment requirement');
|
|
@@ -158,9 +205,7 @@ export const addDeploymentRequirement = async (args, ctx) => {
|
|
|
158
205
|
return { result: response.data };
|
|
159
206
|
};
|
|
160
207
|
export const completeDeploymentRequirement = async (args, ctx) => {
|
|
161
|
-
const { requirement_id } = args;
|
|
162
|
-
validateRequired(requirement_id, 'requirement_id');
|
|
163
|
-
validateUUID(requirement_id, 'requirement_id');
|
|
208
|
+
const { requirement_id } = parseArgs(args, completeDeploymentRequirementSchema);
|
|
164
209
|
const apiClient = getApiClient();
|
|
165
210
|
const response = await apiClient.completeDeploymentRequirement(requirement_id);
|
|
166
211
|
if (!response.ok) {
|
|
@@ -169,9 +214,7 @@ export const completeDeploymentRequirement = async (args, ctx) => {
|
|
|
169
214
|
return { result: response.data };
|
|
170
215
|
};
|
|
171
216
|
export const getDeploymentRequirements = async (args, ctx) => {
|
|
172
|
-
const { project_id, status
|
|
173
|
-
validateRequired(project_id, 'project_id');
|
|
174
|
-
validateUUID(project_id, 'project_id');
|
|
217
|
+
const { project_id, status, stage } = parseArgs(args, getDeploymentRequirementsSchema);
|
|
175
218
|
const apiClient = getApiClient();
|
|
176
219
|
const response = await apiClient.getDeploymentRequirements(project_id, {
|
|
177
220
|
status: status,
|
|
@@ -186,23 +229,7 @@ export const getDeploymentRequirements = async (args, ctx) => {
|
|
|
186
229
|
// Scheduled Deployments
|
|
187
230
|
// ============================================================================
|
|
188
231
|
export const scheduleDeployment = async (args, ctx) => {
|
|
189
|
-
const { project_id, environment
|
|
190
|
-
validateRequired(project_id, 'project_id');
|
|
191
|
-
validateUUID(project_id, 'project_id');
|
|
192
|
-
validateRequired(scheduled_at, 'scheduled_at');
|
|
193
|
-
validateEnvironment(environment);
|
|
194
|
-
if (!['patch', 'minor', 'major'].includes(version_bump)) {
|
|
195
|
-
throw new ValidationError('Invalid version_bump value', {
|
|
196
|
-
field: 'version_bump',
|
|
197
|
-
validValues: ['patch', 'minor', 'major'],
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
if (!['once', 'daily', 'weekly', 'monthly'].includes(schedule_type)) {
|
|
201
|
-
throw new ValidationError('Invalid schedule_type value', {
|
|
202
|
-
field: 'schedule_type',
|
|
203
|
-
validValues: ['once', 'daily', 'weekly', 'monthly'],
|
|
204
|
-
});
|
|
205
|
-
}
|
|
232
|
+
const { project_id, environment, version_bump, schedule_type, scheduled_at, auto_trigger, notes, git_ref, } = parseArgs(args, scheduleDeploymentSchema);
|
|
206
233
|
// Parse and validate scheduled_at
|
|
207
234
|
const scheduledDate = new Date(scheduled_at);
|
|
208
235
|
if (isNaN(scheduledDate.getTime())) {
|
|
@@ -232,9 +259,7 @@ export const scheduleDeployment = async (args, ctx) => {
|
|
|
232
259
|
return { result: response.data };
|
|
233
260
|
};
|
|
234
261
|
export const getScheduledDeployments = async (args, ctx) => {
|
|
235
|
-
const { project_id, include_disabled
|
|
236
|
-
validateRequired(project_id, 'project_id');
|
|
237
|
-
validateUUID(project_id, 'project_id');
|
|
262
|
+
const { project_id, include_disabled } = parseArgs(args, getScheduledDeploymentsSchema);
|
|
238
263
|
const apiClient = getApiClient();
|
|
239
264
|
const response = await apiClient.getScheduledDeployments(project_id, include_disabled);
|
|
240
265
|
if (!response.ok) {
|
|
@@ -243,26 +268,14 @@ export const getScheduledDeployments = async (args, ctx) => {
|
|
|
243
268
|
return { result: response.data };
|
|
244
269
|
};
|
|
245
270
|
export const updateScheduledDeployment = async (args, ctx) => {
|
|
246
|
-
const { schedule_id, environment, version_bump, schedule_type, scheduled_at, auto_trigger, enabled, notes, git_ref, } = args;
|
|
247
|
-
validateRequired(schedule_id, 'schedule_id');
|
|
248
|
-
validateUUID(schedule_id, 'schedule_id');
|
|
271
|
+
const { schedule_id, environment, version_bump, schedule_type, scheduled_at, auto_trigger, enabled, notes, git_ref, } = parseArgs(args, updateScheduledDeploymentSchema);
|
|
249
272
|
const updates = {};
|
|
250
|
-
if (environment !== undefined)
|
|
251
|
-
validateEnvironment(environment);
|
|
273
|
+
if (environment !== undefined)
|
|
252
274
|
updates.environment = environment;
|
|
253
|
-
|
|
254
|
-
if (version_bump !== undefined) {
|
|
255
|
-
if (!['patch', 'minor', 'major'].includes(version_bump)) {
|
|
256
|
-
throw new ValidationError('Invalid version_bump value');
|
|
257
|
-
}
|
|
275
|
+
if (version_bump !== undefined)
|
|
258
276
|
updates.version_bump = version_bump;
|
|
259
|
-
|
|
260
|
-
if (schedule_type !== undefined) {
|
|
261
|
-
if (!['once', 'daily', 'weekly', 'monthly'].includes(schedule_type)) {
|
|
262
|
-
throw new ValidationError('Invalid schedule_type value');
|
|
263
|
-
}
|
|
277
|
+
if (schedule_type !== undefined)
|
|
264
278
|
updates.schedule_type = schedule_type;
|
|
265
|
-
}
|
|
266
279
|
if (scheduled_at !== undefined) {
|
|
267
280
|
const scheduledDate = new Date(scheduled_at);
|
|
268
281
|
if (isNaN(scheduledDate.getTime())) {
|
|
@@ -289,9 +302,7 @@ export const updateScheduledDeployment = async (args, ctx) => {
|
|
|
289
302
|
return { result: response.data };
|
|
290
303
|
};
|
|
291
304
|
export const deleteScheduledDeployment = async (args, ctx) => {
|
|
292
|
-
const { schedule_id } = args;
|
|
293
|
-
validateRequired(schedule_id, 'schedule_id');
|
|
294
|
-
validateUUID(schedule_id, 'schedule_id');
|
|
305
|
+
const { schedule_id } = parseArgs(args, deleteScheduledDeploymentSchema);
|
|
295
306
|
const apiClient = getApiClient();
|
|
296
307
|
const response = await apiClient.deleteScheduledDeployment(schedule_id);
|
|
297
308
|
if (!response.ok) {
|
|
@@ -300,10 +311,8 @@ export const deleteScheduledDeployment = async (args, ctx) => {
|
|
|
300
311
|
return { result: response.data };
|
|
301
312
|
};
|
|
302
313
|
export const triggerScheduledDeployment = async (args, ctx) => {
|
|
303
|
-
const { schedule_id } = args;
|
|
314
|
+
const { schedule_id } = parseArgs(args, triggerScheduledDeploymentSchema);
|
|
304
315
|
const { session } = ctx;
|
|
305
|
-
validateRequired(schedule_id, 'schedule_id');
|
|
306
|
-
validateUUID(schedule_id, 'schedule_id');
|
|
307
316
|
const apiClient = getApiClient();
|
|
308
317
|
const response = await apiClient.triggerScheduledDeployment(schedule_id, session.currentSessionId || undefined);
|
|
309
318
|
if (!response.ok) {
|
|
@@ -312,9 +321,7 @@ export const triggerScheduledDeployment = async (args, ctx) => {
|
|
|
312
321
|
return { result: response.data };
|
|
313
322
|
};
|
|
314
323
|
export const checkDueDeployments = async (args, ctx) => {
|
|
315
|
-
const { project_id } = args;
|
|
316
|
-
validateRequired(project_id, 'project_id');
|
|
317
|
-
validateUUID(project_id, 'project_id');
|
|
324
|
+
const { project_id } = parseArgs(args, checkDueDeploymentsSchema);
|
|
318
325
|
const apiClient = getApiClient();
|
|
319
326
|
const response = await apiClient.checkDueDeployments(project_id);
|
|
320
327
|
if (!response.ok) {
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* Handles tool discovery and documentation:
|
|
5
5
|
* - discover_tools
|
|
6
6
|
* - get_tool_info
|
|
7
|
+
*
|
|
8
|
+
* Note: Tool documentation is lazy-loaded from tool-docs.ts to save tokens.
|
|
9
|
+
* This saves ~8,000 tokens per schema load.
|
|
7
10
|
*/
|
|
8
11
|
import type { Handler, HandlerRegistry } from './types.js';
|
|
9
12
|
export declare const discoverTools: Handler;
|