@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.3
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 +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,247 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* PrettierFormatter - Code formatting using Prettier
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Format code according to consistent style rules
|
|
6
|
-
* - Support multiple languages (JS, TS, CSS, HTML, JSON, etc.)
|
|
7
|
-
* - Detect and use project's Prettier configuration
|
|
8
|
-
* - Provide before/after comparison
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import prettier from 'prettier';
|
|
12
|
-
import path from 'path';
|
|
13
|
-
import fs from 'fs/promises';
|
|
14
|
-
|
|
15
|
-
class PrettierFormatter {
|
|
16
|
-
constructor(logger = null) {
|
|
17
|
-
this.logger = logger;
|
|
18
|
-
this.configCache = new Map();
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Format code with Prettier
|
|
23
|
-
* @param {string} filePath - Path to file
|
|
24
|
-
* @param {string} content - File content
|
|
25
|
-
* @param {Object} options - Format options
|
|
26
|
-
* @returns {Promise<Object>} Formatted content and changes
|
|
27
|
-
*/
|
|
28
|
-
async format(filePath, content, options = {}) {
|
|
29
|
-
try {
|
|
30
|
-
// Get Prettier configuration
|
|
31
|
-
const config = await this.getPrettierConfig(filePath, options.workingDir);
|
|
32
|
-
|
|
33
|
-
// Determine parser from file extension
|
|
34
|
-
const parser = this.getParser(filePath);
|
|
35
|
-
|
|
36
|
-
// Format the code
|
|
37
|
-
const formatted = await prettier.format(content, {
|
|
38
|
-
...config,
|
|
39
|
-
filepath: filePath,
|
|
40
|
-
parser
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Check if formatting made changes
|
|
44
|
-
const hasChanges = formatted !== content;
|
|
45
|
-
|
|
46
|
-
return {
|
|
47
|
-
formatted: hasChanges,
|
|
48
|
-
content: formatted,
|
|
49
|
-
original: content,
|
|
50
|
-
changes: hasChanges ? this.describeChanges(content, formatted) : [],
|
|
51
|
-
linesChanged: hasChanges ? this.countChangedLines(content, formatted) : 0
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
} catch (error) {
|
|
55
|
-
this.logger?.error('Prettier formatting failed', {
|
|
56
|
-
file: filePath,
|
|
57
|
-
error: error.message
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
throw new Error(`Prettier formatting failed: ${error.message}`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Check if file needs formatting
|
|
66
|
-
* @param {string} filePath - Path to file
|
|
67
|
-
* @param {string} content - File content
|
|
68
|
-
* @param {Object} options - Check options
|
|
69
|
-
* @returns {Promise<boolean>} True if file needs formatting
|
|
70
|
-
*/
|
|
71
|
-
async check(filePath, content, options = {}) {
|
|
72
|
-
try {
|
|
73
|
-
const config = await this.getPrettierConfig(filePath, options.workingDir);
|
|
74
|
-
const parser = this.getParser(filePath);
|
|
75
|
-
|
|
76
|
-
const formatted = await prettier.format(content, {
|
|
77
|
-
...config,
|
|
78
|
-
filepath: filePath,
|
|
79
|
-
parser
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
return formatted !== content;
|
|
83
|
-
|
|
84
|
-
} catch (error) {
|
|
85
|
-
this.logger?.warn('Prettier check failed', {
|
|
86
|
-
file: filePath,
|
|
87
|
-
error: error.message
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Get Prettier configuration
|
|
96
|
-
* @private
|
|
97
|
-
*/
|
|
98
|
-
async getPrettierConfig(filePath, workingDir) {
|
|
99
|
-
// Check cache
|
|
100
|
-
const cacheKey = workingDir || path.dirname(filePath);
|
|
101
|
-
if (this.configCache.has(cacheKey)) {
|
|
102
|
-
return this.configCache.get(cacheKey);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
let config = {};
|
|
106
|
-
|
|
107
|
-
// Try to load project's Prettier config
|
|
108
|
-
if (workingDir) {
|
|
109
|
-
try {
|
|
110
|
-
const projectConfig = await prettier.resolveConfig(filePath, {
|
|
111
|
-
config: workingDir
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (projectConfig) {
|
|
115
|
-
this.logger?.debug('Found Prettier config', { workingDir });
|
|
116
|
-
config = projectConfig;
|
|
117
|
-
}
|
|
118
|
-
} catch (error) {
|
|
119
|
-
this.logger?.debug('No Prettier config found, using defaults');
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Default configuration
|
|
124
|
-
const defaultConfig = {
|
|
125
|
-
semi: true,
|
|
126
|
-
singleQuote: true,
|
|
127
|
-
tabWidth: 2,
|
|
128
|
-
trailingComma: 'es5',
|
|
129
|
-
printWidth: 100,
|
|
130
|
-
arrowParens: 'avoid',
|
|
131
|
-
endOfLine: 'lf',
|
|
132
|
-
...config
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
// Cache the configuration
|
|
136
|
-
this.configCache.set(cacheKey, defaultConfig);
|
|
137
|
-
|
|
138
|
-
return defaultConfig;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Get parser for file type
|
|
143
|
-
* @private
|
|
144
|
-
*/
|
|
145
|
-
getParser(filePath) {
|
|
146
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
147
|
-
|
|
148
|
-
const parserMap = {
|
|
149
|
-
'.js': 'babel',
|
|
150
|
-
'.jsx': 'babel',
|
|
151
|
-
'.mjs': 'babel',
|
|
152
|
-
'.cjs': 'babel',
|
|
153
|
-
'.ts': 'typescript',
|
|
154
|
-
'.tsx': 'typescript',
|
|
155
|
-
'.json': 'json',
|
|
156
|
-
'.json5': 'json5',
|
|
157
|
-
'.css': 'css',
|
|
158
|
-
'.scss': 'scss',
|
|
159
|
-
'.less': 'less',
|
|
160
|
-
'.html': 'html',
|
|
161
|
-
'.vue': 'vue',
|
|
162
|
-
'.md': 'markdown',
|
|
163
|
-
'.yaml': 'yaml',
|
|
164
|
-
'.yml': 'yaml'
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
return parserMap[ext] || 'babel';
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Describe changes made by formatting
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
describeChanges(original, formatted) {
|
|
175
|
-
const changes = [];
|
|
176
|
-
const originalLines = original.split('\n');
|
|
177
|
-
const formattedLines = formatted.split('\n');
|
|
178
|
-
|
|
179
|
-
const maxLines = Math.max(originalLines.length, formattedLines.length);
|
|
180
|
-
|
|
181
|
-
for (let i = 0; i < maxLines; i++) {
|
|
182
|
-
const origLine = originalLines[i];
|
|
183
|
-
const formattedLine = formattedLines[i];
|
|
184
|
-
|
|
185
|
-
if (origLine !== formattedLine) {
|
|
186
|
-
changes.push({
|
|
187
|
-
line: i + 1,
|
|
188
|
-
type: origLine !== undefined && formattedLine !== undefined
|
|
189
|
-
? 'modified'
|
|
190
|
-
: (origLine !== undefined ? 'removed' : 'added'),
|
|
191
|
-
original: origLine || '',
|
|
192
|
-
formatted: formattedLine || ''
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return changes;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Count changed lines
|
|
202
|
-
* @private
|
|
203
|
-
*/
|
|
204
|
-
countChangedLines(original, formatted) {
|
|
205
|
-
const originalLines = original.split('\n');
|
|
206
|
-
const formattedLines = formatted.split('\n');
|
|
207
|
-
let changedCount = 0;
|
|
208
|
-
|
|
209
|
-
const maxLines = Math.max(originalLines.length, formattedLines.length);
|
|
210
|
-
|
|
211
|
-
for (let i = 0; i < maxLines; i++) {
|
|
212
|
-
if (originalLines[i] !== formattedLines[i]) {
|
|
213
|
-
changedCount++;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
return changedCount;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Get supported file extensions
|
|
222
|
-
* @returns {Array<string>} Array of supported extensions
|
|
223
|
-
*/
|
|
224
|
-
getSupportedExtensions() {
|
|
225
|
-
return [
|
|
226
|
-
'.js', '.jsx', '.mjs', '.cjs',
|
|
227
|
-
'.ts', '.tsx',
|
|
228
|
-
'.json', '.json5',
|
|
229
|
-
'.css', '.scss', '.less',
|
|
230
|
-
'.html', '.vue',
|
|
231
|
-
'.md',
|
|
232
|
-
'.yaml', '.yml'
|
|
233
|
-
];
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Check if file type is supported
|
|
238
|
-
* @param {string} filePath - Path to file
|
|
239
|
-
* @returns {boolean} True if supported
|
|
240
|
-
*/
|
|
241
|
-
isSupported(filePath) {
|
|
242
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
243
|
-
return this.getSupportedExtensions().includes(ext);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export default PrettierFormatter;
|
|
1
|
+
const a0_0x50cd34=a0_0x27ce;function a0_0x198a(){const _0x57c6eb=['Dg9mB3DLCKnHC2u','BgvUz3rO','lMPZB24','lMPZB241','DhLWzxnJCMLWDa','ntvdDM9SwMK','nJi0mtCXv0DfC0Lg','mJa1nJmYmgTytuzetq','mJu5otq0wxLLqKTW','mte3nta4otzyyuLou0C','ywrKzwq','rM91BMqGuhjLDhrPzxiGy29UzMLN','lNLHBwW','AhrTBa','z2v0uhjLDhrPzxjdB25MAwC','z2v0u3vWCg9YDgvKrxH0zw5ZAw9UCW','BwvZC2fNzq','Bwf4','zgvZy3jPyMvdAgfUz2vZ','y291BNrdAgfUz2vKtgLUzxm','lM1QCW','D29YA2LUz0rPCG','lMPZ','C3bSAxq','yMfIzwW','CMvTB3zLza','lNrZEa','nZmWnZzZuMX0zLu','y29UzMLNq2fJAgu','y2HLy2S','ANnVBG','D2fYBG','zM9YBwf0','zgvIDwC','C2nZCW','mtG5mZyWAeXWBNj6','z2v0','y3nZ','zxjYB3i','mZq2nJqWq2nvuuDr','Bg9Nz2vY'];a0_0x198a=function(){return _0x57c6eb;};return a0_0x198a();}function a0_0x27ce(_0x295608,_0x4b4c20){_0x295608=_0x295608-0x135;const _0x198ab2=a0_0x198a();let _0x27ce59=_0x198ab2[_0x295608];if(a0_0x27ce['QPQlvU']===undefined){var _0xda1fbd=function(_0x2edf93){const _0xdf7acf='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x48dcdd='',_0x5a014d='';for(let _0x25c1d6=0x0,_0x3435da,_0x649507,_0x8f4946=0x0;_0x649507=_0x2edf93['charAt'](_0x8f4946++);~_0x649507&&(_0x3435da=_0x25c1d6%0x4?_0x3435da*0x40+_0x649507:_0x649507,_0x25c1d6++%0x4)?_0x48dcdd+=String['fromCharCode'](0xff&_0x3435da>>(-0x2*_0x25c1d6&0x6)):0x0){_0x649507=_0xdf7acf['indexOf'](_0x649507);}for(let _0x2681b8=0x0,_0x5c0e0a=_0x48dcdd['length'];_0x2681b8<_0x5c0e0a;_0x2681b8++){_0x5a014d+='%'+('00'+_0x48dcdd['charCodeAt'](_0x2681b8)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x5a014d);};a0_0x27ce['XBauih']=_0xda1fbd,a0_0x27ce['TGJBWJ']={},a0_0x27ce['QPQlvU']=!![];}const _0x3c341c=_0x198ab2[0x0],_0x40b3dc=_0x295608+_0x3c341c,_0x4cb882=a0_0x27ce['TGJBWJ'][_0x40b3dc];return!_0x4cb882?(_0x27ce59=a0_0x27ce['XBauih'](_0x27ce59),a0_0x27ce['TGJBWJ'][_0x40b3dc]=_0x27ce59):_0x27ce59=_0x4cb882,_0x27ce59;}(function(_0x41c6aa,_0x5524d8){const _0x465929=a0_0x27ce,_0x3b8c60=_0x41c6aa();while(!![]){try{const _0x2d0271=-parseInt(_0x465929(0x148))/0x1+-parseInt(_0x465929(0x152))/0x2+-parseInt(_0x465929(0x150))/0x3+parseInt(_0x465929(0x13c))/0x4*(-parseInt(_0x465929(0x14f))/0x5)+-parseInt(_0x465929(0x144))/0x6+-parseInt(_0x465929(0x151))/0x7+parseInt(_0x465929(0x153))/0x8;if(_0x2d0271===_0x5524d8)break;else _0x3b8c60['push'](_0x3b8c60['shift']());}catch(_0x21a1f9){_0x3b8c60['push'](_0x3b8c60['shift']());}}}(a0_0x198a,0x3ef7a));import a0_0x48dcdd from'prettier';import a0_0x5a014d from'path';import a0_0x25c1d6 from'fs/promises';class PrettierFormatter{constructor(_0x3435da=null){const _0x37d4a6=a0_0x27ce;this['logger']=_0x3435da,this[_0x37d4a6(0x13d)]=new Map();}async[a0_0x50cd34(0x141)](_0x649507,_0x8f4946,_0x2681b8={}){const _0x36ca43=a0_0x50cd34;try{const _0x5c0e0a=await this[_0x36ca43(0x158)](_0x649507,_0x2681b8[_0x36ca43(0x136)]),_0x194674=this['getParser'](_0x649507),_0x414ea4=await a0_0x48dcdd[_0x36ca43(0x141)](_0x8f4946,{..._0x5c0e0a,'filepath':_0x649507,'parser':_0x194674}),_0xc70a4c=_0x414ea4!==_0x8f4946;return{'formatted':_0xc70a4c,'content':_0x414ea4,'original':_0x8f4946,'changes':_0xc70a4c?this[_0x36ca43(0x15c)](_0x8f4946,_0x414ea4):[],'linesChanged':_0xc70a4c?this[_0x36ca43(0x15d)](_0x8f4946,_0x414ea4):0x0};}catch(_0x39f6bd){this[_0x36ca43(0x149)]?.[_0x36ca43(0x147)]('Prettier\x20formatting\x20failed',{'file':_0x649507,'error':_0x39f6bd['message']});throw new Error('Prettier\x20formatting\x20failed:\x20'+_0x39f6bd[_0x36ca43(0x15a)]);}}async[a0_0x50cd34(0x13e)](_0x2245d2,_0x42bb0e,_0x3aed8d={}){const _0xffdf6f=a0_0x50cd34;try{const _0x192ac7=await this[_0xffdf6f(0x158)](_0x2245d2,_0x3aed8d[_0xffdf6f(0x136)]),_0x1de27e=this['getParser'](_0x2245d2),_0x51cb8f=await a0_0x48dcdd[_0xffdf6f(0x141)](_0x42bb0e,{..._0x192ac7,'filepath':_0x2245d2,'parser':_0x1de27e});return _0x51cb8f!==_0x42bb0e;}catch(_0x4ae5b1){return this[_0xffdf6f(0x149)]?.[_0xffdf6f(0x140)]('Prettier\x20check\x20failed',{'file':_0x2245d2,'error':_0x4ae5b1[_0xffdf6f(0x15a)]}),![];}}async[a0_0x50cd34(0x158)](_0x4ca15a,_0x407fa9){const _0x3bf877=a0_0x50cd34,_0x5cfcd8=_0x407fa9||a0_0x5a014d['dirname'](_0x4ca15a);if(this['configCache']['has'](_0x5cfcd8))return this['configCache'][_0x3bf877(0x145)](_0x5cfcd8);let _0x21a0a7={};if(_0x407fa9)try{const _0x3e2b3b=await a0_0x48dcdd['resolveConfig'](_0x4ca15a,{'config':_0x407fa9});_0x3e2b3b&&(this[_0x3bf877(0x149)]?.[_0x3bf877(0x142)](_0x3bf877(0x155),{'workingDir':_0x407fa9}),_0x21a0a7=_0x3e2b3b);}catch(_0x1c98c6){this['logger']?.[_0x3bf877(0x142)]('No Prettier config found, using defaults');}const defaultConfig={'semi':!![],'singleQuote':!![],'tabWidth':0x2,'trailingComma':'es5','printWidth':0x64,'arrowParens':'avoid','endOfLine':'lf',..._0x21a0a7};return this[_0x3bf877(0x13d)]['set'](_0x5cfcd8,defaultConfig),defaultConfig;}['getParser'](_0x13623b){const _0x2241b7=a0_0x50cd34,_0x40887b=a0_0x5a014d['extname'](_0x13623b)[_0x2241b7(0x14a)](),_0x36a93d={'.js':_0x2241b7(0x139),'.jsx':_0x2241b7(0x139),'.mjs':'babel','.cjs':_0x2241b7(0x139),'.ts':_0x2241b7(0x14e),'.tsx':_0x2241b7(0x14e),'.json':_0x2241b7(0x13f),'.json5':'json5','.css':_0x2241b7(0x146),'.scss':_0x2241b7(0x143),'.less':'less','.html':_0x2241b7(0x157),'.vue':'vue','.md':'markdown','.yaml':'yaml','.yml':'yaml'};return _0x36a93d[_0x40887b]||'babel';}[a0_0x50cd34(0x15c)](_0x1b4072,_0x4c5eaa){const _0x1b7b49=a0_0x50cd34,_0x406ab5=[],_0x436424=_0x1b4072[_0x1b7b49(0x138)]('\x0a'),_0x3b1d5d=_0x4c5eaa['split']('\x0a'),_0x654716=Math[_0x1b7b49(0x15b)](_0x436424[_0x1b7b49(0x14b)],_0x3b1d5d['length']);for(let _0xe78a1a=0x0;_0xe78a1a<_0x654716;_0xe78a1a++){const _0x502d7f=_0x436424[_0xe78a1a],_0x1cfb32=_0x3b1d5d[_0xe78a1a];_0x502d7f!==_0x1cfb32&&_0x406ab5['push']({'line':_0xe78a1a+0x1,'type':_0x502d7f!==undefined&&_0x1cfb32!==undefined?'modified':_0x502d7f!==undefined?_0x1b7b49(0x13a):_0x1b7b49(0x154),'original':_0x502d7f||'','formatted':_0x1cfb32||''});}return _0x406ab5;}['countChangedLines'](_0x3e3717,_0x2f193c){const _0x141211=a0_0x50cd34,_0xacf593=_0x3e3717['split']('\x0a'),_0x1e1d7f=_0x2f193c[_0x141211(0x138)]('\x0a');let _0x3460bd=0x0;const _0x556d7b=Math['max'](_0xacf593['length'],_0x1e1d7f[_0x141211(0x14b)]);for(let _0x8d972b=0x0;_0x8d972b<_0x556d7b;_0x8d972b++){_0xacf593[_0x8d972b]!==_0x1e1d7f[_0x8d972b]&&_0x3460bd++;}return _0x3460bd;}['getSupportedExtensions'](){const _0x4f5d6a=a0_0x50cd34;return[_0x4f5d6a(0x137),'.jsx',_0x4f5d6a(0x135),'.cjs','.ts',_0x4f5d6a(0x13b),_0x4f5d6a(0x14c),_0x4f5d6a(0x14d),'.css','.scss','.less','.html','.vue','.md',_0x4f5d6a(0x156),'.yml'];}['isSupported'](_0x3339e6){const _0x589006=a0_0x50cd34,_0x41e849=a0_0x5a014d['extname'](_0x3339e6)['toLowerCase']();return this[_0x589006(0x159)]()['includes'](_0x41e849);}}export default PrettierFormatter;
|
|
@@ -1,266 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* PythonAnalyzer - Python code analysis using Python's ast module
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Analyze Python code for syntax errors
|
|
6
|
-
* - Detect import issues
|
|
7
|
-
* - Support Django, Flask, FastAPI frameworks
|
|
8
|
-
* - Use Python's built-in ast module via subprocess
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { spawn } from 'child_process';
|
|
12
|
-
import { STATIC_ANALYSIS } from '../utilities/constants.js';
|
|
13
|
-
import fs from 'fs/promises';
|
|
14
|
-
import path from 'path';
|
|
15
|
-
import os from 'os';
|
|
16
|
-
|
|
17
|
-
class PythonAnalyzer {
|
|
18
|
-
constructor(logger = null) {
|
|
19
|
-
this.logger = logger;
|
|
20
|
-
this.pythonCommand = null;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Analyze Python code
|
|
25
|
-
* @param {string} filePath - Path to file
|
|
26
|
-
* @param {string} content - File content
|
|
27
|
-
* @param {Object} options - Analysis options
|
|
28
|
-
* @returns {Promise<Array>} Array of diagnostics
|
|
29
|
-
*/
|
|
30
|
-
async analyze(filePath, content, options = {}) {
|
|
31
|
-
try {
|
|
32
|
-
const diagnostics = [];
|
|
33
|
-
|
|
34
|
-
// Check if Python is available
|
|
35
|
-
const pythonCmd = await this.getPythonCommand();
|
|
36
|
-
if (!pythonCmd) {
|
|
37
|
-
this.logger?.warn('Python not available, skipping analysis');
|
|
38
|
-
return [];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Run syntax check using Python's ast module
|
|
42
|
-
const syntaxErrors = await this.checkSyntax(filePath, content, pythonCmd);
|
|
43
|
-
diagnostics.push(...syntaxErrors);
|
|
44
|
-
|
|
45
|
-
this.logger?.debug('Python analysis completed', {
|
|
46
|
-
file: filePath,
|
|
47
|
-
totalDiagnostics: diagnostics.length,
|
|
48
|
-
errors: diagnostics.filter(d => d.severity === STATIC_ANALYSIS.SEVERITY.ERROR).length,
|
|
49
|
-
warnings: diagnostics.filter(d => d.severity === STATIC_ANALYSIS.SEVERITY.WARNING).length
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return diagnostics;
|
|
53
|
-
|
|
54
|
-
} catch (error) {
|
|
55
|
-
this.logger?.error('Python analysis failed', {
|
|
56
|
-
file: filePath,
|
|
57
|
-
error: error.message
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// Return empty array on error to allow other analysis to continue
|
|
61
|
-
return [];
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Check Python syntax using ast module
|
|
67
|
-
* @private
|
|
68
|
-
*/
|
|
69
|
-
async checkSyntax(filePath, content, pythonCmd) {
|
|
70
|
-
const diagnostics = [];
|
|
71
|
-
|
|
72
|
-
// Create a temporary Python script to check syntax
|
|
73
|
-
const tempDir = os.tmpdir();
|
|
74
|
-
const tempScript = path.join(tempDir, `syntax_check_${Date.now()}.py`);
|
|
75
|
-
const tempFile = path.join(tempDir, `target_${Date.now()}.py`);
|
|
76
|
-
|
|
77
|
-
try {
|
|
78
|
-
// Write the content to a temporary file
|
|
79
|
-
await fs.writeFile(tempFile, content, 'utf-8');
|
|
80
|
-
|
|
81
|
-
// Create syntax checker script
|
|
82
|
-
const checkerScript = `
|
|
83
|
-
import ast
|
|
84
|
-
import sys
|
|
85
|
-
import json
|
|
86
|
-
|
|
87
|
-
def check_syntax(filepath):
|
|
88
|
-
try:
|
|
89
|
-
with open(filepath, 'r', encoding='utf-8') as f:
|
|
90
|
-
source = f.read()
|
|
91
|
-
|
|
92
|
-
# Try to parse the file
|
|
93
|
-
ast.parse(source, filename=filepath)
|
|
94
|
-
|
|
95
|
-
# If successful, no errors
|
|
96
|
-
print(json.dumps({"success": True, "errors": []}))
|
|
97
|
-
|
|
98
|
-
except SyntaxError as e:
|
|
99
|
-
error = {
|
|
100
|
-
"file": filepath,
|
|
101
|
-
"line": e.lineno or 1,
|
|
102
|
-
"column": e.offset or 1,
|
|
103
|
-
"message": str(e.msg),
|
|
104
|
-
"text": e.text.strip() if e.text else ""
|
|
105
|
-
}
|
|
106
|
-
print(json.dumps({"success": False, "errors": [error]}))
|
|
107
|
-
|
|
108
|
-
except Exception as e:
|
|
109
|
-
error = {
|
|
110
|
-
"file": filepath,
|
|
111
|
-
"line": 1,
|
|
112
|
-
"column": 1,
|
|
113
|
-
"message": str(e),
|
|
114
|
-
"text": ""
|
|
115
|
-
}
|
|
116
|
-
print(json.dumps({"success": False, "errors": [error]}))
|
|
117
|
-
|
|
118
|
-
if __name__ == "__main__":
|
|
119
|
-
if len(sys.argv) > 1:
|
|
120
|
-
check_syntax(sys.argv[1])
|
|
121
|
-
else:
|
|
122
|
-
print(json.dumps({"success": False, "errors": [{"message": "No file specified"}]}))
|
|
123
|
-
`;
|
|
124
|
-
|
|
125
|
-
await fs.writeFile(tempScript, checkerScript, 'utf-8');
|
|
126
|
-
|
|
127
|
-
// Run the checker script
|
|
128
|
-
const result = await this.runPythonScript(pythonCmd, tempScript, [tempFile]);
|
|
129
|
-
|
|
130
|
-
// Parse the result
|
|
131
|
-
try {
|
|
132
|
-
const parsed = JSON.parse(result.stdout);
|
|
133
|
-
|
|
134
|
-
if (!parsed.success && parsed.errors) {
|
|
135
|
-
for (const error of parsed.errors) {
|
|
136
|
-
diagnostics.push({
|
|
137
|
-
file: filePath,
|
|
138
|
-
line: error.line || 1,
|
|
139
|
-
column: error.column || 1,
|
|
140
|
-
severity: STATIC_ANALYSIS.SEVERITY.ERROR,
|
|
141
|
-
rule: 'SyntaxError',
|
|
142
|
-
message: error.message,
|
|
143
|
-
category: STATIC_ANALYSIS.CATEGORY.SYNTAX,
|
|
144
|
-
fixable: false,
|
|
145
|
-
source: 'python-ast',
|
|
146
|
-
code: error.text || undefined
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
} catch (parseError) {
|
|
151
|
-
this.logger?.warn('Failed to parse Python syntax check result', {
|
|
152
|
-
error: parseError.message,
|
|
153
|
-
stdout: result.stdout
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
} finally {
|
|
158
|
-
// Clean up temporary files
|
|
159
|
-
try {
|
|
160
|
-
await fs.unlink(tempScript);
|
|
161
|
-
await fs.unlink(tempFile);
|
|
162
|
-
} catch {
|
|
163
|
-
// Ignore cleanup errors
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return diagnostics;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Get Python command (python3 or python)
|
|
172
|
-
* @private
|
|
173
|
-
*/
|
|
174
|
-
async getPythonCommand() {
|
|
175
|
-
if (this.pythonCommand) {
|
|
176
|
-
return this.pythonCommand;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Try python3 first, then python
|
|
180
|
-
const commands = ['python3', 'python'];
|
|
181
|
-
|
|
182
|
-
for (const cmd of commands) {
|
|
183
|
-
try {
|
|
184
|
-
const result = await this.runCommand(cmd, ['--version']);
|
|
185
|
-
if (result.success) {
|
|
186
|
-
this.pythonCommand = cmd;
|
|
187
|
-
this.logger?.debug('Found Python command', { command: cmd, version: result.stdout.trim() });
|
|
188
|
-
return cmd;
|
|
189
|
-
}
|
|
190
|
-
} catch {
|
|
191
|
-
// Continue to next command
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Run Python script
|
|
200
|
-
* @private
|
|
201
|
-
*/
|
|
202
|
-
async runPythonScript(pythonCmd, scriptPath, args = []) {
|
|
203
|
-
return this.runCommand(pythonCmd, [scriptPath, ...args]);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Run command and capture output
|
|
208
|
-
* @private
|
|
209
|
-
*/
|
|
210
|
-
async runCommand(command, args = [], options = {}) {
|
|
211
|
-
return new Promise((resolve, reject) => {
|
|
212
|
-
const proc = spawn(command, args, {
|
|
213
|
-
...options,
|
|
214
|
-
shell: true
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
let stdout = '';
|
|
218
|
-
let stderr = '';
|
|
219
|
-
|
|
220
|
-
proc.stdout?.on('data', (data) => {
|
|
221
|
-
stdout += data.toString();
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
proc.stderr?.on('data', (data) => {
|
|
225
|
-
stderr += data.toString();
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
proc.on('error', (error) => {
|
|
229
|
-
reject(error);
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
proc.on('close', (code) => {
|
|
233
|
-
resolve({
|
|
234
|
-
success: code === 0,
|
|
235
|
-
code,
|
|
236
|
-
stdout,
|
|
237
|
-
stderr
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
// Timeout after 10 seconds
|
|
242
|
-
setTimeout(() => {
|
|
243
|
-
proc.kill();
|
|
244
|
-
reject(new Error('Command timeout'));
|
|
245
|
-
}, 10000);
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Get supported file extensions
|
|
251
|
-
* @returns {Array<string>} Array of supported extensions
|
|
252
|
-
*/
|
|
253
|
-
getSupportedExtensions() {
|
|
254
|
-
return ['.py'];
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Check if auto-fix is supported
|
|
259
|
-
* @returns {boolean} True if auto-fix is supported
|
|
260
|
-
*/
|
|
261
|
-
supportsAutoFix() {
|
|
262
|
-
return false; // Python auto-fix not implemented yet
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export default PythonAnalyzer;
|
|
1
|
+
const a0_0x3e4420=a0_0x3894;(function(_0x58764d,_0x51ff6d){const _0x1508c8=a0_0x3894,_0x4415bc=_0x58764d();while(!![]){try{const _0x106fa3=parseInt(_0x1508c8(0x170))/0x1+-parseInt(_0x1508c8(0x18c))/0x2+-parseInt(_0x1508c8(0x187))/0x3+-parseInt(_0x1508c8(0x16a))/0x4+parseInt(_0x1508c8(0x18b))/0x5+-parseInt(_0x1508c8(0x169))/0x6+parseInt(_0x1508c8(0x182))/0x7;if(_0x106fa3===_0x51ff6d)break;else _0x4415bc['push'](_0x4415bc['shift']());}catch(_0x49b78d){_0x4415bc['push'](_0x4415bc['shift']());}}}(a0_0x4536,0xc2dd3));function a0_0x3894(_0x55bc82,_0x307b8d){_0x55bc82=_0x55bc82-0x165;const _0x453628=a0_0x4536();let _0x389437=_0x453628[_0x55bc82];if(a0_0x3894['ozGwYT']===undefined){var _0x3312e9=function(_0x4da1a6){const _0x294e3b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x389009='',_0xeb39bd='';for(let _0x17448d=0x0,_0x497e23,_0x2aeb40,_0x33cf31=0x0;_0x2aeb40=_0x4da1a6['charAt'](_0x33cf31++);~_0x2aeb40&&(_0x497e23=_0x17448d%0x4?_0x497e23*0x40+_0x2aeb40:_0x2aeb40,_0x17448d++%0x4)?_0x389009+=String['fromCharCode'](0xff&_0x497e23>>(-0x2*_0x17448d&0x6)):0x0){_0x2aeb40=_0x294e3b['indexOf'](_0x2aeb40);}for(let _0x46027f=0x0,_0x5e8a54=_0x389009['length'];_0x46027f<_0x5e8a54;_0x46027f++){_0xeb39bd+='%'+('00'+_0x389009['charCodeAt'](_0x46027f)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xeb39bd);};a0_0x3894['HFOrXu']=_0x3312e9,a0_0x3894['IFyxgo']={},a0_0x3894['ozGwYT']=!![];}const _0x244997=_0x453628[0x0],_0x17d7d6=_0x55bc82+_0x244997,_0x2ce845=a0_0x3894['IFyxgo'][_0x17d7d6];return!_0x2ce845?(_0x389437=a0_0x3894['HFOrXu'](_0x389437),a0_0x3894['IFyxgo'][_0x17d7d6]=_0x389437):_0x389437=_0x2ce845,_0x389437;}import{spawn}from'child_process';import{STATIC_ANALYSIS}from'../utilities/constants.js';function a0_0x4536(){const _0x33cbb2=['lNb5','mtm1nZyXmtvOwKHdvK4','ChvZAa','CNvUq29TBwfUza','D3jPDgvgAwXL','u3LUDgf4rxjYB3i','mZe1mJmXDhzPD1D2','BgvUz3rO','zgf0yq','zxjYB3jZ','ntiXmtmZmgnmwfPowa','mJe2oda1neDjBLLAzG','C3vJy2vZCW','BgLUzq','C3LUDgf4x2nOzwnRxW','AM9PBG','nZi0odqZohzHCujksW','ntm1mtm2nfniA1Dlsq','DxrMltG','u1Lovefy','D2fYBG','Bg9Nz2vY','ls12zxjZAw9U','mtu1mtq3me1rwfD6yq','rMfPBgvKihrVihbHCNnLifb5DgHVBIbZEw50yxGGy2HLy2SGCMvZDwX0','ChL0Ag9Uq29TBwfUza','z2v0uhL0Ag9Uq29TBwfUza','DhjPBq','BwvZC2fNzq','CNvUuhL0Ag9Uu2nYAxb0','rvjst1i','BM93','z2v0u3vWCg9YDgvKrxH0zw5ZAw9UCW','uhL0Ag9Uig5VDcbHDMfPBgfIBguSihnRAxbWAw5NigfUywX5C2LZ','v0fstKLorW','C3rKB3v0','Dgv4Da','y2XVC2u','yw5HBhL6zq','Dw5SAw5R'];a0_0x4536=function(){return _0x33cbb2;};return a0_0x4536();}import a0_0x389009 from'fs/promises';import a0_0xeb39bd from'path';import a0_0x17448d from'os';class PythonAnalyzer{constructor(_0x497e23=null){const _0x5a2ba7=a0_0x3894;this[_0x5a2ba7(0x16e)]=_0x497e23,this['pythonCommand']=null;}async[a0_0x3e4420(0x17f)](_0x2aeb40,_0x33cf31,_0x46027f={}){const _0x463f7a=a0_0x3e4420;try{const _0x5e8a54=[],_0x180781=await this[_0x463f7a(0x173)]();if(!_0x180781)return this['logger']?.['warn'](_0x463f7a(0x17a)),[];const _0x2a3827=await this['checkSyntax'](_0x2aeb40,_0x33cf31,_0x180781);return _0x5e8a54[_0x463f7a(0x183)](..._0x2a3827),this[_0x463f7a(0x16e)]?.['debug']('Python\x20analysis\x20completed',{'file':_0x2aeb40,'totalDiagnostics':_0x5e8a54[_0x463f7a(0x188)],'errors':_0x5e8a54['filter'](_0x2e1770=>_0x2e1770['severity']===STATIC_ANALYSIS['SEVERITY']['ERROR'])[_0x463f7a(0x188)],'warnings':_0x5e8a54['filter'](_0x5b85c1=>_0x5b85c1['severity']===STATIC_ANALYSIS['SEVERITY'][_0x463f7a(0x17b)])['length']}),_0x5e8a54;}catch(_0x211462){return this['logger']?.['error']('Python\x20analysis\x20failed',{'file':_0x2aeb40,'error':_0x211462[_0x463f7a(0x175)]}),[];}}async['checkSyntax'](_0x2651a6,_0x19381f,_0x296839){const _0x494f63=a0_0x3e4420,_0x1a292c=[],_0x46bf30=a0_0x17448d['tmpdir'](),_0x4997b6=a0_0xeb39bd[_0x494f63(0x168)](_0x46bf30,_0x494f63(0x167)+Date[_0x494f63(0x178)]()+'.py'),_0x4c328b=a0_0xeb39bd['join'](_0x46bf30,'target_'+Date['now']()+_0x494f63(0x181));try{await a0_0x389009[_0x494f63(0x185)](_0x4c328b,_0x19381f,_0x494f63(0x16b));const _0x222170='\x0aimport\x20ast\x0aimport\x20sys\x0aimport\x20json\x0a\x0adef\x20check_syntax(filepath):\x0a\x20\x20\x20\x20try:\x0a\x20\x20\x20\x20\x20\x20\x20\x20with\x20open(filepath,\x20\x27r\x27,\x20encoding=\x27utf-8\x27)\x20as\x20f:\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20source\x20=\x20f.read()\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20#\x20Try\x20to\x20parse\x20the\x20file\x0a\x20\x20\x20\x20\x20\x20\x20\x20ast.parse(source,\x20filename=filepath)\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20#\x20If\x20successful,\x20no\x20errors\x0a\x20\x20\x20\x20\x20\x20\x20\x20print(json.dumps({\x22success\x22:\x20True,\x20\x22errors\x22:\x20[]}))\x0a\x0a\x20\x20\x20\x20except\x20SyntaxError\x20as\x20e:\x0a\x20\x20\x20\x20\x20\x20\x20\x20error\x20=\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22file\x22:\x20filepath,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22line\x22:\x20e.lineno\x20or\x201,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22column\x22:\x20e.offset\x20or\x201,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22message\x22:\x20str(e.msg),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22text\x22:\x20e.text.strip()\x20if\x20e.text\x20else\x20\x22\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20print(json.dumps({\x22success\x22:\x20False,\x20\x22errors\x22:\x20[error]}))\x0a\x0a\x20\x20\x20\x20except\x20Exception\x20as\x20e:\x0a\x20\x20\x20\x20\x20\x20\x20\x20error\x20=\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22file\x22:\x20filepath,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22line\x22:\x201,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22column\x22:\x201,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22message\x22:\x20str(e),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22text\x22:\x20\x22\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20print(json.dumps({\x22success\x22:\x20False,\x20\x22errors\x22:\x20[error]}))\x0a\x0aif\x20__name__\x20==\x20\x22__main__\x22:\x0a\x20\x20\x20\x20if\x20len(sys.argv)\x20>\x201:\x0a\x20\x20\x20\x20\x20\x20\x20\x20check_syntax(sys.argv[1])\x0a\x20\x20\x20\x20else:\x0a\x20\x20\x20\x20\x20\x20\x20\x20print(json.dumps({\x22success\x22:\x20False,\x20\x22errors\x22:\x20[{\x22message\x22:\x20\x22No\x20file\x20specified\x22}]}))\x0a';await a0_0x389009['writeFile'](_0x4997b6,_0x222170,_0x494f63(0x16b));const _0x29d3a2=await this[_0x494f63(0x176)](_0x296839,_0x4997b6,[_0x4c328b]);try{const _0x281d8c=JSON['parse'](_0x29d3a2[_0x494f63(0x17c)]);if(!_0x281d8c[_0x494f63(0x165)]&&_0x281d8c[_0x494f63(0x18a)])for(const _0x1e9f04 of _0x281d8c['errors']){_0x1a292c[_0x494f63(0x183)]({'file':_0x2651a6,'line':_0x1e9f04[_0x494f63(0x166)]||0x1,'column':_0x1e9f04['column']||0x1,'severity':STATIC_ANALYSIS['SEVERITY'][_0x494f63(0x177)],'rule':_0x494f63(0x186),'message':_0x1e9f04['message'],'category':STATIC_ANALYSIS['CATEGORY'][_0x494f63(0x16c)],'fixable':![],'source':'python-ast','code':_0x1e9f04[_0x494f63(0x17d)]||undefined});}}catch(_0x123c72){this['logger']?.[_0x494f63(0x16d)](_0x494f63(0x171),{'error':_0x123c72['message'],'stdout':_0x29d3a2[_0x494f63(0x17c)]});}}finally{try{await a0_0x389009[_0x494f63(0x180)](_0x4997b6),await a0_0x389009['unlink'](_0x4c328b);}catch{}}return _0x1a292c;}async['getPythonCommand'](){const _0x1b061f=a0_0x3e4420;if(this[_0x1b061f(0x172)])return this[_0x1b061f(0x172)];const _0x257ac2=['python3','python'];for(const _0x2e2b18 of _0x257ac2){try{const _0x25e6b7=await this[_0x1b061f(0x184)](_0x2e2b18,[_0x1b061f(0x16f)]);if(_0x25e6b7[_0x1b061f(0x165)])return this['pythonCommand']=_0x2e2b18,this['logger']?.['debug']('Found\x20Python\x20command',{'command':_0x2e2b18,'version':_0x25e6b7[_0x1b061f(0x17c)][_0x1b061f(0x174)]()}),_0x2e2b18;}catch{}}return null;}async[a0_0x3e4420(0x176)](_0x4fe3ea,_0x39c34c,_0x3d9cb3=[]){return this['runCommand'](_0x4fe3ea,[_0x39c34c,..._0x3d9cb3]);}async['runCommand'](_0x3e34e2,_0xbac205=[],_0x1f1d8a={}){return new Promise((_0x34e4b5,_0x3f8c84)=>{const _0xbf2bd4=a0_0x3894,_0x250901=spawn(_0x3e34e2,_0xbac205,{..._0x1f1d8a,'shell':!![]});let _0xe63052='',_0xa435df='';_0x250901['stdout']?.['on']('data',_0x48223b=>{_0xe63052+=_0x48223b['toString']();}),_0x250901['stderr']?.['on'](_0xbf2bd4(0x189),_0x5bae78=>{_0xa435df+=_0x5bae78['toString']();}),_0x250901['on']('error',_0x3ba7af=>{_0x3f8c84(_0x3ba7af);}),_0x250901['on'](_0xbf2bd4(0x17e),_0x33aef9=>{_0x34e4b5({'success':_0x33aef9===0x0,'code':_0x33aef9,'stdout':_0xe63052,'stderr':_0xa435df});}),setTimeout(()=>{_0x250901['kill'](),_0x3f8c84(new Error('Command\x20timeout'));},0x2710);});}[a0_0x3e4420(0x179)](){return['.py'];}['supportsAutoFix'](){return![];}}export default PythonAnalyzer;
|