@sudu-cli/fronted-preview-mcp 1.0.0-beta.3 → 1.0.0-beta.5

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.
Files changed (62) hide show
  1. package/dist/cdp/connectionManager.d.ts +57 -0
  2. package/dist/cdp/connectionManager.js +153 -0
  3. package/dist/cdp/connectionManager.js.map +1 -0
  4. package/dist/cli.js +2 -1
  5. package/dist/cli.js.map +1 -1
  6. package/dist/constants.d.ts +19 -0
  7. package/dist/constants.js +26 -0
  8. package/dist/constants.js.map +1 -0
  9. package/dist/detectors/frameworkDetector.js +17 -13
  10. package/dist/detectors/frameworkDetector.js.map +1 -1
  11. package/dist/handlers/autoFixLoop.d.ts +24 -0
  12. package/dist/handlers/autoFixLoop.js +81 -4
  13. package/dist/handlers/autoFixLoop.js.map +1 -1
  14. package/dist/handlers/checkPageErrors.js +11 -50
  15. package/dist/handlers/checkPageErrors.js.map +1 -1
  16. package/dist/handlers/typescriptDiagnostics.d.ts +9 -0
  17. package/dist/handlers/typescriptDiagnostics.js +4 -25
  18. package/dist/handlers/typescriptDiagnostics.js.map +1 -1
  19. package/dist/index.js +15 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/serverManager.d.ts +22 -4
  22. package/dist/serverManager.js +215 -140
  23. package/dist/serverManager.js.map +1 -1
  24. package/dist/strategies/baseStrategy.d.ts +27 -0
  25. package/dist/strategies/baseStrategy.js +23 -0
  26. package/dist/strategies/baseStrategy.js.map +1 -0
  27. package/dist/strategies/index.d.ts +9 -0
  28. package/dist/strategies/index.js +22 -0
  29. package/dist/strategies/index.js.map +1 -0
  30. package/dist/strategies/missingImport.d.ts +16 -0
  31. package/dist/strategies/missingImport.js +156 -0
  32. package/dist/strategies/missingImport.js.map +1 -0
  33. package/dist/strategies/missingProperty.d.ts +13 -0
  34. package/dist/strategies/missingProperty.js +134 -0
  35. package/dist/strategies/missingProperty.js.map +1 -0
  36. package/dist/strategies/networkError.d.ts +10 -0
  37. package/dist/strategies/networkError.js +56 -0
  38. package/dist/strategies/networkError.js.map +1 -0
  39. package/dist/strategies/nullCheckInsertion.d.ts +14 -0
  40. package/dist/strategies/nullCheckInsertion.js +138 -0
  41. package/dist/strategies/nullCheckInsertion.js.map +1 -0
  42. package/dist/strategies/typeAssignment.d.ts +13 -0
  43. package/dist/strategies/typeAssignment.js +121 -0
  44. package/dist/strategies/typeAssignment.js.map +1 -0
  45. package/dist/strategies/unusedImportRemoval.d.ts +11 -0
  46. package/dist/strategies/unusedImportRemoval.js +138 -0
  47. package/dist/strategies/unusedImportRemoval.js.map +1 -0
  48. package/dist/types.d.ts +9 -0
  49. package/dist/types.js +21 -1
  50. package/dist/types.js.map +1 -1
  51. package/dist/version.d.ts +7 -0
  52. package/dist/version.js +10 -0
  53. package/dist/version.js.map +1 -0
  54. package/package.json +1 -1
  55. package/templates/init/instructions.md +1 -11
  56. package/templates/init/opencode.json +1 -1
  57. package/dist/handlers/pickElement.d.ts +0 -10
  58. package/dist/handlers/pickElement.js +0 -413
  59. package/dist/handlers/pickElement.js.map +0 -1
  60. package/dist/handlers/takeScreenshot.d.ts +0 -17
  61. package/dist/handlers/takeScreenshot.js +0 -83
  62. package/dist/handlers/takeScreenshot.js.map +0 -1
