@sudu-cli/fronted-preview-mcp 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/handlers/autoFixLoop.d.ts +21 -0
- package/dist/handlers/autoFixLoop.js +135 -0
- package/dist/handlers/autoFixLoop.js.map +1 -0
- package/dist/handlers/checkPageErrors.d.ts +9 -0
- package/dist/handlers/checkPageErrors.js +168 -0
- package/dist/handlers/checkPageErrors.js.map +1 -0
- package/dist/handlers/pickElement.d.ts +10 -0
- package/dist/handlers/pickElement.js +413 -0
- package/dist/handlers/pickElement.js.map +1 -0
- package/dist/handlers/takeScreenshot.d.ts +17 -0
- package/dist/handlers/takeScreenshot.js +83 -0
- package/dist/handlers/takeScreenshot.js.map +1 -0
- package/dist/handlers/typescriptDiagnostics.d.ts +9 -0
- package/dist/handlers/typescriptDiagnostics.js +151 -0
- package/dist/handlers/typescriptDiagnostics.js.map +1 -0
- package/dist/index.js +276 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/package.json +7 -4
- package/templates/init/agent.md +18 -2
- package/templates/init/instructions.md +31 -4
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Client } from 'chrome-remote-interface';
|
|
2
|
+
import { ToolContext } from '../types.js';
|
|
3
|
+
export interface AutoFixOptions {
|
|
4
|
+
maxIterations?: number;
|
|
5
|
+
timeoutPerIteration?: number;
|
|
6
|
+
stopOnSuccess?: boolean;
|
|
7
|
+
screenshotOnError?: boolean;
|
|
8
|
+
screenshotOnSuccess?: boolean;
|
|
9
|
+
targetErrors?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface AutoFixResult {
|
|
12
|
+
success: boolean;
|
|
13
|
+
iterations: number;
|
|
14
|
+
errorsFixed: number;
|
|
15
|
+
errorsRemaining: number;
|
|
16
|
+
screenshots: string[];
|
|
17
|
+
messages: string[];
|
|
18
|
+
errors: string[];
|
|
19
|
+
}
|
|
20
|
+
export declare function autoFixLoop(client: Client, context: ToolContext, options?: AutoFixOptions): Promise<AutoFixResult>;
|
|
21
|
+
export declare function handleAutoFixLoop(context: ToolContext, options?: AutoFixOptions): Promise<AutoFixResult>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { handleCheckPageErrors } from './checkPageErrors.js';
|
|
2
|
+
import { handleGetTypeScriptDiagnostics } from './typescriptDiagnostics.js';
|
|
3
|
+
import { handleTakeScreenshot } from './takeScreenshot.js';
|
|
4
|
+
export async function autoFixLoop(client, context, options = {}) {
|
|
5
|
+
const { maxIterations = 3, timeoutPerIteration = 30000, stopOnSuccess = true, screenshotOnError = true, screenshotOnSuccess = false, targetErrors = [] } = options;
|
|
6
|
+
const result = {
|
|
7
|
+
success: false,
|
|
8
|
+
iterations: 0,
|
|
9
|
+
errorsFixed: 0,
|
|
10
|
+
errorsRemaining: 0,
|
|
11
|
+
screenshots: [],
|
|
12
|
+
messages: [],
|
|
13
|
+
errors: []
|
|
14
|
+
};
|
|
15
|
+
// Check initial state
|
|
16
|
+
const initialConsoleErrors = await handleCheckPageErrors(context);
|
|
17
|
+
const initialTsDiagnostics = await handleGetTypeScriptDiagnostics(context);
|
|
18
|
+
let currentConsoleErrors = [...initialConsoleErrors.errors];
|
|
19
|
+
let currentTsDiagnostics = [...initialTsDiagnostics.diagnostics];
|
|
20
|
+
// Filter errors if targetErrors is specified
|
|
21
|
+
if (targetErrors.length > 0) {
|
|
22
|
+
currentConsoleErrors = currentConsoleErrors.filter(error => targetErrors.some(target => error.message.includes(target)));
|
|
23
|
+
currentTsDiagnostics = currentTsDiagnostics.filter(diagnostic => targetErrors.some(target => diagnostic.message.includes(target)));
|
|
24
|
+
}
|
|
25
|
+
const initialErrorCount = currentConsoleErrors.length + currentTsDiagnostics.length;
|
|
26
|
+
result.errorsRemaining = initialErrorCount;
|
|
27
|
+
// Take initial screenshot if requested
|
|
28
|
+
if (screenshotOnError && initialErrorCount > 0) {
|
|
29
|
+
const screenshot = await handleTakeScreenshot(context, { format: 'png' });
|
|
30
|
+
if (screenshot.success && screenshot.dataUrl) {
|
|
31
|
+
result.screenshots.push(`Initial state - ${initialErrorCount} errors: ${screenshot.dataUrl}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
35
|
+
result.iterations = iteration + 1;
|
|
36
|
+
result.messages.push(`=== Iteration ${iteration + 1} ===`);
|
|
37
|
+
try {
|
|
38
|
+
// Wait for any pending operations
|
|
39
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
40
|
+
// Check current state
|
|
41
|
+
const currentErrors = await handleCheckPageErrors(context);
|
|
42
|
+
const currentDiagnostics = await handleGetTypeScriptDiagnostics(context);
|
|
43
|
+
// Update error counts
|
|
44
|
+
currentConsoleErrors = [...currentErrors.errors];
|
|
45
|
+
currentTsDiagnostics = [...currentDiagnostics.diagnostics];
|
|
46
|
+
if (targetErrors.length > 0) {
|
|
47
|
+
currentConsoleErrors = currentConsoleErrors.filter(error => targetErrors.some(target => error.message.includes(target)));
|
|
48
|
+
currentTsDiagnostics = currentTsDiagnostics.filter(diagnostic => targetErrors.some(target => diagnostic.message.includes(target)));
|
|
49
|
+
}
|
|
50
|
+
const currentErrorCount = currentConsoleErrors.length + currentTsDiagnostics.length;
|
|
51
|
+
const errorsFixed = initialErrorCount - currentErrorCount;
|
|
52
|
+
result.errorsFixed = errorsFixed;
|
|
53
|
+
result.errorsRemaining = currentErrorCount;
|
|
54
|
+
// Check if we've succeeded
|
|
55
|
+
if (currentErrorCount === 0 && stopOnSuccess) {
|
|
56
|
+
result.success = true;
|
|
57
|
+
result.messages.push(`✅ All errors fixed after ${iteration + 1} iterations`);
|
|
58
|
+
if (screenshotOnSuccess) {
|
|
59
|
+
const screenshot = await handleTakeScreenshot(context, { format: 'png' });
|
|
60
|
+
if (screenshot.success && screenshot.dataUrl) {
|
|
61
|
+
result.screenshots.push(`Success state - no errors: ${screenshot.dataUrl}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
// Log current state
|
|
67
|
+
result.messages.push(`Current errors: ${currentErrorCount} (fixed: ${errorsFixed})`);
|
|
68
|
+
if (currentConsoleErrors.length > 0) {
|
|
69
|
+
result.messages.push('Console errors:');
|
|
70
|
+
currentConsoleErrors.forEach((error) => {
|
|
71
|
+
result.messages.push(` - ${error.message} (${error.type})`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
if (currentTsDiagnostics.length > 0) {
|
|
75
|
+
result.messages.push('TypeScript diagnostics:');
|
|
76
|
+
currentTsDiagnostics.forEach((diagnostic) => {
|
|
77
|
+
result.messages.push(` - ${diagnostic.message} (${diagnostic.severity})`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Take screenshot if errors still exist
|
|
81
|
+
if (currentErrorCount > 0 && screenshotOnError) {
|
|
82
|
+
const screenshot = await handleTakeScreenshot(context, { format: 'png' });
|
|
83
|
+
if (screenshot.success && screenshot.dataUrl) {
|
|
84
|
+
result.screenshots.push(`Iteration ${iteration + 1} - ${currentErrorCount} errors: ${screenshot.dataUrl}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// If no errors but we're not stopping on success, continue
|
|
88
|
+
if (currentErrorCount === 0) {
|
|
89
|
+
result.messages.push('No errors found, but continuing to next iteration');
|
|
90
|
+
}
|
|
91
|
+
// Wait before next iteration
|
|
92
|
+
await new Promise(resolve => setTimeout(resolve, timeoutPerIteration));
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const errorMessage = `Error in iteration ${iteration + 1}: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
|
96
|
+
result.errors.push(errorMessage);
|
|
97
|
+
result.messages.push(errorMessage);
|
|
98
|
+
// Take error screenshot if requested
|
|
99
|
+
if (screenshotOnError) {
|
|
100
|
+
const screenshot = await handleTakeScreenshot(context, { format: 'png' });
|
|
101
|
+
if (screenshot.success && screenshot.dataUrl) {
|
|
102
|
+
result.screenshots.push(`Error in iteration ${iteration + 1}: ${screenshot.dataUrl}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Final check
|
|
109
|
+
const finalConsoleErrors = await handleCheckPageErrors(context);
|
|
110
|
+
const finalTsDiagnostics = await handleGetTypeScriptDiagnostics(context);
|
|
111
|
+
let finalErrorCount = finalConsoleErrors.errors.length + finalTsDiagnostics.diagnostics.length;
|
|
112
|
+
if (targetErrors.length > 0) {
|
|
113
|
+
finalErrorCount = finalConsoleErrors.errors.filter((error) => targetErrors.some(target => error.message.includes(target))).length + finalTsDiagnostics.diagnostics.filter((diagnostic) => targetErrors.some(target => diagnostic.message.includes(target))).length;
|
|
114
|
+
}
|
|
115
|
+
result.errorsRemaining = finalErrorCount;
|
|
116
|
+
result.success = finalErrorCount === 0;
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
// MCP tool handler
|
|
120
|
+
export async function handleAutoFixLoop(context, options) {
|
|
121
|
+
const { chromeClient } = context;
|
|
122
|
+
if (!chromeClient) {
|
|
123
|
+
return {
|
|
124
|
+
success: false,
|
|
125
|
+
iterations: 0,
|
|
126
|
+
errorsFixed: 0,
|
|
127
|
+
errorsRemaining: 0,
|
|
128
|
+
screenshots: [],
|
|
129
|
+
messages: ['Chrome client not connected. Please connect to Chrome first.'],
|
|
130
|
+
errors: ['Chrome client not connected']
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return await autoFixLoop(chromeClient, context, options);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=autoFixLoop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoFixLoop.js","sourceRoot":"","sources":["../../src/handlers/autoFixLoop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { MCPToolResponse } from '../types.js';
|
|
2
|
+
interface CheckPageErrorsArgs {
|
|
3
|
+
projectDir?: string;
|
|
4
|
+
customPort?: number;
|
|
5
|
+
cdpPort?: number;
|
|
6
|
+
waitForLoadMs?: number;
|
|
7
|
+
}
|
|
8
|
+
declare function handleCheckPageErrors(args: CheckPageErrorsArgs): Promise<MCPToolResponse>;
|
|
9
|
+
export { handleCheckPageErrors };
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { detectFramework } from '../detectors/frameworkDetector.js';
|
|
2
|
+
import { startServer } from '../serverManager.js';
|
|
3
|
+
import CDP from 'chrome-remote-interface';
|
|
4
|
+
async function handleCheckPageErrors(args) {
|
|
5
|
+
const projectDir = args.projectDir || process.cwd();
|
|
6
|
+
const cdpPort = args.cdpPort || 9222;
|
|
7
|
+
const waitForLoadMs = args.waitForLoadMs || 3000;
|
|
8
|
+
let client = null;
|
|
9
|
+
try {
|
|
10
|
+
// Step 1: Detect framework and start/get dev server
|
|
11
|
+
const info = await detectFramework(projectDir);
|
|
12
|
+
if (!info.devScript) {
|
|
13
|
+
return {
|
|
14
|
+
content: [
|
|
15
|
+
{
|
|
16
|
+
type: 'text',
|
|
17
|
+
text: JSON.stringify({
|
|
18
|
+
error: 'No dev script found',
|
|
19
|
+
availableScripts: Object.keys(info.npmScripts),
|
|
20
|
+
projectDir,
|
|
21
|
+
}, null, 2),
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
isError: true,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Step 2: Start dev server (or reuse existing)
|
|
28
|
+
const port = args.customPort || info.port;
|
|
29
|
+
const command = `npm run ${info.devScript}`;
|
|
30
|
+
const status = await startServer(projectDir, command, port);
|
|
31
|
+
const pageUrl = status.url;
|
|
32
|
+
// Step 3: Connect to Chrome via CDP
|
|
33
|
+
const cdpOptions = { port: cdpPort };
|
|
34
|
+
try {
|
|
35
|
+
client = await CDP(cdpOptions);
|
|
36
|
+
}
|
|
37
|
+
catch (cdpErr) {
|
|
38
|
+
return {
|
|
39
|
+
content: [
|
|
40
|
+
{
|
|
41
|
+
type: 'text',
|
|
42
|
+
text: JSON.stringify({
|
|
43
|
+
error: `Failed to connect to Chrome DevTools Protocol on port ${cdpPort}. Ensure Chrome is running with --remote-debugging-port=${cdpPort}`,
|
|
44
|
+
details: cdpErr instanceof Error ? cdpErr.message : String(cdpErr),
|
|
45
|
+
pageUrl,
|
|
46
|
+
suggestion: 'Start Chrome with: chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug',
|
|
47
|
+
}, null, 2),
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
isError: true,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (!client) {
|
|
54
|
+
return {
|
|
55
|
+
content: [
|
|
56
|
+
{
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: JSON.stringify({
|
|
59
|
+
error: 'Failed to create CDP client',
|
|
60
|
+
pageUrl,
|
|
61
|
+
}, null, 2),
|
|
62
|
+
},
|
|
63
|
+
],
|
|
64
|
+
isError: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
// Enable domains
|
|
68
|
+
const { Page, Runtime, Network, Log } = client;
|
|
69
|
+
await Promise.all([
|
|
70
|
+
Page.enable(),
|
|
71
|
+
Runtime.enable(),
|
|
72
|
+
Network.enable(),
|
|
73
|
+
Log.enable(),
|
|
74
|
+
]);
|
|
75
|
+
// Collect console messages
|
|
76
|
+
const consoleMessages = [];
|
|
77
|
+
const networkErrors = [];
|
|
78
|
+
// Listen for console messages (Log.entryAdded)
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
80
|
+
client.on('Log.entryAdded', (params) => {
|
|
81
|
+
const entry = params.entry;
|
|
82
|
+
consoleMessages.push({
|
|
83
|
+
type: entry.level,
|
|
84
|
+
text: entry.text,
|
|
85
|
+
url: entry.url,
|
|
86
|
+
lineNumber: entry.lineNumber,
|
|
87
|
+
stackTrace: entry.stackTrace,
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
// Listen for network errors (Network.responseReceived)
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
+
client.on('Network.responseReceived', (params) => {
|
|
93
|
+
const response = params.response;
|
|
94
|
+
if (response.status >= 400) {
|
|
95
|
+
networkErrors.push({
|
|
96
|
+
url: response.url,
|
|
97
|
+
method: response.requestMethod || 'GET',
|
|
98
|
+
statusCode: response.status,
|
|
99
|
+
errorText: `HTTP ${response.status}`,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
// Listen for network loading failed
|
|
104
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
105
|
+
client.on('Network.loadingFailed', (params) => {
|
|
106
|
+
networkErrors.push({
|
|
107
|
+
url: `request:${params.requestId}`,
|
|
108
|
+
method: 'UNKNOWN',
|
|
109
|
+
errorText: params.errorText,
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
// Step 4: Navigate to the page
|
|
113
|
+
await Page.navigate({ url: pageUrl });
|
|
114
|
+
// Wait for page load
|
|
115
|
+
await new Promise((resolve) => {
|
|
116
|
+
const timeout = setTimeout(resolve, waitForLoadMs);
|
|
117
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
118
|
+
const handler = (params) => {
|
|
119
|
+
clearTimeout(timeout);
|
|
120
|
+
resolve();
|
|
121
|
+
};
|
|
122
|
+
client.on('Page.loadEventFired', handler);
|
|
123
|
+
});
|
|
124
|
+
// Give a bit more time for async console messages
|
|
125
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
126
|
+
// Step 5: Compile report
|
|
127
|
+
const errors = consoleMessages.filter((m) => m.type === 'error');
|
|
128
|
+
const warnings = consoleMessages.filter((m) => m.type === 'warning');
|
|
129
|
+
const report = {
|
|
130
|
+
pageUrl,
|
|
131
|
+
framework: info.framework,
|
|
132
|
+
port: status.port,
|
|
133
|
+
consoleMessages,
|
|
134
|
+
networkErrors,
|
|
135
|
+
hasErrors: errors.length > 0 || networkErrors.length > 0,
|
|
136
|
+
errorCount: errors.length + networkErrors.length,
|
|
137
|
+
warningCount: warnings.length,
|
|
138
|
+
timestamp: new Date().toISOString(),
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
content: [
|
|
142
|
+
{
|
|
143
|
+
type: 'text',
|
|
144
|
+
text: JSON.stringify(report, null, 2),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
151
|
+
return {
|
|
152
|
+
content: [{ type: 'text', text: JSON.stringify({ error: errorMessage }, null, 2) }],
|
|
153
|
+
isError: true,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
if (client) {
|
|
158
|
+
try {
|
|
159
|
+
await client.close();
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Ignore cleanup errors
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
export { handleCheckPageErrors };
|
|
168
|
+
//# sourceMappingURL=checkPageErrors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkPageErrors.js","sourceRoot":"","sources":["../../src/handlers/checkPageErrors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MCPToolResponse } from '../types.js';
|
|
2
|
+
interface PickElementArgs {
|
|
3
|
+
projectDir?: string;
|
|
4
|
+
customPort?: number;
|
|
5
|
+
cdpPort?: number;
|
|
6
|
+
selector?: string;
|
|
7
|
+
waitForLoadMs?: number;
|
|
8
|
+
}
|
|
9
|
+
declare function handlePickElement(args: PickElementArgs): Promise<MCPToolResponse>;
|
|
10
|
+
export { handlePickElement };
|