@perfai/mcp 1.0.24
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/LICENSE +21 -0
- package/README.md +352 -0
- package/dist/auth/authManager.d.ts +83 -0
- package/dist/auth/authManager.d.ts.map +1 -0
- package/dist/auth/authManager.js +555 -0
- package/dist/auth/sessionCache.d.ts +5 -0
- package/dist/auth/sessionCache.d.ts.map +1 -0
- package/dist/auth/sessionCache.js +29 -0
- package/dist/auth/sessionStorage.d.ts +53 -0
- package/dist/auth/sessionStorage.d.ts.map +1 -0
- package/dist/auth/sessionStorage.js +234 -0
- package/dist/auth/types.d.ts +28 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +74 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +144 -0
- package/dist/setup-config.d.ts +4 -0
- package/dist/setup-config.d.ts.map +1 -0
- package/dist/setup-config.js +69 -0
- package/dist/tools/index.d.ts +361 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +275 -0
- package/dist/tools/protected/aiFixDesignIssue.d.ts +17 -0
- package/dist/tools/protected/aiFixDesignIssue.d.ts.map +1 -0
- package/dist/tools/protected/aiFixDesignIssue.js +205 -0
- package/dist/tools/protected/aiFixQualityIssue.d.ts +17 -0
- package/dist/tools/protected/aiFixQualityIssue.d.ts.map +1 -0
- package/dist/tools/protected/aiFixQualityIssue.js +188 -0
- package/dist/tools/protected/aiFixSecurityIssue.d.ts +17 -0
- package/dist/tools/protected/aiFixSecurityIssue.d.ts.map +1 -0
- package/dist/tools/protected/aiFixSecurityIssue.js +205 -0
- package/dist/tools/protected/checkDesignFixes.d.ts +17 -0
- package/dist/tools/protected/checkDesignFixes.d.ts.map +1 -0
- package/dist/tools/protected/checkDesignFixes.js +199 -0
- package/dist/tools/protected/checkQualityFixes.d.ts +17 -0
- package/dist/tools/protected/checkQualityFixes.d.ts.map +1 -0
- package/dist/tools/protected/checkQualityFixes.js +199 -0
- package/dist/tools/protected/checkSecurityFixes.d.ts +17 -0
- package/dist/tools/protected/checkSecurityFixes.d.ts.map +1 -0
- package/dist/tools/protected/checkSecurityFixes.js +177 -0
- package/dist/tools/protected/listApis.d.ts +28 -0
- package/dist/tools/protected/listApis.d.ts.map +1 -0
- package/dist/tools/protected/listApis.js +102 -0
- package/dist/tools/protected/logout.d.ts +11 -0
- package/dist/tools/protected/logout.d.ts.map +1 -0
- package/dist/tools/protected/logout.js +22 -0
- package/dist/tools/protected/manageOrganizations.d.ts +26 -0
- package/dist/tools/protected/manageOrganizations.d.ts.map +1 -0
- package/dist/tools/protected/manageOrganizations.js +147 -0
- package/dist/tools/protected/runDesignTest.d.ts +21 -0
- package/dist/tools/protected/runDesignTest.d.ts.map +1 -0
- package/dist/tools/protected/runDesignTest.js +132 -0
- package/dist/tools/protected/runQualityTest.d.ts +21 -0
- package/dist/tools/protected/runQualityTest.d.ts.map +1 -0
- package/dist/tools/protected/runQualityTest.js +150 -0
- package/dist/tools/protected/runSecurityTest.d.ts +21 -0
- package/dist/tools/protected/runSecurityTest.d.ts.map +1 -0
- package/dist/tools/protected/runSecurityTest.js +107 -0
- package/dist/tools/protected/selectApi.d.ts +24 -0
- package/dist/tools/protected/selectApi.d.ts.map +1 -0
- package/dist/tools/protected/selectApi.js +172 -0
- package/dist/tools/protected/setup.d.ts +11 -0
- package/dist/tools/protected/setup.d.ts.map +1 -0
- package/dist/tools/protected/setup.js +151 -0
- package/dist/tools/protected/showDesignIssues.d.ts +38 -0
- package/dist/tools/protected/showDesignIssues.d.ts.map +1 -0
- package/dist/tools/protected/showDesignIssues.js +201 -0
- package/dist/tools/protected/showFixedIssues.d.ts +11 -0
- package/dist/tools/protected/showFixedIssues.d.ts.map +1 -0
- package/dist/tools/protected/showFixedIssues.js +36 -0
- package/dist/tools/protected/showQualityIssues.d.ts +33 -0
- package/dist/tools/protected/showQualityIssues.d.ts.map +1 -0
- package/dist/tools/protected/showQualityIssues.js +225 -0
- package/dist/tools/protected/showSecurityIssues.d.ts +47 -0
- package/dist/tools/protected/showSecurityIssues.d.ts.map +1 -0
- package/dist/tools/protected/showSecurityIssues.js +212 -0
- package/dist/tools/protected/summarizeIssues.d.ts +11 -0
- package/dist/tools/protected/summarizeIssues.d.ts.map +1 -0
- package/dist/tools/protected/summarizeIssues.js +161 -0
- package/dist/tools/protected/userInfo.d.ts +11 -0
- package/dist/tools/protected/userInfo.d.ts.map +1 -0
- package/dist/tools/protected/userInfo.js +21 -0
- package/dist/tools/protected/visionAiAppLearning.d.ts +37 -0
- package/dist/tools/protected/visionAiAppLearning.d.ts.map +1 -0
- package/dist/tools/protected/visionAiAppLearning.js +122 -0
- package/dist/tools/public/authStatus.d.ts +11 -0
- package/dist/tools/public/authStatus.d.ts.map +1 -0
- package/dist/tools/public/authStatus.js +78 -0
- package/dist/tools/public/login.d.ts +12 -0
- package/dist/tools/public/login.d.ts.map +1 -0
- package/dist/tools/public/login.js +230 -0
- package/dist/types/api.d.ts +12 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +1 -0
- package/dist/utils/dockerRunner.d.ts +44 -0
- package/dist/utils/dockerRunner.d.ts.map +1 -0
- package/dist/utils/dockerRunner.js +300 -0
- package/dist/utils/formatters.d.ts +14 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +510 -0
- package/dist/utils/promptBuilder.d.ts +4 -0
- package/dist/utils/promptBuilder.d.ts.map +1 -0
- package/dist/utils/promptBuilder.js +132 -0
- package/package.json +67 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { API_ENDPOINTS } from "../../config.js";
|
|
3
|
+
// Function to compare fixed design issues with current design issues
|
|
4
|
+
function compareAndCountFixedDesignIssues(previousIssues, currentIssues) {
|
|
5
|
+
let fixedCount = 0;
|
|
6
|
+
const fixedIssues = [];
|
|
7
|
+
const stillExistsIssues = [];
|
|
8
|
+
// Loop through each design issue we attempted to fix
|
|
9
|
+
for (const previousIssue of previousIssues) {
|
|
10
|
+
// Check if this previous issue still exists in current issues
|
|
11
|
+
const stillExists = currentIssues.some((currentIssue) => currentIssue.method === previousIssue.method &&
|
|
12
|
+
currentIssue.path === previousIssue.path &&
|
|
13
|
+
currentIssue.category === previousIssue.category);
|
|
14
|
+
// If the issue no longer exists in current issues, it was fixed
|
|
15
|
+
if (!stillExists) {
|
|
16
|
+
fixedCount++;
|
|
17
|
+
fixedIssues.push(previousIssue);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
stillExistsIssues.push(previousIssue);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return { fixedCount, fixedIssues, stillExistsIssues };
|
|
24
|
+
}
|
|
25
|
+
// Function to fetch current design issues
|
|
26
|
+
async function fetchDesignIssues(accessToken, tokenType, orgId, designAppId) {
|
|
27
|
+
const url = `${API_ENDPOINTS.DESIGN_ISSUES_BY_APP}?app_id=${encodeURIComponent(designAppId)}&limit=100`;
|
|
28
|
+
const response = await axios.get(url, {
|
|
29
|
+
headers: {
|
|
30
|
+
'Authorization': `${tokenType} ${accessToken}`,
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
'X-Org-ID': orgId
|
|
33
|
+
},
|
|
34
|
+
timeout: 30000
|
|
35
|
+
});
|
|
36
|
+
if (response.status !== 200 || !response.data) {
|
|
37
|
+
throw new Error(`Failed to fetch design issues: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return response.data.issues || [];
|
|
40
|
+
}
|
|
41
|
+
export const checkDesignFixesTool = {
|
|
42
|
+
name: "check_design_fixes",
|
|
43
|
+
description: "š Check which previously fixed design issues were actually resolved (auto-triggered after run_design_test)",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
wait_seconds: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Wait time before checking issues (default: 15 seconds)",
|
|
50
|
+
default: 15
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export async function handleCheckDesignFixes(authManager, args) {
|
|
57
|
+
try {
|
|
58
|
+
const waitSeconds = args.wait_seconds || 15;
|
|
59
|
+
const accessToken = authManager.getAccessToken();
|
|
60
|
+
const tokenType = authManager.getTokenType();
|
|
61
|
+
const orgId = authManager.getSelectedOrgId();
|
|
62
|
+
const selectedAppId = authManager.getSelectedApiId();
|
|
63
|
+
if (!accessToken) {
|
|
64
|
+
throw new Error('No access token available');
|
|
65
|
+
}
|
|
66
|
+
if (!orgId) {
|
|
67
|
+
throw new Error('No organization selected. Please select an organization first using manage_organizations tool.');
|
|
68
|
+
}
|
|
69
|
+
if (!selectedAppId) {
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: `ā **No APP Selected**\n\nšÆ **Required**: You must select an APP first to check design fixes.\n\nš **Steps**:\n1. Run \`list_apps\` to see available APPs\n2. Run \`select_app\` with an APP ID\n3. Run \`show_design_issues\` to see design issues\n4. Then run this tool again`,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// First, get the app details using the catalog ID to get the design app ID
|
|
80
|
+
const catalogUrl = `${API_ENDPOINTS.API_CATALOG_SERVICE_IDS}/${selectedAppId}`;
|
|
81
|
+
let appDetails;
|
|
82
|
+
try {
|
|
83
|
+
const catalogResponse = await axios.get(catalogUrl, {
|
|
84
|
+
headers: {
|
|
85
|
+
'Authorization': `${tokenType} ${accessToken}`,
|
|
86
|
+
'Content-Type': 'application/json',
|
|
87
|
+
'X-Org-ID': orgId
|
|
88
|
+
},
|
|
89
|
+
timeout: 30000
|
|
90
|
+
});
|
|
91
|
+
if (catalogResponse.status !== 200 || !catalogResponse.data) {
|
|
92
|
+
throw new Error(`Failed to fetch app details with status ${catalogResponse.status}`);
|
|
93
|
+
}
|
|
94
|
+
appDetails = catalogResponse.data;
|
|
95
|
+
if (!appDetails.design_test_appId) {
|
|
96
|
+
throw new Error('No design_test_appId found for this app');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: `ā **Error fetching app details**\n\nš“ **Error**: ${errorMessage}\n\nš” **Tip**: Make sure the selected app has design testing enabled.`,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Use the design_test_appId for fetching design issues
|
|
111
|
+
const designAppId = appDetails.design_test_appId;
|
|
112
|
+
// Get current fixed design issues from session
|
|
113
|
+
const fixedIssues = authManager.getFixedDesignIssues();
|
|
114
|
+
const previousIssues = fixedIssues.map((fi) => fi.issue);
|
|
115
|
+
if (previousIssues.length === 0) {
|
|
116
|
+
return {
|
|
117
|
+
content: [
|
|
118
|
+
{
|
|
119
|
+
type: "text",
|
|
120
|
+
text: `ā¹ļø **No Fixed Design Issues to Check**\n\nšÆ **Status**: No previously fixed design issues found in session.\n\nš” **Tip**: Use \`ai_fix_design_issue\` to fix some design issues first, then run \`run_design_test\`, and then this tool.`,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
console.error(`š Found ${previousIssues.length} previously fixed design issues to check`);
|
|
126
|
+
// Wait for specified time for system to process
|
|
127
|
+
console.error(`ā³ Waiting ${waitSeconds} seconds for system to process design issues...`);
|
|
128
|
+
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
|
|
129
|
+
console.error('ā
Wait completed, fetching updated design issues...');
|
|
130
|
+
// Fetch current design issues
|
|
131
|
+
console.error('š Fetching current design issues...');
|
|
132
|
+
const currentIssues = await fetchDesignIssues(accessToken, tokenType, orgId, designAppId);
|
|
133
|
+
console.error(`š Found ${currentIssues.length} current design issues`);
|
|
134
|
+
// Compare fixed issues with current issues
|
|
135
|
+
const comparison = compareAndCountFixedDesignIssues(previousIssues, currentIssues);
|
|
136
|
+
// Create comparison table
|
|
137
|
+
const createComparisonTable = () => {
|
|
138
|
+
const lines = [];
|
|
139
|
+
if (comparison.fixedCount > 0) {
|
|
140
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
141
|
+
lines.push('ā Fixed Design Issues ā Endpoint ā Status ā');
|
|
142
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
143
|
+
comparison.fixedIssues.forEach((issue, index) => {
|
|
144
|
+
const issueType = issue.category || issue.label || 'Unknown Issue';
|
|
145
|
+
const method = issue.method || 'MULTIPLE';
|
|
146
|
+
const path = issue.path || '/unknown';
|
|
147
|
+
const endpoint = `${method} ${path}`;
|
|
148
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
149
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
150
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
151
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
152
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā
FIXED ā`);
|
|
153
|
+
});
|
|
154
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
155
|
+
}
|
|
156
|
+
if (comparison.stillExistsIssues.length > 0) {
|
|
157
|
+
lines.push('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
158
|
+
lines.push('ā Still Existing Design Issues ā Endpoint ā Status ā');
|
|
159
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
160
|
+
comparison.stillExistsIssues.forEach((issue, index) => {
|
|
161
|
+
const issueType = issue.category || issue.label || 'Unknown Issue';
|
|
162
|
+
const method = issue.method || 'MULTIPLE';
|
|
163
|
+
const path = issue.path || '/unknown';
|
|
164
|
+
const endpoint = `${method} ${path}`;
|
|
165
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
166
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
167
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
168
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
169
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā STILL EXISTS ā`);
|
|
170
|
+
});
|
|
171
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
172
|
+
}
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
};
|
|
175
|
+
const comparisonTable = createComparisonTable();
|
|
176
|
+
// Clear fixed design issues after comparison is done
|
|
177
|
+
console.error('šļø Clearing fixed design issues after comparison...');
|
|
178
|
+
authManager.clearFixedDesignIssues();
|
|
179
|
+
return {
|
|
180
|
+
content: [
|
|
181
|
+
{
|
|
182
|
+
type: "text",
|
|
183
|
+
text: `š **Design Fixes Check Results**\n\nšÆ **APP**: ${selectedAppId}\nšØ **Organization**: ${orgId}\n\nš **Issue Comparison Results**:\n\n**Previously Fixed Design Issues**: ${previousIssues.length}\n**Current Design Issues**: ${currentIssues.length}\n**Actually Fixed**: ${comparison.fixedCount}\n**Still Existing**: ${comparison.stillExistsIssues.length}\n\n${comparisonTable}\n\nā³ **Processing Wait**: System waited ${waitSeconds} seconds to ensure design issues were fully processed and updated.\n\nšļø **Fixed Design Issues Cleared**: All previously fixed design issues have been cleared from session after comparison.\n\nā
**Status**: Design fix verification completed.\n\nš” **Next Steps**:\n1. Review the comparison results above\n2. For still existing issues, use \`ai_fix_design_issue\` to generate new fixes\n3. Run \`run_design_test\` again to test new fixes\n4. Use \`check_design_fixes\` to verify the new fixes`,
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
190
|
+
return {
|
|
191
|
+
content: [
|
|
192
|
+
{
|
|
193
|
+
type: "text",
|
|
194
|
+
text: `ā **Error checking design fixes**\n\nš“ **Error**: ${errorMessage}\n\nš” **Tip**: Make sure you're authenticated, have an organization selected, and have run \`run_design_test\` first.\n\nš **Try**: Check your inputs and try again.`,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const checkQualityFixesTool: {
|
|
2
|
+
readonly name: "check_quality_fixes";
|
|
3
|
+
readonly description: "š Check which previously fixed quality issues were actually resolved (auto-triggered after run_quality_test)";
|
|
4
|
+
readonly inputSchema: {
|
|
5
|
+
readonly type: "object";
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly wait_seconds: {
|
|
8
|
+
readonly type: "number";
|
|
9
|
+
readonly description: "Wait time before checking issues (default: 15 seconds)";
|
|
10
|
+
readonly default: 15;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
readonly additionalProperties: false;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function handleCheckQualityFixes(authManager: any, args: any): Promise<any>;
|
|
17
|
+
//# sourceMappingURL=checkQualityFixes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkQualityFixes.d.ts","sourceRoot":"","sources":["../../../src/tools/protected/checkQualityFixes.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;CAcxB,CAAC;AAEX,wBAAsB,uBAAuB,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CA8KvF"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { API_ENDPOINTS } from "../../config.js";
|
|
3
|
+
// Function to compare fixed quality issues with current quality issues
|
|
4
|
+
function compareAndCountFixedQualityIssues(previousIssues, currentIssues) {
|
|
5
|
+
let fixedCount = 0;
|
|
6
|
+
const fixedIssues = [];
|
|
7
|
+
const stillExistsIssues = [];
|
|
8
|
+
// Loop through each quality issue we attempted to fix
|
|
9
|
+
for (const previousIssue of previousIssues) {
|
|
10
|
+
// Check if this previous issue still exists in current issues
|
|
11
|
+
const stillExists = currentIssues.some((currentIssue) => currentIssue.method === previousIssue.method &&
|
|
12
|
+
currentIssue.path === previousIssue.path &&
|
|
13
|
+
currentIssue.category === previousIssue.category);
|
|
14
|
+
// If the issue no longer exists in current issues, it was fixed
|
|
15
|
+
if (!stillExists) {
|
|
16
|
+
fixedCount++;
|
|
17
|
+
fixedIssues.push(previousIssue);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
stillExistsIssues.push(previousIssue);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return { fixedCount, fixedIssues, stillExistsIssues };
|
|
24
|
+
}
|
|
25
|
+
// Function to fetch current quality issues
|
|
26
|
+
async function fetchQualityIssues(accessToken, tokenType, orgId, qualityAppId) {
|
|
27
|
+
const url = `${API_ENDPOINTS.QUALITY_ISSUES_BY_APP}/${qualityAppId}?page=1&pageSize=100`;
|
|
28
|
+
const response = await axios.get(url, {
|
|
29
|
+
headers: {
|
|
30
|
+
'Authorization': `${tokenType} ${accessToken}`,
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
'X-Org-ID': orgId
|
|
33
|
+
},
|
|
34
|
+
timeout: 30000
|
|
35
|
+
});
|
|
36
|
+
if (response.status !== 200 || !response.data) {
|
|
37
|
+
throw new Error(`Failed to fetch quality issues: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return response.data.tests || [];
|
|
40
|
+
}
|
|
41
|
+
export const checkQualityFixesTool = {
|
|
42
|
+
name: "check_quality_fixes",
|
|
43
|
+
description: "š Check which previously fixed quality issues were actually resolved (auto-triggered after run_quality_test)",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
wait_seconds: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Wait time before checking issues (default: 15 seconds)",
|
|
50
|
+
default: 15
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export async function handleCheckQualityFixes(authManager, args) {
|
|
57
|
+
try {
|
|
58
|
+
const waitSeconds = args.wait_seconds || 15;
|
|
59
|
+
const accessToken = authManager.getAccessToken();
|
|
60
|
+
const tokenType = authManager.getTokenType();
|
|
61
|
+
const orgId = authManager.getSelectedOrgId();
|
|
62
|
+
const selectedAppId = authManager.getSelectedApiId();
|
|
63
|
+
if (!accessToken) {
|
|
64
|
+
throw new Error('No access token available');
|
|
65
|
+
}
|
|
66
|
+
if (!orgId) {
|
|
67
|
+
throw new Error('No organization selected. Please select an organization first using manage_organizations tool.');
|
|
68
|
+
}
|
|
69
|
+
if (!selectedAppId) {
|
|
70
|
+
return {
|
|
71
|
+
content: [
|
|
72
|
+
{
|
|
73
|
+
type: "text",
|
|
74
|
+
text: `ā **No APP Selected**\n\nšÆ **Required**: You must select an APP first to check quality fixes.\n\nš **Steps**:\n1. Run \`list_apps\` to see available APPs\n2. Run \`select_app\` with an APP ID\n3. Run \`show_quality_issues\` to see quality issues\n4. Then run this tool again`,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
// First, get the app details using the catalog ID to get the quality app ID
|
|
80
|
+
const catalogUrl = `${API_ENDPOINTS.API_CATALOG_SERVICE_IDS}/${selectedAppId}`;
|
|
81
|
+
let appDetails;
|
|
82
|
+
try {
|
|
83
|
+
const catalogResponse = await axios.get(catalogUrl, {
|
|
84
|
+
headers: {
|
|
85
|
+
'Authorization': `${tokenType} ${accessToken}`,
|
|
86
|
+
'Content-Type': 'application/json',
|
|
87
|
+
'X-Org-ID': orgId
|
|
88
|
+
},
|
|
89
|
+
timeout: 30000
|
|
90
|
+
});
|
|
91
|
+
if (catalogResponse.status !== 200 || !catalogResponse.data) {
|
|
92
|
+
throw new Error(`Failed to fetch app details with status ${catalogResponse.status}`);
|
|
93
|
+
}
|
|
94
|
+
appDetails = catalogResponse.data;
|
|
95
|
+
if (!appDetails.quality_test_appId) {
|
|
96
|
+
throw new Error('No quality_test_appId found for this app');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: `ā **Error fetching app details**\n\nš“ **Error**: ${errorMessage}\n\nš” **Tip**: Make sure the selected app has quality testing enabled.`,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Use the quality_test_appId for fetching quality issues
|
|
111
|
+
const qualityAppId = appDetails.quality_test_appId;
|
|
112
|
+
// Get current fixed quality issues from session
|
|
113
|
+
const fixedIssues = authManager.getFixedQualityIssues();
|
|
114
|
+
const previousIssues = fixedIssues.map((fi) => fi.issue);
|
|
115
|
+
if (previousIssues.length === 0) {
|
|
116
|
+
return {
|
|
117
|
+
content: [
|
|
118
|
+
{
|
|
119
|
+
type: "text",
|
|
120
|
+
text: `ā¹ļø **No Fixed Quality Issues to Check**\n\nšÆ **Status**: No previously fixed quality issues found in session.\n\nš” **Tip**: Use \`ai_fix_quality_issue\` to fix some quality issues first, then run \`run_quality_test\`, and then this tool.`,
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
console.error(`š Found ${previousIssues.length} previously fixed quality issues to check`);
|
|
126
|
+
// Wait for specified time for system to process
|
|
127
|
+
console.error(`ā³ Waiting ${waitSeconds} seconds for system to process quality issues...`);
|
|
128
|
+
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
|
|
129
|
+
console.error('ā
Wait completed, fetching updated quality issues...');
|
|
130
|
+
// Fetch current quality issues
|
|
131
|
+
console.error('š Fetching current quality issues...');
|
|
132
|
+
const currentIssues = await fetchQualityIssues(accessToken, tokenType, orgId, qualityAppId);
|
|
133
|
+
console.error(`š Found ${currentIssues.length} current quality issues`);
|
|
134
|
+
// Compare fixed issues with current issues
|
|
135
|
+
const comparison = compareAndCountFixedQualityIssues(previousIssues, currentIssues);
|
|
136
|
+
// Create comparison table
|
|
137
|
+
const createComparisonTable = () => {
|
|
138
|
+
const lines = [];
|
|
139
|
+
if (comparison.fixedCount > 0) {
|
|
140
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
141
|
+
lines.push('ā Fixed Quality Issues ā Endpoint ā Status ā');
|
|
142
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
143
|
+
comparison.fixedIssues.forEach((issue, index) => {
|
|
144
|
+
const issueType = issue.category || issue.label || 'Unknown Issue';
|
|
145
|
+
const method = issue.method || 'MULTIPLE';
|
|
146
|
+
const path = issue.path || '/unknown';
|
|
147
|
+
const endpoint = `${method} ${path}`;
|
|
148
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
149
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
150
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
151
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
152
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā
FIXED ā`);
|
|
153
|
+
});
|
|
154
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
155
|
+
}
|
|
156
|
+
if (comparison.stillExistsIssues.length > 0) {
|
|
157
|
+
lines.push('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
158
|
+
lines.push('ā Still Existing Quality Issues ā Endpoint ā Status ā');
|
|
159
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
160
|
+
comparison.stillExistsIssues.forEach((issue, index) => {
|
|
161
|
+
const issueType = issue.category || issue.label || 'Unknown Issue';
|
|
162
|
+
const method = issue.method || 'MULTIPLE';
|
|
163
|
+
const path = issue.path || '/unknown';
|
|
164
|
+
const endpoint = `${method} ${path}`;
|
|
165
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
166
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
167
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
168
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
169
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā STILL EXISTS ā`);
|
|
170
|
+
});
|
|
171
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
172
|
+
}
|
|
173
|
+
return lines.join('\n');
|
|
174
|
+
};
|
|
175
|
+
const comparisonTable = createComparisonTable();
|
|
176
|
+
// Clear fixed quality issues after comparison is done
|
|
177
|
+
console.error('šļø Clearing fixed quality issues after comparison...');
|
|
178
|
+
authManager.clearFixedQualityIssues();
|
|
179
|
+
return {
|
|
180
|
+
content: [
|
|
181
|
+
{
|
|
182
|
+
type: "text",
|
|
183
|
+
text: `š **Quality Fixes Check Results**\n\nšÆ **APP**: ${selectedAppId}\nš **Quality App ID**: ${qualityAppId}\nš¢ **Organization**: ${orgId}\n\nš **Issue Comparison Results**:\n\n**Previously Fixed Quality Issues**: ${previousIssues.length}\n**Current Quality Issues**: ${currentIssues.length}\n**Actually Fixed**: ${comparison.fixedCount}\n**Still Existing**: ${comparison.stillExistsIssues.length}\n\n${comparisonTable}\n\nā³ **Processing Wait**: System waited ${waitSeconds} seconds to ensure quality issues were fully processed and updated.\n\nšļø **Fixed Quality Issues Cleared**: All previously fixed quality issues have been cleared from session after comparison.\n\nā
**Status**: Quality fix verification completed.\n\nš” **Next Steps**:\n1. Review the comparison results above\n2. For still existing issues, use \`ai_fix_quality_issue\` to generate new fixes\n3. Run \`run_quality_test\` again to test new fixes\n4. Use \`check_quality_fixes\` to verify the new fixes`,
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
190
|
+
return {
|
|
191
|
+
content: [
|
|
192
|
+
{
|
|
193
|
+
type: "text",
|
|
194
|
+
text: `ā **Error checking quality fixes**\n\nš“ **Error**: ${errorMessage}\n\nš” **Tip**: Make sure you're authenticated, have an organization selected, and have run \`run_quality_test\` first.\n\nš **Try**: Check your inputs and try again.`,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const checkSecurityFixesTool: {
|
|
2
|
+
readonly name: "check_security_fixes";
|
|
3
|
+
readonly description: "š Check which previously fixed security issues were actually resolved (auto-triggered after run_security_test)";
|
|
4
|
+
readonly inputSchema: {
|
|
5
|
+
readonly type: "object";
|
|
6
|
+
readonly properties: {
|
|
7
|
+
readonly wait_seconds: {
|
|
8
|
+
readonly type: "number";
|
|
9
|
+
readonly description: "Wait time before checking issues (default: 15 seconds)";
|
|
10
|
+
readonly default: 15;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
readonly additionalProperties: false;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function handleCheckSecurityFixes(authManager: any, args: any): Promise<any>;
|
|
17
|
+
//# sourceMappingURL=checkSecurityFixes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkSecurityFixes.d.ts","sourceRoot":"","sources":["../../../src/tools/protected/checkSecurityFixes.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;CAczB,CAAC;AAEX,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAoJxF"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { API_ENDPOINTS } from "../../config.js";
|
|
3
|
+
// Function to compare fixed issues with current issues
|
|
4
|
+
function compareAndCountFixedIssues(previousIssues, currentIssues) {
|
|
5
|
+
let fixedCount = 0;
|
|
6
|
+
const fixedIssues = [];
|
|
7
|
+
const stillExistsIssues = [];
|
|
8
|
+
// Loop through each issue we attempted to fix
|
|
9
|
+
for (const previousIssue of previousIssues) {
|
|
10
|
+
// Check if this previous issue still exists in current issues
|
|
11
|
+
const stillExists = currentIssues.some((currentIssue) => currentIssue.method === previousIssue.method &&
|
|
12
|
+
currentIssue.path === previousIssue.path &&
|
|
13
|
+
currentIssue.label === previousIssue.label);
|
|
14
|
+
// If the issue no longer exists in current issues, it was fixed
|
|
15
|
+
if (!stillExists) {
|
|
16
|
+
fixedCount++;
|
|
17
|
+
fixedIssues.push(previousIssue);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
stillExistsIssues.push(previousIssue);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return { fixedCount, fixedIssues, stillExistsIssues };
|
|
24
|
+
}
|
|
25
|
+
// Function to fetch current security issues
|
|
26
|
+
async function fetchSecurityIssues(securityAppId, accessToken, tokenType, orgId) {
|
|
27
|
+
const url = `${API_ENDPOINTS.SECURITY_ISSUES_BY_APP}?app_id=${encodeURIComponent(securityAppId)}&limit=100`;
|
|
28
|
+
const response = await axios.get(url, {
|
|
29
|
+
headers: {
|
|
30
|
+
'Authorization': `${tokenType} ${accessToken}`,
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
'X-Org-ID': orgId
|
|
33
|
+
},
|
|
34
|
+
timeout: 30000
|
|
35
|
+
});
|
|
36
|
+
if (response.status !== 200 || !response.data) {
|
|
37
|
+
throw new Error(`Failed to fetch security issues: ${response.status}`);
|
|
38
|
+
}
|
|
39
|
+
return response.data.data || [];
|
|
40
|
+
}
|
|
41
|
+
export const checkSecurityFixesTool = {
|
|
42
|
+
name: "check_security_fixes",
|
|
43
|
+
description: "š Check which previously fixed security issues were actually resolved (auto-triggered after run_security_test)",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
wait_seconds: {
|
|
48
|
+
type: "number",
|
|
49
|
+
description: "Wait time before checking issues (default: 15 seconds)",
|
|
50
|
+
default: 15
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
export async function handleCheckSecurityFixes(authManager, args) {
|
|
57
|
+
try {
|
|
58
|
+
const waitSeconds = args.wait_seconds || 15;
|
|
59
|
+
const accessToken = authManager.getAccessToken();
|
|
60
|
+
const tokenType = authManager.getTokenType();
|
|
61
|
+
const orgId = authManager.getSelectedOrgId();
|
|
62
|
+
const selectedAppId = authManager.getSelectedApiId();
|
|
63
|
+
const securityAppId = authManager.getSelectedSecurityAppId();
|
|
64
|
+
if (!accessToken) {
|
|
65
|
+
throw new Error('No access token available');
|
|
66
|
+
}
|
|
67
|
+
if (!orgId) {
|
|
68
|
+
throw new Error('No organization selected. Please select an organization first using manage_organizations tool.');
|
|
69
|
+
}
|
|
70
|
+
if (!selectedAppId) {
|
|
71
|
+
return {
|
|
72
|
+
content: [
|
|
73
|
+
{
|
|
74
|
+
type: "text",
|
|
75
|
+
text: `ā **No APP Selected**\n\nšÆ **Required**: You must select an APP first to check security fixes.\n\nš **Steps**:\n1. Run \`list_apps\` to see available APPs\n2. Run \`select_app\` with an APP ID\n3. Run \`show_security_issues\` to get the security app ID\n4. Then run this tool again`,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (!securityAppId) {
|
|
81
|
+
return {
|
|
82
|
+
content: [
|
|
83
|
+
{
|
|
84
|
+
type: "text",
|
|
85
|
+
text: `ā **No Security App ID Available**\n\nšÆ **Required**: You must run \`show_security_issues\` first to get the security app ID.\n\nš **Steps**:\n1. Make sure you have an APP selected\n2. Run \`show_security_issues\` to fetch and store the security app ID\n3. Then run this tool again`,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Get current fixed issues from session
|
|
91
|
+
const fixedIssues = authManager.getFixedIssues();
|
|
92
|
+
const previousIssues = fixedIssues.map((fi) => fi.issue);
|
|
93
|
+
if (previousIssues.length === 0) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: "text",
|
|
98
|
+
text: `ā¹ļø **No Fixed Issues to Check**\n\nšÆ **Status**: No previously fixed issues found in session.\n\nš” **Tip**: Use \`ai_fix_security_issue\` to fix some issues first, then run \`run_security_test\`, and then this tool.`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
console.error(`š Found ${previousIssues.length} previously fixed issues to check`);
|
|
104
|
+
// Wait for specified time for system to process
|
|
105
|
+
console.error(`ā³ Waiting ${waitSeconds} seconds for system to process security issues...`);
|
|
106
|
+
await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
|
|
107
|
+
console.error('ā
Wait completed, fetching updated security issues...');
|
|
108
|
+
// Fetch current security issues
|
|
109
|
+
console.error('š Fetching current security issues...');
|
|
110
|
+
const currentIssues = await fetchSecurityIssues(securityAppId, accessToken, tokenType, orgId);
|
|
111
|
+
console.error(`š Found ${currentIssues.length} current security issues`);
|
|
112
|
+
// Compare fixed issues with current issues
|
|
113
|
+
const comparison = compareAndCountFixedIssues(previousIssues, currentIssues);
|
|
114
|
+
// Create comparison table
|
|
115
|
+
const createComparisonTable = () => {
|
|
116
|
+
const lines = [];
|
|
117
|
+
if (comparison.fixedCount > 0) {
|
|
118
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
119
|
+
lines.push('ā Fixed Issues ā Endpoint ā Status ā');
|
|
120
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
121
|
+
comparison.fixedIssues.forEach((issue, index) => {
|
|
122
|
+
const issueType = issue.label || 'Unknown Issue';
|
|
123
|
+
const method = issue.method || 'MULTIPLE';
|
|
124
|
+
const path = issue.path || '/unknown';
|
|
125
|
+
const endpoint = `${method} ${path}`;
|
|
126
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
127
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
128
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
129
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
130
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā
FIXED ā`);
|
|
131
|
+
});
|
|
132
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
133
|
+
}
|
|
134
|
+
if (comparison.stillExistsIssues.length > 0) {
|
|
135
|
+
lines.push('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¬āāāāāāāāāāā');
|
|
136
|
+
lines.push('ā Still Existing Issues ā Endpoint ā Status ā');
|
|
137
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāā¤');
|
|
138
|
+
comparison.stillExistsIssues.forEach((issue, index) => {
|
|
139
|
+
const issueType = issue.label || 'Unknown Issue';
|
|
140
|
+
const method = issue.method || 'MULTIPLE';
|
|
141
|
+
const path = issue.path || '/unknown';
|
|
142
|
+
const endpoint = `${method} ${path}`;
|
|
143
|
+
const truncatedIssueType = issueType.length > 60 ? issueType.substring(0, 57) + '...' : issueType;
|
|
144
|
+
const truncatedEndpoint = endpoint.length > 60 ? endpoint.substring(0, 57) + '...' : endpoint;
|
|
145
|
+
const paddedIssueType = truncatedIssueType.padEnd(60);
|
|
146
|
+
const paddedEndpoint = truncatedEndpoint.padEnd(60);
|
|
147
|
+
lines.push(`ā ${paddedIssueType} ā ${paddedEndpoint} ā ā STILL EXISTS ā`);
|
|
148
|
+
});
|
|
149
|
+
lines.push('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāā');
|
|
150
|
+
}
|
|
151
|
+
return lines.join('\n');
|
|
152
|
+
};
|
|
153
|
+
const comparisonTable = createComparisonTable();
|
|
154
|
+
// Clear fixed issues after comparison is done
|
|
155
|
+
console.error('šļø Clearing fixed issues after comparison...');
|
|
156
|
+
authManager.clearFixedIssues();
|
|
157
|
+
return {
|
|
158
|
+
content: [
|
|
159
|
+
{
|
|
160
|
+
type: "text",
|
|
161
|
+
text: `š **Security Fixes Check Results**\n\nšÆ **APP**: ${selectedAppId}\nš **Security App ID**: ${securityAppId}\nš¢ **Organization**: ${orgId}\n\nš **Issue Comparison Results**:\n\n**Previously Fixed Issues**: ${previousIssues.length}\n**Current Security Issues**: ${currentIssues.length}\n**Actually Fixed**: ${comparison.fixedCount}\n**Still Existing**: ${comparison.stillExistsIssues.length}\n\n${comparisonTable}\n\nā³ **Processing Wait**: System waited ${waitSeconds} seconds to ensure security issues were fully processed and updated.\n\nšļø **Fixed Issues Cleared**: All previously fixed issues have been cleared from session after comparison.\n\nā
**Status**: Security fix verification completed.\n\nš” **Next Steps**:\n1. Review the comparison results above\n2. For still existing issues, use \`ai_fix_security_issue\` to generate new fixes\n3. Run \`run_security_test\` again to test new fixes\n4. Use \`check_security_fixes\` to verify the new fixes`,
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
168
|
+
return {
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
171
|
+
type: "text",
|
|
172
|
+
text: `ā **Error checking security fixes**\n\nš“ **Error**: ${errorMessage}\n\nš” **Tip**: Make sure you're authenticated, have an organization selected, and have run \`run_security_test\` first.\n\nš **Try**: Check your inputs and try again.`,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|