@@ -0,0 +1,138 @@
1
+ import { Block, SyntaxKind } from 'ts-morph';
2
+ import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
3
+ export class NullCheckInsertionStrategy {
4
+ errorType = 'console';
5
+ pattern = /Cannot read propert(?:y|ies) of (?:null|undefined)|Cannot read property '([^']+)' of (?:null|undefined)|is (?:null|undefined) and has no property/i;
6
+ canFix(error) {
7
+ return this.pattern.test(error.message);
8
+ }
9
+ async fix(context, error) {
10
+ const changes = [];
11
+ if (!error.url) {
12
+ return { success: false, message: 'No URL in console error', changes };
13
+ }
14
+ // Extract file path from URL (e.g., http://localhost:3000/src/main.ts -> src/main.ts)
15
+ const filePath = this.extractFilePathFromUrl(error.url);
16
+ if (!filePath) {
17
+ return { success: false, message: 'Could not extract file path from URL', changes };
18
+ }
19
+ const sourceFile = getSourceFile(context, filePath);
20
+ if (!sourceFile) {
21
+ return { success: false, message: `Source file not found: ${filePath}`, changes };
22
+ }
23
+ const originalText = sourceFile.getFullText();
24
+ const targetLine = error.lineNumber || 1;
25
+ try {
26
+ // Find the problematic property access at the error line
27
+ const propertyAccess = this.findPropertyAccessAtLine(sourceFile, targetLine);
28
+ if (!propertyAccess) {
29
+ return { success: false, message: `No property access found at line ${targetLine}`, changes };
30
+ }
31
+ // Strategy 1: Try to add optional chaining (?.) - modern and clean
32
+ const addedOptionalChaining = this.addOptionalChaining(propertyAccess);
33
+ if (!addedOptionalChaining) {
34
+ // Strategy 2: Wrap with null check if statement
35
+ const wrapped = this.wrapWithNullCheck(propertyAccess);
36
+ if (!wrapped) {
37
+ return { success: false, message: 'Could not add null check or optional chaining', changes };
38
+ }
39
+ }
40
+ saveChanges(context);
41
+ const newText = sourceFile.getFullText();
42
+ const diff = this.generateDiff(originalText, newText, filePath);
43
+ changes.push({
44
+ file: getRelativePath(context, filePath),
45
+ description: `Added null/undefined check for property access at line ${targetLine}`,
46
+ diff,
47
+ });
48
+ return {
49
+ success: true,
50
+ message: `Fixed null/undefined property access at line ${targetLine}`,
51
+ changes,
52
+ };
53
+ }
54
+ catch (err) {
55
+ const msg = err instanceof Error ? err.message : String(err);
56
+ return { success: false, message: `Fix failed: ${msg}`, changes };
57
+ }
58
+ }
59
+ extractFilePathFromUrl(url) {
60
+ try {
61
+ const urlObj = new URL(url);
62
+ const pathname = urlObj.pathname;
63
+ // Remove leading slash and common prefixes
64
+ return pathname.replace(/^\//, '').replace(/^src\//, '').replace(/^app\//, '');
65
+ }
66
+ catch {
67
+ return null;
68
+ }
69
+ }
70
+ findPropertyAccessAtLine(sourceFile, line) {
71
+ const propertyAccesses = sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression);
72
+ for (const propAccess of propertyAccesses) {
73
+ const startLine = propAccess.getStartLineNumber();
74
+ const endLine = propAccess.getEndLineNumber();
75
+ if (startLine <= line && endLine >= line) {
76
+ return propAccess;
77
+ }
78
+ }
79
+ return undefined;
80
+ }
81
+ addOptionalChaining(propAccess) {
82
+ try {
83
+ // Check if it already has optional chaining
84
+ const expression = propAccess.getExpression();
85
+ if (expression.getKind() === SyntaxKind.NonNullExpression) {
86
+ return false; // Already has !
87
+ }
88
+ // Add optional chaining by replacing the dot with ?.
89
+ // We need to replace the entire property access expression
90
+ const exprText = propAccess.getExpression().getText();
91
+ const name = propAccess.getName();
92
+ const newText = `${exprText}?.${name}`;
93
+ propAccess.replaceWithText(newText);
94
+ return true;
95
+ }
96
+ catch {
97
+ return false;
98
+ }
99
+ }
100
+ wrapWithNullCheck(propAccess) {
101
+ try {
102
+ const statement = propAccess.getFirstAncestorByKind(SyntaxKind.ExpressionStatement);
103
+ if (!statement)
104
+ return false;
105
+ const parent = statement.getParent();
106
+ if (!parent || !Block.isBlock(parent))
107
+ return false;
108
+ const exprText = statement.getText().trim();
109
+ const checkExpr = propAccess.getExpression().getText();
110
+ // Create if statement: if (obj != null) { obj.prop = ...; }
111
+ const ifStatement = `if (${checkExpr} != null) {\n ${exprText}\n}`;
112
+ statement.replaceWithText(ifStatement);
113
+ return true;
114
+ }
115
+ catch {
116
+ return false;
117
+ }
118
+ }
119
+ generateDiff(oldText, newText, fileName) {
120
+ const oldLines = oldText.split('\n');
121
+ const newLines = newText.split('\n');
122
+ let diff = `--- ${fileName}\n+++ ${fileName}\n`;
123
+ const maxLen = Math.max(oldLines.length, newLines.length);
124
+ for (let i = 0; i < maxLen; i++) {
125
+ const oldLine = oldLines[i];
126
+ const newLine = newLines[i];
127
+ if (oldLine !== newLine) {
128
+ if (oldLine !== undefined)
129
+ diff += `-${oldLine}\n`;
130
+ if (newLine !== undefined)
131
+ diff += `+${newLine}\n`;
132
+ }
133
+ }
134
+ return diff;
135
+ }
136
+ }
137
+ export const nullCheckInsertionStrategy = new NullCheckInsertionStrategy();
138
+ //# sourceMappingURL=nullCheckInsertion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nullCheckInsertion.js","sourceRoot":"","sources":["../../src/strategies/nullCheckInsertion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
2
+ import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
3
+ export declare class TypeAssignmentStrategy implements FixStrategy {
4
+ errorType: "typescript";
5
+ pattern: RegExp;
6
+ canFix(error: DiagnosticInfo): boolean;
7
+ fix(context: FixContext, error: DiagnosticInfo): Promise<FixResult>;
8
+ private findExpressionAtLine;
9
+ private isFixableExpression;
10
+ private addTypeAssertion;
11
+ private generateDiff;
12
+ }
13
+ export declare const typeAssignmentStrategy: TypeAssignmentStrategy;
@@ -0,0 +1,121 @@
1
+ import { SyntaxKind } from 'ts-morph';
2
+ import { getSourceFile, getRelativePath, saveChanges } from './baseStrategy.js';
3
+ export class TypeAssignmentStrategy {
4
+ errorType = 'typescript';
5
+ pattern = /Type '([^']+)' is not assignable to type '([^']+)'/i;
6
+ canFix(error) {
7
+ return this.pattern.test(error.message) && error.severity === 'error';
8
+ }
9
+ async fix(context, error) {
10
+ const changes = [];
11
+ if (!error.file || error.line === undefined) {
12
+ return { success: false, message: 'No file path or line number in error', changes };
13
+ }
14
+ const match = error.message.match(this.pattern);
15
+ if (!match) {
16
+ return { success: false, message: 'Could not parse type assignment error', changes };
17
+ }
18
+ const sourceType = match[1];
19
+ const targetType = match[2];
20
+ const sourceFile = getSourceFile(context, error.file);
21
+ if (!sourceFile) {
22
+ return { success: false, message: `Source file not found: ${error.file}`, changes };
23
+ }
24
+ const originalText = sourceFile.getFullText();
25
+ try {
26
+ // Find the expression at the error location
27
+ const expression = this.findExpressionAtLine(sourceFile, error.line);
28
+ if (!expression) {
29
+ return { success: false, message: `No expression found at line ${error.line}`, changes };
30
+ }
31
+ // Strategy: Add type assertion (as targetType) to the expression
32
+ const fixed = this.addTypeAssertion(expression, targetType);
33
+ if (!fixed) {
34
+ return { success: false, message: 'Could not add type assertion to expression', changes };
35
+ }
36
+ saveChanges(context);
37
+ const newText = sourceFile.getFullText();
38
+ const diff = this.generateDiff(originalText, newText, error.file);
39
+ changes.push({
40
+ file: getRelativePath(context, error.file),
41
+ description: `Added type assertion 'as ${targetType}' to fix assignment`,
42
+ diff,
43
+ });
44
+ return {
45
+ success: true,
46
+ message: `Fixed type assignment: added 'as ${targetType}' assertion`,
47
+ changes,
48
+ };
49
+ }
50
+ catch (err) {
51
+ const msg = err instanceof Error ? err.message : String(err);
52
+ return { success: false, message: `Fix failed: ${msg}`, changes };
53
+ }
54
+ }
55
+ findExpressionAtLine(sourceFile, line) {
56
+ // Get all expressions in the file and find one at the target line
57
+ const expressions = sourceFile.getDescendantsOfKind(SyntaxKind.Identifier);
58
+ for (const expr of expressions) {
59
+ const startLine = expr.getStartLineNumber();
60
+ const endLine = expr.getEndLineNumber();
61
+ if (startLine <= line && endLine >= line) {
62
+ // Prefer variable declarations, call expressions, property access
63
+ if (this.isFixableExpression(expr)) {
64
+ return expr;
65
+ }
66
+ }
67
+ }
68
+ return undefined;
69
+ }
70
+ isFixableExpression(expr) {
71
+ const kind = expr.getKind();
72
+ return (kind === SyntaxKind.VariableDeclaration ||
73
+ kind === SyntaxKind.CallExpression ||
74
+ kind === SyntaxKind.PropertyAccessExpression ||
75
+ kind === SyntaxKind.Identifier ||
76
+ kind === SyntaxKind.AsExpression);
77
+ }
78
+ addTypeAssertion(expr, targetType) {
79
+ // If it's already an AsExpression, update the type
80
+ if (expr.getKind() === SyntaxKind.AsExpression) {
81
+ const asExpr = expr;
82
+ asExpr.setType(targetType);
83
+ return true;
84
+ }
85
+ // For other expressions, wrap with AsExpression
86
+ // We need to replace the expression with an AsExpression
87
+ const parent = expr.getParent();
88
+ if (!parent)
89
+ return false;
90
+ try {
91
+ // Create the new as expression text
92
+ const exprText = expr.getText();
93
+ const newText = `(${exprText} as ${targetType})`;
94
+ // Replace the expression in the parent
95
+ expr.replaceWithText(newText);
96
+ return true;
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ }
102
+ generateDiff(oldText, newText, fileName) {
103
+ const oldLines = oldText.split('\n');
104
+ const newLines = newText.split('\n');
105
+ let diff = `--- ${fileName}\n+++ ${fileName}\n`;
106
+ const maxLen = Math.max(oldLines.length, newLines.length);
107
+ for (let i = 0; i < maxLen; i++) {
108
+ const oldLine = oldLines[i];
109
+ const newLine = newLines[i];
110
+ if (oldLine !== newLine) {
111
+ if (oldLine !== undefined)
112
+ diff += `-${oldLine}\n`;
113
+ if (newLine !== undefined)
114
+ diff += `+${newLine}\n`;
115
+ }
116
+ }
117
+ return diff;
118
+ }
119
+ }
120
+ export const typeAssignmentStrategy = new TypeAssignmentStrategy();
121
+ //# sourceMappingURL=typeAssignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typeAssignment.js","sourceRoot":"","sources":["../../src/strategies/typeAssignment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { FixStrategy, FixContext, FixResult } from './baseStrategy.js';
2
+ import { DiagnosticInfo } from '../handlers/typescriptDiagnostics.js';
3
+ export declare class UnusedImportRemovalStrategy implements FixStrategy {
4
+ errorType: "typescript";
5
+ pattern: RegExp;
6
+ canFix(error: DiagnosticInfo): boolean;
7
+ fix(context: FixContext, error: DiagnosticInfo): Promise<FixResult>;
8
+ private isSymbolUsedInFile;
9
+ private generateDiff;
10
+ }
11
+ export declare const unusedImportRemovalStrategy: UnusedImportRemovalStrategy;
@@ -0,0 +1,138 @@
1
+ import { SyntaxKind } from 'ts-morph';
2
+ import { saveChanges, getSourceFile, getRelativePath } from './baseStrategy.js';
3
+ export class UnusedImportRemovalStrategy {
4
+ errorType = 'typescript';
5
+ pattern = /(?:Unused variable|unused import|is declared but its value is never read|'([^']+)' is defined but never used)/i;
6
+ canFix(error) {
7
+ return this.pattern.test(error.message) && error.severity === 'error';
8
+ }
9
+ async fix(context, error) {
10
+ const changes = [];
11
+ let fixedCount = 0;
12
+ if (!error.file) {
13
+ return { success: false, message: 'No file path in error', changes };
14
+ }
15
+ const sourceFile = getSourceFile(context, error.file);
16
+ if (!sourceFile) {
17
+ return { success: false, message: `Source file not found: ${error.file}`, changes };
18
+ }
19
+ const originalText = sourceFile.getFullText();
20
+ try {
21
+ // Handle unused imports
22
+ const importDecls = sourceFile.getImportDeclarations();
23
+ for (const importDecl of importDecls) {
24
+ const namedImports = importDecl.getNamedImports();
25
+ const unusedSpecifiers = [];
26
+ for (const specifier of namedImports) {
27
+ const symbol = specifier.getSymbol();
28
+ if (symbol && !this.isSymbolUsedInFile(symbol, sourceFile)) {
29
+ unusedSpecifiers.push(specifier);
30
+ }
31
+ }
32
+ if (unusedSpecifiers.length > 0) {
33
+ if (unusedSpecifiers.length === namedImports.length) {
34
+ // All imports unused - remove entire declaration
35
+ const declText = importDecl.getText();
36
+ importDecl.remove();
37
+ changes.push({
38
+ file: getRelativePath(context, error.file),
39
+ description: `Removed unused import: ${declText.trim()}`,
40
+ });
41
+ }
42
+ else {
43
+ // Remove only unused specifiers
44
+ for (const spec of unusedSpecifiers) {
45
+ const specText = spec.getText();
46
+ spec.remove();
47
+ changes.push({
48
+ file: getRelativePath(context, error.file),
49
+ description: `Removed unused import specifier: ${specText}`,
50
+ });
51
+ }
52
+ // Fix formatting if needed
53
+ const syntaxList = importDecl.getFirstChildByKind(SyntaxKind.NamedImports)?.getFirstChildByKind(SyntaxKind.SyntaxList);
54
+ if (syntaxList) {
55
+ syntaxList.forEach?.(() => { });
56
+ }
57
+ }
58
+ fixedCount += unusedSpecifiers.length;
59
+ }
60
+ }
61
+ // Handle unused variables (const/let/var declarations)
62
+ const variableDecls = sourceFile.getVariableDeclarations();
63
+ for (const varDecl of variableDecls) {
64
+ const symbol = varDecl.getSymbol();
65
+ if (symbol && !this.isSymbolUsedInFile(symbol, sourceFile)) {
66
+ // Check if it's a simple unused variable (not part of destructuring used elsewhere)
67
+ const parent = varDecl.getParent();
68
+ if (parent && parent.getKind() === SyntaxKind.VariableDeclarationList) {
69
+ const declarations = parent.getDeclarations?.() || [];
70
+ if (declarations.length === 1) {
71
+ // Single declaration - remove entire statement
72
+ const statement = parent.getParent();
73
+ if (statement) {
74
+ const stmtText = statement.getText();
75
+ statement.remove();
76
+ changes.push({
77
+ file: getRelativePath(context, error.file),
78
+ description: `Removed unused variable declaration: ${stmtText.trim()}`,
79
+ });
80
+ fixedCount++;
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ if (fixedCount > 0) {
87
+ saveChanges(context);
88
+ const newText = sourceFile.getFullText();
89
+ const diff = this.generateDiff(originalText, newText, error.file);
90
+ if (changes.length > 0) {
91
+ changes[changes.length - 1].diff = diff;
92
+ }
93
+ return {
94
+ success: true,
95
+ message: `Removed ${fixedCount} unused import(s)/variable(s)`,
96
+ changes,
97
+ };
98
+ }
99
+ return { success: false, message: 'No unused imports/variables found to remove', changes };
100
+ }
101
+ catch (err) {
102
+ const msg = err instanceof Error ? err.message : String(err);
103
+ return { success: false, message: `Fix failed: ${msg}`, changes };
104
+ }
105
+ }
106
+ isSymbolUsedInFile(symbol, sourceFile) {
107
+ try {
108
+ const references = symbol.getReferences();
109
+ return references.some((ref) => {
110
+ const node = ref.getNode();
111
+ return node && node.getSourceFile() === sourceFile && node !== symbol.getDeclarations()[0];
112
+ });
113
+ }
114
+ catch {
115
+ return false;
116
+ }
117
+ }
118
+ generateDiff(oldText, newText, fileName) {
119
+ const oldLines = oldText.split('\n');
120
+ const newLines = newText.split('\n');
121
+ let diff = `--- ${fileName}\n+++ ${fileName}\n`;
122
+ // Simple line-by-line diff
123
+ const maxLen = Math.max(oldLines.length, newLines.length);
124
+ for (let i = 0; i < maxLen; i++) {
125
+ const oldLine = oldLines[i];
126
+ const newLine = newLines[i];
127
+ if (oldLine !== newLine) {
128
+ if (oldLine !== undefined)
129
+ diff += `-${oldLine}\n`;
130
+ if (newLine !== undefined)
131
+ diff += `+${newLine}\n`;
132
+ }
133
+ }
134
+ return diff;
135
+ }
136
+ }
137
+ export const unusedImportRemovalStrategy = new UnusedImportRemovalStrategy();
138
+ //# sourceMappingURL=unusedImportRemoval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unusedImportRemoval.js","sourceRoot":"","sources":["../../src/strategies/unusedImportRemoval.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -28,3 +28,12 @@ export interface ToolContext {
28
28
  port?: number;
29
29
  cdpPort?: number;
30
30
  }
31
+ export type MCPErrorCode = 'FRAMEWORK_NOT_DETECTED' | 'DEV_SERVER_START_FAILED' | 'CDP_CONNECTION_FAILED' | 'PAGE_NAVIGATION_FAILED' | 'TYPE_CHECK_FAILED' | 'CONFIG_NOT_FOUND' | 'INVALID_PROJECT_DIR' | 'PORT_IN_USE' | 'TIMEOUT' | 'UNKNOWN_ERROR';
32
+ export interface MCPError {
33
+ code: MCPErrorCode;
34
+ message: string;
35
+ details?: unknown;
36
+ suggestion?: string;
37
+ }
38
+ export declare function createMCPError(code: MCPErrorCode, message: string, details?: unknown, suggestion?: string): MCPToolResponse;
39
+ export declare function createMCPSuccess(data: unknown): MCPToolResponse;
package/dist/types.js CHANGED
@@ -1,2 +1,22 @@
1
- export {};
1
+ export function createMCPError(code, message, details, suggestion) {
2
+ return {
3
+ content: [
4
+ {
5
+ type: 'text',
6
+ text: JSON.stringify({ error: { code, message, details, suggestion } }, null, 2),
7
+ },
8
+ ],
9
+ isError: true,
10
+ };
11
+ }
12
+ export function createMCPSuccess(data) {
13
+ return {
14
+ content: [
15
+ {
16
+ type: 'text',
17
+ text: JSON.stringify(data, null, 2),
18
+ },
19
+ ],
20
+ };
21
+ }
2
22
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAsDA,MAAM,UAAU,cAAc,CAC5B,IAAkB,EAClB,OAAe,EACf,OAAiB,EACjB,UAAmB;IAEnB,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;aACjF;SACF;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAa;IAC5C,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const VERSION = "1.0.0-beta.4";
2
+ export declare const VERSION_MAJOR = 1;
3
+ export declare const VERSION_MINOR = 0;
4
+ export declare const VERSION_PATCH = 0;
5
+ export declare const VERSION_PRERELEASE = "beta.4";
6
+ export declare const VERSION_STRING = "1.0.0-beta.4";
7
+ export declare const VERSION_SHORT = "1.0.0";
@@ -0,0 +1,10 @@
1
+ // Version management - single source of truth
2
+ export const VERSION = '1.0.0-beta.4';
3
+ export const VERSION_MAJOR = 1;
4
+ export const VERSION_MINOR = 0;
5
+ export const VERSION_PATCH = 0;
6
+ export const VERSION_PRERELEASE = 'beta.4';
7
+ // Formatted version strings
8
+ export const VERSION_STRING = VERSION;
9
+ export const VERSION_SHORT = `${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}`;
10
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,4BAA4B;AAC5B,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AACtC,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,aAAa,IAAI,aAAa,IAAI,aAAa,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudu-cli/fronted-preview-mcp",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "MCP server for frontend project detection, dev server management, and preview workflow. Pairs with chrome-devtools-mcp for automated frontend checking.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -22,14 +22,6 @@
22
22
  3. **`auto_fix_loop`** — 自动检测和修复错误(可选)
23
23
  4. **汇总结果** — 告诉用户:错误类型、数量、修复建议
24
24
 
25
- ## 元素分析与截图工作流
26
-
27
- 当用户想"分析元素"、"截图"、"查看样式"时,按照以下步骤:
28
-
29
- 1. **`pick_element`** — 拾取页面元素获取详细信息
30
- 2. **`take_screenshot`** — 截图页面或特定元素
31
- 3. **汇总结果** — 告诉用户:元素信息、样式、截图结果
32
-
33
25
  ## 工具快速参考
34
26
 
35
27
  | 工具 | 用途 | 优先使用场景 |
@@ -43,8 +35,6 @@
43
35
  | `check_page_errors` | 检测页面 console 错误和网络失败 | 检查页面是否有 JavaScript 错误 |
44
36
  | `get_typescript_diagnostics` | 检测 TypeScript 类型错误 | 检查代码类型错误和警告 |
45
37
  | `auto_fix_loop` | 自动检测和修复错误 | 自动修复所有检测到的错误 |
46
- | **元素分析工具** | | |
47
- | `pick_element` | 拾取页面元素获取详细信息 | 分析特定元素的信息和样式 |
48
38
  | **chrome-devtools** | | |
49
39
  | `chrome-devtools `navigate_page` | 打开 URL | 拿到 URL 后立即使用 |
50
40
  | `chrome-devtools `list_console_messages` | 检查 console 错误 | 页面加载完成后 |
@@ -57,4 +47,4 @@
57
47
  - `quick_preview` 已包含 framework 检测,不要再重复调 `get_project_info`
58
48
  - dev server 可以保持运行,不需要每次用完就关闭
59
49
  - 使用 `auto_fix_loop` 时需要 Chrome 运行在调试模式(--remote-debugging-port=9222)
60
- - `pick_element` 支持直接传入 CSS 选择器,或进入交互式拾取模式
50
+ - 元素拾取和截图功能已委托给 `chrome-devtools-mcp`
@@ -3,7 +3,7 @@
3
3
  "mcp": {
4
4
  "frontend-preview": {
5
5
  "type": "local",
6
- "command": ["npx", "-y", "@sudu-cli/fronted-preview-mcp"]
6
+ "command": ["npx", "-y", "@sudu-cli/fronted-preview-mcp@latest"]
7
7
  },
8
8
  "chrome-devtools": {
9
9
  "type": "local",
@@ -1,10 +0,0 @@
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 };