@loxia-labs/loxia-autopilot-one 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +267 -0
- package/README.md +509 -0
- package/bin/cli.js +117 -0
- package/package.json +94 -0
- package/scripts/install-scanners.js +236 -0
- package/src/analyzers/CSSAnalyzer.js +297 -0
- package/src/analyzers/ConfigValidator.js +690 -0
- package/src/analyzers/ESLintAnalyzer.js +320 -0
- package/src/analyzers/JavaScriptAnalyzer.js +261 -0
- package/src/analyzers/PrettierFormatter.js +247 -0
- package/src/analyzers/PythonAnalyzer.js +266 -0
- package/src/analyzers/SecurityAnalyzer.js +729 -0
- package/src/analyzers/TypeScriptAnalyzer.js +247 -0
- package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
- package/src/analyzers/codeCloneDetector/detector.js +203 -0
- package/src/analyzers/codeCloneDetector/index.js +160 -0
- package/src/analyzers/codeCloneDetector/parser.js +199 -0
- package/src/analyzers/codeCloneDetector/reporter.js +148 -0
- package/src/analyzers/codeCloneDetector/scanner.js +59 -0
- package/src/core/agentPool.js +1474 -0
- package/src/core/agentScheduler.js +2147 -0
- package/src/core/contextManager.js +709 -0
- package/src/core/messageProcessor.js +732 -0
- package/src/core/orchestrator.js +548 -0
- package/src/core/stateManager.js +877 -0
- package/src/index.js +631 -0
- package/src/interfaces/cli.js +549 -0
- package/src/interfaces/webServer.js +2162 -0
- package/src/modules/fileExplorer/controller.js +280 -0
- package/src/modules/fileExplorer/index.js +37 -0
- package/src/modules/fileExplorer/middleware.js +92 -0
- package/src/modules/fileExplorer/routes.js +125 -0
- package/src/modules/fileExplorer/types.js +44 -0
- package/src/services/aiService.js +1232 -0
- package/src/services/apiKeyManager.js +164 -0
- package/src/services/benchmarkService.js +366 -0
- package/src/services/budgetService.js +539 -0
- package/src/services/contextInjectionService.js +247 -0
- package/src/services/conversationCompactionService.js +637 -0
- package/src/services/errorHandler.js +810 -0
- package/src/services/fileAttachmentService.js +544 -0
- package/src/services/modelRouterService.js +366 -0
- package/src/services/modelsService.js +322 -0
- package/src/services/qualityInspector.js +796 -0
- package/src/services/tokenCountingService.js +536 -0
- package/src/tools/agentCommunicationTool.js +1344 -0
- package/src/tools/agentDelayTool.js +485 -0
- package/src/tools/asyncToolManager.js +604 -0
- package/src/tools/baseTool.js +800 -0
- package/src/tools/browserTool.js +920 -0
- package/src/tools/cloneDetectionTool.js +621 -0
- package/src/tools/dependencyResolverTool.js +1215 -0
- package/src/tools/fileContentReplaceTool.js +875 -0
- package/src/tools/fileSystemTool.js +1107 -0
- package/src/tools/fileTreeTool.js +853 -0
- package/src/tools/imageTool.js +901 -0
- package/src/tools/importAnalyzerTool.js +1060 -0
- package/src/tools/jobDoneTool.js +248 -0
- package/src/tools/seekTool.js +956 -0
- package/src/tools/staticAnalysisTool.js +1778 -0
- package/src/tools/taskManagerTool.js +2873 -0
- package/src/tools/terminalTool.js +2304 -0
- package/src/tools/webTool.js +1430 -0
- package/src/types/agent.js +519 -0
- package/src/types/contextReference.js +972 -0
- package/src/types/conversation.js +730 -0
- package/src/types/toolCommand.js +747 -0
- package/src/utilities/attachmentValidator.js +292 -0
- package/src/utilities/configManager.js +582 -0
- package/src/utilities/constants.js +722 -0
- package/src/utilities/directoryAccessManager.js +535 -0
- package/src/utilities/fileProcessor.js +307 -0
- package/src/utilities/logger.js +436 -0
- package/src/utilities/tagParser.js +1246 -0
- package/src/utilities/toolConstants.js +317 -0
- package/web-ui/build/index.html +15 -0
- package/web-ui/build/logo.png +0 -0
- package/web-ui/build/logo2.png +0 -0
- package/web-ui/build/static/index-CjkkcnFA.js +344 -0
- package/web-ui/build/static/index-Dy2bYbOa.css +1 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attachment Validator
|
|
3
|
+
* Validates file attachments for security and size constraints
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { fileURLToPath } from 'url';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// Constants
|
|
13
|
+
const SIZE_LIMITS = {
|
|
14
|
+
content: 1024 * 1024, // 1MB for content mode
|
|
15
|
+
reference: Number.MAX_VALUE // No limit for reference mode (just metadata)
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const SIZE_WARNING_THRESHOLD = {
|
|
19
|
+
yellow: 100 * 1024, // 100KB
|
|
20
|
+
red: 1024 * 1024 // 1MB
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const BLOCKED_EXTENSIONS = [
|
|
24
|
+
'.exe', '.dll', '.so', '.dylib',
|
|
25
|
+
'.sh', '.bat', '.cmd', '.ps1',
|
|
26
|
+
'.app', '.dmg', '.deb', '.rpm',
|
|
27
|
+
'.msi', '.pkg', '.apk', '.jar'
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const SUPPORTED_TEXT_EXTENSIONS = [
|
|
31
|
+
'.txt', '.md', '.js', '.jsx', '.ts', '.tsx',
|
|
32
|
+
'.json', '.xml', '.html', '.css', '.scss',
|
|
33
|
+
'.py', '.java', '.cpp', '.c', '.h',
|
|
34
|
+
'.go', '.rs', '.rb', '.php', '.sh',
|
|
35
|
+
'.yml', '.yaml', '.toml', '.env',
|
|
36
|
+
'.log', '.sql', '.vue', '.svelte'
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const SUPPORTED_IMAGE_EXTENSIONS = [
|
|
40
|
+
'.jpg', '.jpeg', '.png', '.gif',
|
|
41
|
+
'.webp', '.bmp', '.svg'
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
const SUPPORTED_PDF_EXTENSIONS = ['.pdf'];
|
|
45
|
+
|
|
46
|
+
class AttachmentValidator {
|
|
47
|
+
constructor(config = {}, logger = null) {
|
|
48
|
+
this.config = config;
|
|
49
|
+
this.logger = logger;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Validate file size
|
|
54
|
+
* @param {number} size - File size in bytes
|
|
55
|
+
* @param {string} mode - 'content' or 'reference'
|
|
56
|
+
* @returns {Object} { valid: boolean, error?: string, warning?: string, level?: string }
|
|
57
|
+
*/
|
|
58
|
+
validateSize(size, mode = 'content') {
|
|
59
|
+
const limit = SIZE_LIMITS[mode];
|
|
60
|
+
|
|
61
|
+
if (size > limit) {
|
|
62
|
+
return {
|
|
63
|
+
valid: false,
|
|
64
|
+
error: `File size (${this.formatBytes(size)}) exceeds ${mode} mode limit (${this.formatBytes(limit)})`
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Check warning thresholds
|
|
69
|
+
if (mode === 'content') {
|
|
70
|
+
if (size > SIZE_WARNING_THRESHOLD.red) {
|
|
71
|
+
return {
|
|
72
|
+
valid: true,
|
|
73
|
+
warning: `This file is large (${this.formatBytes(size)}) and will consume significant tokens`,
|
|
74
|
+
level: 'red'
|
|
75
|
+
};
|
|
76
|
+
} else if (size > SIZE_WARNING_THRESHOLD.yellow) {
|
|
77
|
+
return {
|
|
78
|
+
valid: true,
|
|
79
|
+
warning: `This file is moderately large (${this.formatBytes(size)})`,
|
|
80
|
+
level: 'yellow'
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { valid: true, level: 'green' };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Validate file type (block executables)
|
|
90
|
+
* @param {string} fileName - File name
|
|
91
|
+
* @returns {Object} { valid: boolean, error?: string }
|
|
92
|
+
*/
|
|
93
|
+
validateFileType(fileName) {
|
|
94
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
95
|
+
|
|
96
|
+
if (this.isExecutable(fileName)) {
|
|
97
|
+
return {
|
|
98
|
+
valid: false,
|
|
99
|
+
error: `Executable files (${ext}) are not allowed for security reasons`
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { valid: true };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Check if file is executable
|
|
108
|
+
* @param {string} fileName - File name
|
|
109
|
+
* @returns {boolean}
|
|
110
|
+
*/
|
|
111
|
+
isExecutable(fileName) {
|
|
112
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
113
|
+
return BLOCKED_EXTENSIONS.includes(ext);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Validate file path (for reference mode)
|
|
118
|
+
* @param {string} filePath - File path
|
|
119
|
+
* @returns {Object} { valid: boolean, error?: string }
|
|
120
|
+
*/
|
|
121
|
+
validatePath(filePath) {
|
|
122
|
+
// Check for directory traversal attempts
|
|
123
|
+
const normalizedPath = path.normalize(filePath);
|
|
124
|
+
|
|
125
|
+
if (normalizedPath.includes('..')) {
|
|
126
|
+
return {
|
|
127
|
+
valid: false,
|
|
128
|
+
error: 'Directory traversal is not allowed'
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check for absolute paths to system directories (Unix)
|
|
133
|
+
const systemDirs = ['/etc', '/bin', '/sbin', '/usr/bin', '/usr/sbin', '/sys', '/proc'];
|
|
134
|
+
if (systemDirs.some(dir => normalizedPath.startsWith(dir))) {
|
|
135
|
+
return {
|
|
136
|
+
valid: false,
|
|
137
|
+
error: 'Access to system directories is not allowed'
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check for Windows system directories
|
|
142
|
+
const winSystemDirs = ['C:\\Windows', 'C:\\Program Files', 'C:\\Program Files (x86)'];
|
|
143
|
+
if (winSystemDirs.some(dir => normalizedPath.startsWith(dir))) {
|
|
144
|
+
return {
|
|
145
|
+
valid: false,
|
|
146
|
+
error: 'Access to system directories is not allowed'
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { valid: true };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get content type from file extension
|
|
155
|
+
* @param {string} fileName - File name
|
|
156
|
+
* @returns {string} - 'text' | 'image' | 'pdf' | 'binary'
|
|
157
|
+
*/
|
|
158
|
+
getContentType(fileName) {
|
|
159
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
160
|
+
|
|
161
|
+
if (SUPPORTED_TEXT_EXTENSIONS.includes(ext)) {
|
|
162
|
+
return 'text';
|
|
163
|
+
}
|
|
164
|
+
if (SUPPORTED_IMAGE_EXTENSIONS.includes(ext)) {
|
|
165
|
+
return 'image';
|
|
166
|
+
}
|
|
167
|
+
if (SUPPORTED_PDF_EXTENSIONS.includes(ext)) {
|
|
168
|
+
return 'pdf';
|
|
169
|
+
}
|
|
170
|
+
return 'binary';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check if file type is supported
|
|
175
|
+
* @param {string} fileName - File name
|
|
176
|
+
* @returns {boolean}
|
|
177
|
+
*/
|
|
178
|
+
isSupported(fileName) {
|
|
179
|
+
const contentType = this.getContentType(fileName);
|
|
180
|
+
return contentType !== 'binary';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Validate all aspects of an attachment
|
|
185
|
+
* @param {Object} options
|
|
186
|
+
* @param {string} options.fileName - File name
|
|
187
|
+
* @param {number} options.size - File size in bytes
|
|
188
|
+
* @param {string} options.mode - 'content' or 'reference'
|
|
189
|
+
* @param {string} options.path - File path (for reference mode)
|
|
190
|
+
* @returns {Object} { valid: boolean, errors: string[], warnings: string[], sizeLevel: string }
|
|
191
|
+
*/
|
|
192
|
+
validate({ fileName, size, mode = 'content', path: filePath = null }) {
|
|
193
|
+
const errors = [];
|
|
194
|
+
const warnings = [];
|
|
195
|
+
let sizeLevel = 'green';
|
|
196
|
+
|
|
197
|
+
// Validate file type
|
|
198
|
+
const typeValidation = this.validateFileType(fileName);
|
|
199
|
+
if (!typeValidation.valid) {
|
|
200
|
+
errors.push(typeValidation.error);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Validate size
|
|
204
|
+
const sizeValidation = this.validateSize(size, mode);
|
|
205
|
+
if (!sizeValidation.valid) {
|
|
206
|
+
errors.push(sizeValidation.error);
|
|
207
|
+
} else if (sizeValidation.warning) {
|
|
208
|
+
warnings.push(sizeValidation.warning);
|
|
209
|
+
sizeLevel = sizeValidation.level;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Validate path (reference mode only)
|
|
213
|
+
if (mode === 'reference' && filePath) {
|
|
214
|
+
const pathValidation = this.validatePath(filePath);
|
|
215
|
+
if (!pathValidation.valid) {
|
|
216
|
+
errors.push(pathValidation.error);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Check if file type is supported
|
|
221
|
+
if (!this.isSupported(fileName)) {
|
|
222
|
+
warnings.push(`File type may not be fully supported (${path.extname(fileName)})`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
valid: errors.length === 0,
|
|
227
|
+
errors,
|
|
228
|
+
warnings,
|
|
229
|
+
sizeLevel
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Format bytes to human-readable string
|
|
235
|
+
* @param {number} bytes
|
|
236
|
+
* @returns {string}
|
|
237
|
+
*/
|
|
238
|
+
formatBytes(bytes) {
|
|
239
|
+
if (bytes === 0) return '0 Bytes';
|
|
240
|
+
const k = 1024;
|
|
241
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
242
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
243
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get MIME type from file extension
|
|
248
|
+
* @param {string} fileName - File name
|
|
249
|
+
* @returns {string}
|
|
250
|
+
*/
|
|
251
|
+
getMimeType(fileName) {
|
|
252
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
253
|
+
const mimeTypes = {
|
|
254
|
+
// Text
|
|
255
|
+
'.txt': 'text/plain',
|
|
256
|
+
'.md': 'text/markdown',
|
|
257
|
+
'.json': 'application/json',
|
|
258
|
+
'.xml': 'application/xml',
|
|
259
|
+
'.html': 'text/html',
|
|
260
|
+
'.css': 'text/css',
|
|
261
|
+
'.js': 'text/javascript',
|
|
262
|
+
'.jsx': 'text/javascript',
|
|
263
|
+
'.ts': 'text/typescript',
|
|
264
|
+
'.tsx': 'text/typescript',
|
|
265
|
+
'.py': 'text/x-python',
|
|
266
|
+
'.java': 'text/x-java',
|
|
267
|
+
'.cpp': 'text/x-c++',
|
|
268
|
+
'.c': 'text/x-c',
|
|
269
|
+
'.yml': 'text/yaml',
|
|
270
|
+
'.yaml': 'text/yaml',
|
|
271
|
+
|
|
272
|
+
// Images
|
|
273
|
+
'.jpg': 'image/jpeg',
|
|
274
|
+
'.jpeg': 'image/jpeg',
|
|
275
|
+
'.png': 'image/png',
|
|
276
|
+
'.gif': 'image/gif',
|
|
277
|
+
'.webp': 'image/webp',
|
|
278
|
+
'.bmp': 'image/bmp',
|
|
279
|
+
'.svg': 'image/svg+xml',
|
|
280
|
+
|
|
281
|
+
// PDF
|
|
282
|
+
'.pdf': 'application/pdf',
|
|
283
|
+
|
|
284
|
+
// Default
|
|
285
|
+
'default': 'application/octet-stream'
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
return mimeTypes[ext] || mimeTypes['default'];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export default AttachmentValidator;
|