@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.
Files changed (80) hide show
  1. package/LICENSE +267 -0
  2. package/README.md +509 -0
  3. package/bin/cli.js +117 -0
  4. package/package.json +94 -0
  5. package/scripts/install-scanners.js +236 -0
  6. package/src/analyzers/CSSAnalyzer.js +297 -0
  7. package/src/analyzers/ConfigValidator.js +690 -0
  8. package/src/analyzers/ESLintAnalyzer.js +320 -0
  9. package/src/analyzers/JavaScriptAnalyzer.js +261 -0
  10. package/src/analyzers/PrettierFormatter.js +247 -0
  11. package/src/analyzers/PythonAnalyzer.js +266 -0
  12. package/src/analyzers/SecurityAnalyzer.js +729 -0
  13. package/src/analyzers/TypeScriptAnalyzer.js +247 -0
  14. package/src/analyzers/codeCloneDetector/analyzer.js +344 -0
  15. package/src/analyzers/codeCloneDetector/detector.js +203 -0
  16. package/src/analyzers/codeCloneDetector/index.js +160 -0
  17. package/src/analyzers/codeCloneDetector/parser.js +199 -0
  18. package/src/analyzers/codeCloneDetector/reporter.js +148 -0
  19. package/src/analyzers/codeCloneDetector/scanner.js +59 -0
  20. package/src/core/agentPool.js +1474 -0
  21. package/src/core/agentScheduler.js +2147 -0
  22. package/src/core/contextManager.js +709 -0
  23. package/src/core/messageProcessor.js +732 -0
  24. package/src/core/orchestrator.js +548 -0
  25. package/src/core/stateManager.js +877 -0
  26. package/src/index.js +631 -0
  27. package/src/interfaces/cli.js +549 -0
  28. package/src/interfaces/webServer.js +2162 -0
  29. package/src/modules/fileExplorer/controller.js +280 -0
  30. package/src/modules/fileExplorer/index.js +37 -0
  31. package/src/modules/fileExplorer/middleware.js +92 -0
  32. package/src/modules/fileExplorer/routes.js +125 -0
  33. package/src/modules/fileExplorer/types.js +44 -0
  34. package/src/services/aiService.js +1232 -0
  35. package/src/services/apiKeyManager.js +164 -0
  36. package/src/services/benchmarkService.js +366 -0
  37. package/src/services/budgetService.js +539 -0
  38. package/src/services/contextInjectionService.js +247 -0
  39. package/src/services/conversationCompactionService.js +637 -0
  40. package/src/services/errorHandler.js +810 -0
  41. package/src/services/fileAttachmentService.js +544 -0
  42. package/src/services/modelRouterService.js +366 -0
  43. package/src/services/modelsService.js +322 -0
  44. package/src/services/qualityInspector.js +796 -0
  45. package/src/services/tokenCountingService.js +536 -0
  46. package/src/tools/agentCommunicationTool.js +1344 -0
  47. package/src/tools/agentDelayTool.js +485 -0
  48. package/src/tools/asyncToolManager.js +604 -0
  49. package/src/tools/baseTool.js +800 -0
  50. package/src/tools/browserTool.js +920 -0
  51. package/src/tools/cloneDetectionTool.js +621 -0
  52. package/src/tools/dependencyResolverTool.js +1215 -0
  53. package/src/tools/fileContentReplaceTool.js +875 -0
  54. package/src/tools/fileSystemTool.js +1107 -0
  55. package/src/tools/fileTreeTool.js +853 -0
  56. package/src/tools/imageTool.js +901 -0
  57. package/src/tools/importAnalyzerTool.js +1060 -0
  58. package/src/tools/jobDoneTool.js +248 -0
  59. package/src/tools/seekTool.js +956 -0
  60. package/src/tools/staticAnalysisTool.js +1778 -0
  61. package/src/tools/taskManagerTool.js +2873 -0
  62. package/src/tools/terminalTool.js +2304 -0
  63. package/src/tools/webTool.js +1430 -0
  64. package/src/types/agent.js +519 -0
  65. package/src/types/contextReference.js +972 -0
  66. package/src/types/conversation.js +730 -0
  67. package/src/types/toolCommand.js +747 -0
  68. package/src/utilities/attachmentValidator.js +292 -0
  69. package/src/utilities/configManager.js +582 -0
  70. package/src/utilities/constants.js +722 -0
  71. package/src/utilities/directoryAccessManager.js +535 -0
  72. package/src/utilities/fileProcessor.js +307 -0
  73. package/src/utilities/logger.js +436 -0
  74. package/src/utilities/tagParser.js +1246 -0
  75. package/src/utilities/toolConstants.js +317 -0
  76. package/web-ui/build/index.html +15 -0
  77. package/web-ui/build/logo.png +0 -0
  78. package/web-ui/build/logo2.png +0 -0
  79. package/web-ui/build/static/index-CjkkcnFA.js +344 -0
  80. 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;