@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4
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 +15 -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_0x5f4b5b=a0_0x2e9d;function a0_0x2e9d(_0x40edf1,_0x456c41){_0x40edf1=_0x40edf1-0x114;const _0x1ee2d4=a0_0x1ee2();let _0x2e9df3=_0x1ee2d4[_0x40edf1];if(a0_0x2e9d['AeLdwt']===undefined){var _0x4f2344=function(_0x489463){const _0x2ce8c3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1865b9='',_0x339ccf='';for(let _0x46d2ca=0x0,_0x3442e8,_0x5b67fc,_0x4f4fba=0x0;_0x5b67fc=_0x489463['charAt'](_0x4f4fba++);~_0x5b67fc&&(_0x3442e8=_0x46d2ca%0x4?_0x3442e8*0x40+_0x5b67fc:_0x5b67fc,_0x46d2ca++%0x4)?_0x1865b9+=String['fromCharCode'](0xff&_0x3442e8>>(-0x2*_0x46d2ca&0x6)):0x0){_0x5b67fc=_0x2ce8c3['indexOf'](_0x5b67fc);}for(let _0x1a3677=0x0,_0x861802=_0x1865b9['length'];_0x1a3677<_0x861802;_0x1a3677++){_0x339ccf+='%'+('00'+_0x1865b9['charCodeAt'](_0x1a3677)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x339ccf);};a0_0x2e9d['VnKQes']=_0x4f2344,a0_0x2e9d['bGWIKW']={},a0_0x2e9d['AeLdwt']=!![];}const _0x190753=_0x1ee2d4[0x0],_0x5b94b6=_0x40edf1+_0x190753,_0x59f4bd=a0_0x2e9d['bGWIKW'][_0x5b94b6];return!_0x59f4bd?(_0x2e9df3=a0_0x2e9d['VnKQes'](_0x2e9df3),a0_0x2e9d['bGWIKW'][_0x5b94b6]=_0x2e9df3):_0x2e9df3=_0x59f4bd,_0x2e9df3;}(function(_0x151982,_0x5ce5fd){const _0x2b37fd=a0_0x2e9d,_0x268328=_0x151982();while(!![]){try{const _0xbb905e=-parseInt(_0x2b37fd(0x13d))/0x1+parseInt(_0x2b37fd(0x12c))/0x2*(parseInt(_0x2b37fd(0x11a))/0x3)+-parseInt(_0x2b37fd(0x135))/0x4*(-parseInt(_0x2b37fd(0x11b))/0x5)+-parseInt(_0x2b37fd(0x133))/0x6*(parseInt(_0x2b37fd(0x120))/0x7)+-parseInt(_0x2b37fd(0x146))/0x8+parseInt(_0x2b37fd(0x141))/0x9*(-parseInt(_0x2b37fd(0x139))/0xa)+parseInt(_0x2b37fd(0x12a))/0xb*(parseInt(_0x2b37fd(0x12b))/0xc);if(_0xbb905e===_0x5ce5fd)break;else _0x268328['push'](_0x268328['shift']());}catch(_0x2dfc5c){_0x268328['push'](_0x268328['shift']());}}}(a0_0x1ee2,0x61934));import a0_0x1865b9 from'prettier';import a0_0x339ccf from'path';function a0_0x1ee2(){const _0x23a93e=['y29UzMLNq2fJAgu','lMH0BwW','yMfIzwW','lNrZEa','oty0n1vtzMzAAG','mZiYogzOEe1vvW','mtm2ndKYnfrwwfHRDG','zM9YBwf0','Dg9mB3DLCKnHC2u','yxzVAwq','zgvIDwC','BwfYA2rVD24','lNLHBwW','nNfuDK12DW','lMnZCW','mJG4t0HtqMTI','y3nZ','y291BNrdAgfUz2vKtgLUzxm','z2v0','mJy4nJy3mhLfquTNtG','zgvZy3jPyMvdAgfUz2vZ','ANnVBG','Aw5JBhvKzxm','mZaYotfWuxH3Eu4','lM1K','BwvZC2fNzq','EwfTBa','mtHWC1DWs0S','lMXLC3m','D29YA2LUz0rPCG','DhLWzxnJCMLWDa','Bwf4','mJuZmZi0merfz2PHAG','Bg9Nz2vY','C3bSAxq','D2fYBG','z2v0ugfYC2vY','C2v0','zxH0BMfTzq','ANnVBJu','m0vSuK1cqq','mJyWndvRuNr2q0e','lMPZB241','ChvZAa','z2v0u3vWCg9YDgvKrxH0zw5ZAw9UCW','uhjLDhrPzxiGy2HLy2SGzMfPBgvK','nJyZmJv2ANPiDha','Bw9KAwzPzwq','z2v0uhjLDhrPzxjdB25MAwC','BgvUz3rO','AxntDxbWB3j0zwq','DNvL'];a0_0x1ee2=function(){return _0x23a93e;};return a0_0x1ee2();}import a0_0x46d2ca from'fs/promises';class PrettierFormatter{constructor(_0x3442e8=null){const _0x34fdd6=a0_0x2e9d;this[_0x34fdd6(0x147)]=_0x3442e8,this[_0x34fdd6(0x126)]=new Map();}async['format'](_0x5b67fc,_0x4f4fba,_0x1a3677={}){const _0x44f6ef=a0_0x2e9d;try{const _0x861802=await this[_0x44f6ef(0x122)](_0x5b67fc,_0x1a3677[_0x44f6ef(0x143)]),_0x3775b3=this[_0x44f6ef(0x116)](_0x5b67fc),_0x5be11e=await a0_0x1865b9[_0x44f6ef(0x12d)](_0x4f4fba,{..._0x861802,'filepath':_0x5b67fc,'parser':_0x3775b3}),_0x4abbfc=_0x5be11e!==_0x4f4fba;return{'formatted':_0x4abbfc,'content':_0x5be11e,'original':_0x4f4fba,'changes':_0x4abbfc?this[_0x44f6ef(0x13a)](_0x4f4fba,_0x5be11e):[],'linesChanged':_0x4abbfc?this['countChangedLines'](_0x4f4fba,_0x5be11e):0x0};}catch(_0x16a049){this[_0x44f6ef(0x147)]?.['error']('Prettier\x20formatting\x20failed',{'file':_0x5b67fc,'error':_0x16a049[_0x44f6ef(0x13f)]});throw new Error('Prettier\x20formatting\x20failed:\x20'+_0x16a049[_0x44f6ef(0x13f)]);}}async['check'](_0xbc77a2,_0xc962c6,_0x35a792={}){const _0x253357=a0_0x2e9d;try{const _0x33fedb=await this[_0x253357(0x122)](_0xbc77a2,_0x35a792[_0x253357(0x143)]),_0x4fca24=this[_0x253357(0x116)](_0xbc77a2),_0x10e138=await a0_0x1865b9[_0x253357(0x12d)](_0xc962c6,{..._0x33fedb,'filepath':_0xbc77a2,'parser':_0x4fca24});return _0x10e138!==_0xc962c6;}catch(_0x266d3f){return this['logger']?.[_0x253357(0x115)](_0x253357(0x11f),{'file':_0xbc77a2,'error':_0x266d3f[_0x253357(0x13f)]}),![];}}async['getPrettierConfig'](_0x542e56,_0x14e5bd){const _0x2ec272=a0_0x2e9d,_0x462137=_0x14e5bd||a0_0x339ccf['dirname'](_0x542e56);if(this['configCache']['has'](_0x462137))return this[_0x2ec272(0x126)][_0x2ec272(0x138)](_0x462137);let _0x3c6d27={};if(_0x14e5bd)try{const _0x1900f1=await a0_0x1865b9['resolveConfig'](_0x542e56,{'config':_0x14e5bd});_0x1900f1&&(this['logger']?.[_0x2ec272(0x130)]('Found\x20Prettier\x20config',{'workingDir':_0x14e5bd}),_0x3c6d27=_0x1900f1);}catch(_0x3979ad){this[_0x2ec272(0x147)]?.[_0x2ec272(0x130)]('No Prettier config found, using defaults');}const defaultConfig={'semi':!![],'singleQuote':!![],'tabWidth':0x2,'trailingComma':'es5','printWidth':0x64,'arrowParens':_0x2ec272(0x12f),'endOfLine':'lf',..._0x3c6d27};return this['configCache'][_0x2ec272(0x117)](_0x462137,defaultConfig),defaultConfig;}[a0_0x5f4b5b(0x116)](_0x120f13){const _0x453d28=a0_0x5f4b5b,_0x1a7e48=a0_0x339ccf[_0x453d28(0x118)](_0x120f13)['toLowerCase'](),_0x2dd27f={'.js':'babel','.jsx':'babel','.mjs':'babel','.cjs':_0x453d28(0x128),'.ts':_0x453d28(0x144),'.tsx':_0x453d28(0x144),'.json':_0x453d28(0x13b),'.json5':_0x453d28(0x119),'.css':_0x453d28(0x136),'.scss':'scss','.less':'less','.html':'html','.vue':_0x453d28(0x125),'.md':_0x453d28(0x131),'.yaml':_0x453d28(0x140),'.yml':'yaml'};return _0x2dd27f[_0x1a7e48]||'babel';}['describeChanges'](_0x3e78a9,_0x5d2c38){const _0xc514c7=a0_0x5f4b5b,_0x4368e3=[],_0x4c1f4b=_0x3e78a9[_0xc514c7(0x114)]('\x0a'),_0x3e5d54=_0x5d2c38['split']('\x0a'),_0x1b84db=Math[_0xc514c7(0x145)](_0x4c1f4b['length'],_0x3e5d54['length']);for(let _0x3a82ba=0x0;_0x3a82ba<_0x1b84db;_0x3a82ba++){const _0x18d2b5=_0x4c1f4b[_0x3a82ba],_0xde3f4f=_0x3e5d54[_0x3a82ba];_0x18d2b5!==_0xde3f4f&&_0x4368e3[_0xc514c7(0x11d)]({'line':_0x3a82ba+0x1,'type':_0x18d2b5!==undefined&&_0xde3f4f!==undefined?_0xc514c7(0x121):_0x18d2b5!==undefined?'removed':'added','original':_0x18d2b5||'','formatted':_0xde3f4f||''});}return _0x4368e3;}[a0_0x5f4b5b(0x137)](_0x26da20,_0x4e6934){const _0x4a7c50=a0_0x5f4b5b,_0x4699b2=_0x26da20[_0x4a7c50(0x114)]('\x0a'),_0x4d6f54=_0x4e6934['split']('\x0a');let _0xe8ccb3=0x0;const _0x128f55=Math['max'](_0x4699b2[_0x4a7c50(0x123)],_0x4d6f54[_0x4a7c50(0x123)]);for(let _0x122cd6=0x0;_0x122cd6<_0x128f55;_0x122cd6++){_0x4699b2[_0x122cd6]!==_0x4d6f54[_0x122cd6]&&_0xe8ccb3++;}return _0xe8ccb3;}[a0_0x5f4b5b(0x11e)](){const _0x26e0a3=a0_0x5f4b5b;return['.js','.jsx','.mjs','.cjs','.ts',_0x26e0a3(0x129),'.json',_0x26e0a3(0x11c),_0x26e0a3(0x134),'.scss',_0x26e0a3(0x142),_0x26e0a3(0x127),'.vue',_0x26e0a3(0x13e),_0x26e0a3(0x132),'.yml'];}[a0_0x5f4b5b(0x124)](_0x5ce550){const _0x5c2ea9=a0_0x5f4b5b,_0x12868d=a0_0x339ccf['extname'](_0x5ce550)[_0x5c2ea9(0x12e)]();return this['getSupportedExtensions']()[_0x5c2ea9(0x13c)](_0x12868d);}}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_0x4c81ec=a0_0x383e;function a0_0x84f6(){const _0x2ef85d=['CgfYC2u','DgfYz2v0xW','Dg9tDhjPBMC','rMfPBgvKihrVihbHCNnLifb5DgHVBIbZEw50yxGGy2HLy2SGCMvZDwX0','yw5HBhL6zq','ndmZnJm0mejnrg9YDW','ChL0Ag9UlwfZDa','y2XVC2u','mJu1nZu1sgzvB0Hy','owXbqMz0wG','odr3tfzpEhu','C3LUDgf4x2nOzwnRxW','Bg9Nz2vY','BM93','rM91BMqGuhL0Ag9UignVBw1HBMq','BgvUz3rO','C3vJy2vZCW','mty4nta3m2j0zefbDG','zxjYB3i','u1Lovefy','mtKYnJq0ovvStLfeCG','mtz2ALvuB0y','mJKYn1r0qxDZtG','C3rKB3v0','uhL0Ag9UigfUywX5C2LZignVBxbSzxrLza','A2LSBa','mtK4mta1nZfHr3LSswy','DxrMltG','zMLSDgvY','ChL0Ag9Uq29TBwfUza','y2HLy2TtEw50yxG','CNvUuhL0Ag9Uu2nYAxb0','lNb5','zgf0yq','mJe3mJeZmMLwvMfgrW','ndi4wunhsNjS','v0fstKLorW','uhL0Ag9Uig5VDcbHDMfPBgfIBguSihnRAxbWAw5NigfUywX5C2LZ','CNvUq29TBwfUza','BwvZC2fNzq','q0furuDpuLK','rvjst1i','u0vwrvjjvfK'];a0_0x84f6=function(){return _0x2ef85d;};return a0_0x84f6();}(function(_0x22918c,_0x3fa39f){const _0xaf8af7=a0_0x383e,_0x27e792=_0x22918c();while(!![]){try{const _0x523203=parseInt(_0xaf8af7(0x14d))/0x1*(-parseInt(_0xaf8af7(0x15a))/0x2)+parseInt(_0xaf8af7(0x148))/0x3+-parseInt(_0xaf8af7(0x159))/0x4+parseInt(_0xaf8af7(0x16a))/0x5*(-parseInt(_0xaf8af7(0x16c))/0x6)+-parseInt(_0xaf8af7(0x14b))/0x7*(parseInt(_0xaf8af7(0x14c))/0x8)+-parseInt(_0xaf8af7(0x16b))/0x9*(-parseInt(_0xaf8af7(0x167))/0xa)+parseInt(_0xaf8af7(0x151))/0xb;if(_0x523203===_0x3fa39f)break;else _0x27e792['push'](_0x27e792['shift']());}catch(_0x177f20){_0x27e792['push'](_0x27e792['shift']());}}}(a0_0x84f6,0x57f9b));import{spawn}from'child_process';import{STATIC_ANALYSIS}from'../utilities/constants.js';import a0_0x2863c7 from'fs/promises';function a0_0x383e(_0xd5acaf,_0x18a786){_0xd5acaf=_0xd5acaf-0x145;const _0x84f6e9=a0_0x84f6();let _0x383e90=_0x84f6e9[_0xd5acaf];if(a0_0x383e['IpzYGN']===undefined){var _0x1e6cfb=function(_0x4618f2){const _0x360e7b='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x2863c7='',_0x49f745='';for(let _0x5c0b11=0x0,_0x3afbe7,_0x4bb2e2,_0x2ca520=0x0;_0x4bb2e2=_0x4618f2['charAt'](_0x2ca520++);~_0x4bb2e2&&(_0x3afbe7=_0x5c0b11%0x4?_0x3afbe7*0x40+_0x4bb2e2:_0x4bb2e2,_0x5c0b11++%0x4)?_0x2863c7+=String['fromCharCode'](0xff&_0x3afbe7>>(-0x2*_0x5c0b11&0x6)):0x0){_0x4bb2e2=_0x360e7b['indexOf'](_0x4bb2e2);}for(let _0x25bdd8=0x0,_0x5483c0=_0x2863c7['length'];_0x25bdd8<_0x5483c0;_0x25bdd8++){_0x49f745+='%'+('00'+_0x2863c7['charCodeAt'](_0x25bdd8)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x49f745);};a0_0x383e['wmApfN']=_0x1e6cfb,a0_0x383e['SjUYOc']={},a0_0x383e['IpzYGN']=!![];}const _0xbf6551=_0x84f6e9[0x0],_0x348cf2=_0xd5acaf+_0xbf6551,_0x248974=a0_0x383e['SjUYOc'][_0x348cf2];return!_0x248974?(_0x383e90=a0_0x383e['wmApfN'](_0x383e90),a0_0x383e['SjUYOc'][_0x348cf2]=_0x383e90):_0x383e90=_0x248974,_0x383e90;}import a0_0x49f745 from'path';import a0_0x5c0b11 from'os';class PythonAnalyzer{constructor(_0x3afbe7=null){const _0x3738a2=a0_0x383e;this[_0x3738a2(0x16e)]=_0x3afbe7,this[_0x3738a2(0x154)]=null;}async[a0_0x4c81ec(0x166)](_0x4bb2e2,_0x2ca520,_0x25bdd8={}){const _0x3a8116=a0_0x4c81ec;try{const _0x5483c0=[],_0x1a5116=await this['getPythonCommand']();if(!_0x1a5116)return this['logger']?.['warn'](_0x3a8116(0x15c)),[];const _0x237d99=await this[_0x3a8116(0x155)](_0x4bb2e2,_0x2ca520,_0x1a5116);return _0x5483c0['push'](..._0x237d99),this[_0x3a8116(0x16e)]?.['debug'](_0x3a8116(0x14f),{'file':_0x4bb2e2,'totalDiagnostics':_0x5483c0['length'],'errors':_0x5483c0[_0x3a8116(0x153)](_0x3dc54b=>_0x3dc54b['severity']===STATIC_ANALYSIS['SEVERITY'][_0x3a8116(0x160)])['length'],'warnings':_0x5483c0['filter'](_0x2be6c7=>_0x2be6c7['severity']===STATIC_ANALYSIS[_0x3a8116(0x161)][_0x3a8116(0x15b)])[_0x3a8116(0x146)]}),_0x5483c0;}catch(_0x11cd71){return this['logger']?.[_0x3a8116(0x149)]('Python\x20analysis\x20failed',{'file':_0x4bb2e2,'error':_0x11cd71['message']}),[];}}async['checkSyntax'](_0x275fb5,_0xfbf232,_0x177a86){const _0x1bf601=a0_0x4c81ec,_0x377b7f=[],_0x1268b4=a0_0x5c0b11['tmpdir'](),_0x2ece19=a0_0x49f745['join'](_0x1268b4,_0x1bf601(0x16d)+Date[_0x1bf601(0x16f)]()+_0x1bf601(0x157)),_0x3ea263=a0_0x49f745['join'](_0x1268b4,_0x1bf601(0x163)+Date[_0x1bf601(0x16f)]()+_0x1bf601(0x157));try{await a0_0x2863c7['writeFile'](_0x3ea263,_0xfbf232,_0x1bf601(0x152));const _0xdda612='\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_0x2863c7['writeFile'](_0x2ece19,_0xdda612,_0x1bf601(0x152));const _0x593b3a=await this[_0x1bf601(0x156)](_0x177a86,_0x2ece19,[_0x3ea263]);try{const _0x5bf3e3=JSON[_0x1bf601(0x162)](_0x593b3a[_0x1bf601(0x14e)]);if(!_0x5bf3e3['success']&&_0x5bf3e3['errors'])for(const _0x142bb6 of _0x5bf3e3['errors']){_0x377b7f['push']({'file':_0x275fb5,'line':_0x142bb6['line']||0x1,'column':_0x142bb6['column']||0x1,'severity':STATIC_ANALYSIS[_0x1bf601(0x161)]['ERROR'],'rule':'SyntaxError','message':_0x142bb6['message'],'category':STATIC_ANALYSIS[_0x1bf601(0x15f)][_0x1bf601(0x14a)],'fixable':![],'source':_0x1bf601(0x168),'code':_0x142bb6['text']||undefined});}}catch(_0x13359a){this['logger']?.['warn'](_0x1bf601(0x165),{'error':_0x13359a[_0x1bf601(0x15e)],'stdout':_0x593b3a[_0x1bf601(0x14e)]});}}finally{try{await a0_0x2863c7['unlink'](_0x2ece19),await a0_0x2863c7['unlink'](_0x3ea263);}catch{}}return _0x377b7f;}async['getPythonCommand'](){const _0x16f760=a0_0x4c81ec;if(this['pythonCommand'])return this['pythonCommand'];const _0x2ba835=['python3','python'];for(const _0x538fe7 of _0x2ba835){try{const _0x387f1c=await this[_0x16f760(0x15d)](_0x538fe7,['--version']);if(_0x387f1c[_0x16f760(0x147)])return this['pythonCommand']=_0x538fe7,this[_0x16f760(0x16e)]?.['debug'](_0x16f760(0x145),{'command':_0x538fe7,'version':_0x387f1c[_0x16f760(0x14e)]['trim']()}),_0x538fe7;}catch{}}return null;}async['runPythonScript'](_0x13d19c,_0x23a425,_0x323e42=[]){return this['runCommand'](_0x13d19c,[_0x23a425,..._0x323e42]);}async[a0_0x4c81ec(0x15d)](_0x54be85,_0x318919=[],_0x506bb9={}){return new Promise((_0x36803f,_0x317b43)=>{const _0x1491da=a0_0x383e,_0x40620b=spawn(_0x54be85,_0x318919,{..._0x506bb9,'shell':!![]});let _0x548ae6='',_0x53afb0='';_0x40620b['stdout']?.['on'](_0x1491da(0x158),_0xe9365d=>{const _0x1ff18c=_0x1491da;_0x548ae6+=_0xe9365d[_0x1ff18c(0x164)]();}),_0x40620b['stderr']?.['on'](_0x1491da(0x158),_0x3a9699=>{_0x53afb0+=_0x3a9699['toString']();}),_0x40620b['on'](_0x1491da(0x149),_0xf59624=>{_0x317b43(_0xf59624);}),_0x40620b['on'](_0x1491da(0x169),_0x283187=>{_0x36803f({'success':_0x283187===0x0,'code':_0x283187,'stdout':_0x548ae6,'stderr':_0x53afb0});}),setTimeout(()=>{const _0x4eaaf0=_0x1491da;_0x40620b[_0x4eaaf0(0x150)](),_0x317b43(new Error('Command\x20timeout'));},0x2710);});}['getSupportedExtensions'](){const _0x24b6db=a0_0x4c81ec;return[_0x24b6db(0x157)];}['supportsAutoFix'](){return![];}}export default PythonAnalyzer;
|