@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.
Files changed (120) hide show
  1. package/README.md +44 -54
  2. package/bin/cli.js +1 -115
  3. package/bin/loxia-terminal-v2.js +3 -0
  4. package/bin/loxia-terminal.js +3 -0
  5. package/bin/start-with-terminal.js +3 -0
  6. package/package.json +14 -15
  7. package/scripts/install-scanners.js +1 -235
  8. package/src/analyzers/CSSAnalyzer.js +1 -297
  9. package/src/analyzers/ConfigValidator.js +1 -690
  10. package/src/analyzers/ESLintAnalyzer.js +1 -320
  11. package/src/analyzers/JavaScriptAnalyzer.js +1 -261
  12. package/src/analyzers/PrettierFormatter.js +1 -247
  13. package/src/analyzers/PythonAnalyzer.js +1 -266
  14. package/src/analyzers/SecurityAnalyzer.js +1 -729
  15. package/src/analyzers/TypeScriptAnalyzer.js +1 -247
  16. package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
  17. package/src/analyzers/codeCloneDetector/detector.js +1 -203
  18. package/src/analyzers/codeCloneDetector/index.js +1 -160
  19. package/src/analyzers/codeCloneDetector/parser.js +1 -199
  20. package/src/analyzers/codeCloneDetector/reporter.js +1 -148
  21. package/src/analyzers/codeCloneDetector/scanner.js +1 -59
  22. package/src/core/agentPool.js +1 -1474
  23. package/src/core/agentScheduler.js +1 -2147
  24. package/src/core/contextManager.js +1 -709
  25. package/src/core/messageProcessor.js +1 -732
  26. package/src/core/orchestrator.js +1 -548
  27. package/src/core/stateManager.js +1 -877
  28. package/src/index.js +1 -631
  29. package/src/interfaces/cli.js +1 -549
  30. package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
  31. package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
  32. package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
  33. package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
  34. package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
  35. package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
  36. package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
  37. package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
  38. package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
  39. package/src/interfaces/terminal/api/apiClient.js +1 -0
  40. package/src/interfaces/terminal/api/messageRouter.js +1 -0
  41. package/src/interfaces/terminal/api/session.js +1 -0
  42. package/src/interfaces/terminal/api/websocket.js +1 -0
  43. package/src/interfaces/terminal/components/AgentCreator.js +1 -0
  44. package/src/interfaces/terminal/components/AgentEditor.js +1 -0
  45. package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
  46. package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
  47. package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
  48. package/src/interfaces/terminal/components/Header.js +1 -0
  49. package/src/interfaces/terminal/components/HelpPanel.js +1 -0
  50. package/src/interfaces/terminal/components/InputBox.js +1 -0
  51. package/src/interfaces/terminal/components/Layout.js +1 -0
  52. package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
  53. package/src/interfaces/terminal/components/MessageList.js +1 -0
  54. package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
  55. package/src/interfaces/terminal/components/SearchPanel.js +1 -0
  56. package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
  57. package/src/interfaces/terminal/components/StatusBar.js +1 -0
  58. package/src/interfaces/terminal/components/TextInput.js +1 -0
  59. package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
  60. package/src/interfaces/terminal/config/constants.js +1 -0
  61. package/src/interfaces/terminal/index.js +1 -0
  62. package/src/interfaces/terminal/state/useAgentControl.js +1 -0
  63. package/src/interfaces/terminal/state/useAgents.js +1 -0
  64. package/src/interfaces/terminal/state/useConnection.js +1 -0
  65. package/src/interfaces/terminal/state/useMessages.js +1 -0
  66. package/src/interfaces/terminal/state/useTools.js +1 -0
  67. package/src/interfaces/terminal/utils/debugLogger.js +1 -0
  68. package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
  69. package/src/interfaces/terminal/utils/theme.js +1 -0
  70. package/src/interfaces/webServer.js +1 -2162
  71. package/src/modules/fileExplorer/controller.js +1 -280
  72. package/src/modules/fileExplorer/index.js +1 -37
  73. package/src/modules/fileExplorer/middleware.js +1 -92
  74. package/src/modules/fileExplorer/routes.js +1 -125
  75. package/src/modules/fileExplorer/types.js +1 -44
  76. package/src/services/aiService.js +1 -1232
  77. package/src/services/apiKeyManager.js +1 -164
  78. package/src/services/benchmarkService.js +1 -366
  79. package/src/services/budgetService.js +1 -539
  80. package/src/services/contextInjectionService.js +1 -247
  81. package/src/services/conversationCompactionService.js +1 -637
  82. package/src/services/errorHandler.js +1 -810
  83. package/src/services/fileAttachmentService.js +1 -544
  84. package/src/services/modelRouterService.js +1 -366
  85. package/src/services/modelsService.js +1 -322
  86. package/src/services/qualityInspector.js +1 -796
  87. package/src/services/tokenCountingService.js +1 -536
  88. package/src/tools/agentCommunicationTool.js +1 -1344
  89. package/src/tools/agentDelayTool.js +1 -485
  90. package/src/tools/asyncToolManager.js +1 -604
  91. package/src/tools/baseTool.js +1 -800
  92. package/src/tools/browserTool.js +1 -920
  93. package/src/tools/cloneDetectionTool.js +1 -621
  94. package/src/tools/dependencyResolverTool.js +1 -1215
  95. package/src/tools/fileContentReplaceTool.js +1 -875
  96. package/src/tools/fileSystemTool.js +1 -1107
  97. package/src/tools/fileTreeTool.js +1 -853
  98. package/src/tools/imageTool.js +1 -901
  99. package/src/tools/importAnalyzerTool.js +1 -1060
  100. package/src/tools/jobDoneTool.js +1 -248
  101. package/src/tools/seekTool.js +1 -956
  102. package/src/tools/staticAnalysisTool.js +1 -1778
  103. package/src/tools/taskManagerTool.js +1 -2873
  104. package/src/tools/terminalTool.js +1 -2304
  105. package/src/tools/webTool.js +1 -1430
  106. package/src/types/agent.js +1 -519
  107. package/src/types/contextReference.js +1 -972
  108. package/src/types/conversation.js +1 -730
  109. package/src/types/toolCommand.js +1 -747
  110. package/src/utilities/attachmentValidator.js +1 -292
  111. package/src/utilities/configManager.js +1 -582
  112. package/src/utilities/constants.js +1 -722
  113. package/src/utilities/directoryAccessManager.js +1 -535
  114. package/src/utilities/fileProcessor.js +1 -307
  115. package/src/utilities/logger.js +1 -436
  116. package/src/utilities/tagParser.js +1 -1246
  117. package/src/utilities/toolConstants.js +1 -317
  118. package/web-ui/build/index.html +2 -2
  119. package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
  120. package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
@@ -1,1107 +1 @@
1
- /**
2
- * FileSystemTool - Handle file system operations safely
3
- *
4
- * Purpose:
5
- * - Read, write, and manipulate files
6
- * - Directory operations
7
- * - File metadata and permissions
8
- * - Safe file operations with validation
9
- */
10
-
11
- import { BaseTool } from './baseTool.js';
12
- import TagParser from '../utilities/tagParser.js';
13
- import DirectoryAccessManager from '../utilities/directoryAccessManager.js';
14
- import fs from 'fs/promises';
15
- import path from 'path';
16
- import crypto from 'crypto';
17
-
18
- import {
19
- TOOL_STATUS,
20
- FILE_EXTENSIONS,
21
- SYSTEM_DEFAULTS
22
- } from '../utilities/constants.js';
23
-
24
- class FileSystemTool extends BaseTool {
25
- constructor(config = {}, logger = null) {
26
- super(config, logger);
27
-
28
- // Tool metadata
29
- this.requiresProject = true;
30
- this.isAsync = false; // Most file operations are quick
31
- this.timeout = config.timeout || 30000; // 30 seconds
32
- this.maxConcurrentOperations = config.maxConcurrentOperations || 5;
33
-
34
- // Security settings
35
- this.maxFileSize = config.maxFileSize || SYSTEM_DEFAULTS.MAX_FILE_SIZE;
36
- this.allowedExtensions = config.allowedExtensions || null; // null = all allowed
37
- this.blockedExtensions = config.blockedExtensions || ['.exe', '.bat', '.cmd', '.scr', '.com'];
38
- this.allowedDirectories = config.allowedDirectories || null; // null = project dir only
39
-
40
- // File operation history
41
- this.operationHistory = [];
42
-
43
- // Directory access manager
44
- this.directoryAccessManager = new DirectoryAccessManager(config, logger);
45
- }
46
-
47
- /**
48
- * Get tool description for LLM consumption
49
- * @returns {string} Tool description
50
- */
51
- getDescription() {
52
- return `
53
- File System Tool: Perform file and directory operations safely within the project scope.
54
-
55
- CRITICAL: Both XML and JSON formats are fully supported. When using XML format, commands are automatically converted to the appropriate structure internally - you don't need to manually wrap them in an actions array.
56
-
57
- USAGE - TWO FORMATS SUPPORTED:
58
-
59
- FORMAT 1 - XML STYLE (Recommended):
60
- [tool id="filesystem"]
61
- <read file-path="src/index.js" />
62
- <write output-path="src/components/Button.js">
63
- const Button = () => {
64
- return <button>Click me</button>;
65
- };
66
- export default Button;
67
- </write>
68
- [/tool]
69
-
70
- FORMAT 2 - JSON STYLE:
71
- \`\`\`json
72
- {
73
- "toolId": "filesystem",
74
- "actions": [
75
- {
76
- "type": "read",
77
- "filePath": "src/index.js"
78
- },
79
- {
80
- "type": "write",
81
- "outputPath": "src/components/Button.js",
82
- "content": "const Button = () => { return <button>Click me</button>; };"
83
- }
84
- ]
85
- }
86
- \`\`\`
87
-
88
- IMPORTANT:
89
- - Use either format consistently. Do NOT mix formats in a single command.
90
- - XML format is recommended for single operations and better readability
91
- - JSON format is recommended for complex multi-action operations
92
- - Both formats work equally well and produce the same results
93
-
94
- SUPPORTED ACTIONS:
95
- - read: Read file contents
96
- - write: Write content to file
97
- - append: Append content to existing file
98
- - delete: Delete a file
99
- - copy: Copy file from source to destination
100
- - move: Move/rename file
101
- - create-dir: Create directory
102
- - list: List directory contents
103
- - exists: Check if file/directory exists
104
- - stats: Get file/directory metadata
105
-
106
- PARAMETERS:
107
- - file-path: Path to file to read
108
- - output-path: Path where to write/create file
109
- - source-path: Source path for copy/move operations
110
- - dest-path: Destination path for copy/move operations
111
- - directory: Directory path for directory operations
112
- - content: Content to write/append
113
- - encoding: File encoding (default: utf8)
114
- - create-dirs: Create parent directories if they don't exist (true/false)
115
-
116
- EXAMPLES:
117
-
118
- SIMPLE FILE CREATION (XML format - recommended):
119
- [tool id="filesystem"]
120
- <write output-path="hello.c">
121
- #include <stdio.h>
122
-
123
- int main() {
124
- printf("Hello, World!\\n");
125
- return 0;
126
- }
127
- </write>
128
- [/tool]
129
-
130
- READING FILES (XML format):
131
- [tool id="filesystem"]
132
- <read file-path="package.json" />
133
- [/tool]
134
-
135
- MULTIPLE OPERATIONS (JSON format recommended):
136
- \`\`\`json
137
- {
138
- "toolId": "filesystem",
139
- "actions": [
140
- {
141
- "type": "read",
142
- "filePath": "src/index.js"
143
- },
144
- {
145
- "type": "write",
146
- "outputPath": "src/backup.js",
147
- "content": "// Backup file\\nconsole.log('backup');"
148
- }
149
- ]
150
- }
151
- \`\`\`
152
-
153
- OTHER XML EXAMPLES:
154
- [tool id="filesystem"]
155
- <copy source-path="template.js" dest-path="src/component.js" />
156
- <create-dir directory="src/components/ui" />
157
- <list directory="src" />
158
- [/tool]
159
-
160
- SECURITY:
161
- - Operations restricted to project directory
162
- - File size limits enforced (max ${Math.round(this.maxFileSize / 1024 / 1024)}MB)
163
- - Dangerous file types blocked
164
- - Path traversal protection
165
- - Backup created for destructive operations
166
-
167
- ENCODING SUPPORT:
168
- - utf8 (default)
169
- - ascii
170
- - base64
171
- - binary
172
- - hex
173
- `;
174
- }
175
-
176
- /**
177
- * Parse parameters from tool command content
178
- * @param {string} content - Raw tool command content
179
- * @returns {Object} Parsed parameters
180
- */
181
- parseParameters(content) {
182
- try {
183
- const params = {};
184
- const actions = [];
185
-
186
- this.logger?.debug('FileSystem tool parsing parameters', {
187
- contentLength: content.length,
188
- contentPreview: content.substring(0, 200)
189
- });
190
-
191
- // Extract self-closing tags (read, delete, copy, etc.)
192
- const selfClosingTags = [
193
- 'read', 'delete', 'copy', 'move', 'create-dir',
194
- 'list', 'exists', 'stats', 'append'
195
- ];
196
-
197
- for (const tagName of selfClosingTags) {
198
- const tags = TagParser.extractTagsWithAttributes(content, tagName);
199
- for (const tag of tags) {
200
- const action = {
201
- type: tagName,
202
- ...tag.attributes
203
- };
204
-
205
- // Normalize common attribute names
206
- if (action['file-path']) {
207
- action.filePath = action['file-path'];
208
- delete action['file-path'];
209
- }
210
- if (action['output-path']) {
211
- action.outputPath = action['output-path'];
212
- delete action['output-path'];
213
- }
214
- if (action['source-path']) {
215
- action.sourcePath = action['source-path'];
216
- delete action['source-path'];
217
- }
218
- if (action['dest-path']) {
219
- action.destPath = action['dest-path'];
220
- delete action['dest-path'];
221
- }
222
- if (action['create-dirs']) {
223
- action.createDirs = action['create-dirs'] === 'true';
224
- delete action['create-dirs'];
225
- }
226
-
227
- actions.push(action);
228
- }
229
- }
230
-
231
- // Extract write and append tags with content
232
- const writeMatches = content.matchAll(/<write\s+([^>]*)>(.*?)<\/write>/gs);
233
- for (const match of writeMatches) {
234
- const parser = new TagParser();
235
- const attributes = parser.parseAttributes(match[1]);
236
- const writeContent = match[2].trim();
237
-
238
- const action = {
239
- type: 'write',
240
- content: writeContent,
241
- ...attributes
242
- };
243
-
244
- // Normalize attribute names
245
- if (action['output-path']) {
246
- action.outputPath = action['output-path'];
247
- delete action['output-path'];
248
- }
249
- if (action['create-dirs']) {
250
- action.createDirs = action['create-dirs'] === 'true';
251
- delete action['create-dirs'];
252
- }
253
-
254
- actions.push(action);
255
- }
256
-
257
- const appendMatches = content.matchAll(/<append\s+([^>]*)>(.*?)<\/append>/gs);
258
- for (const match of appendMatches) {
259
- const parser = new TagParser();
260
- const attributes = parser.parseAttributes(match[1]);
261
- const appendContent = match[2].trim();
262
-
263
- const action = {
264
- type: 'append',
265
- content: appendContent,
266
- ...attributes
267
- };
268
-
269
- // Normalize attribute names
270
- if (action['file-path']) {
271
- action.filePath = action['file-path'];
272
- delete action['file-path'];
273
- }
274
-
275
- actions.push(action);
276
- }
277
-
278
- params.actions = actions;
279
- params.rawContent = content.trim();
280
-
281
- this.logger?.debug('Parsed FileSystem tool parameters', {
282
- totalActions: actions.length,
283
- actionTypes: actions.map(a => a.type),
284
- actions: actions.map(a => ({
285
- type: a.type,
286
- filePath: a.filePath,
287
- outputPath: a.outputPath,
288
- hasContent: !!a.content
289
- }))
290
- });
291
-
292
- return params;
293
-
294
- } catch (error) {
295
- throw new Error(`Failed to parse filesystem parameters: ${error.message}`);
296
- }
297
- }
298
-
299
- /**
300
- * Get required parameters
301
- * @returns {Array<string>} Array of required parameter names
302
- */
303
- getRequiredParameters() {
304
- return ['actions'];
305
- }
306
-
307
- /**
308
- * Custom parameter validation
309
- * @param {Object} params - Parameters to validate
310
- * @returns {Object} Validation result
311
- */
312
- customValidateParameters(params) {
313
- const errors = [];
314
-
315
- if (!params.actions || !Array.isArray(params.actions) || params.actions.length === 0) {
316
- errors.push('At least one action is required');
317
- } else {
318
- // Validate each action
319
- for (const [index, action] of params.actions.entries()) {
320
- if (!action.type) {
321
- errors.push(`Action ${index + 1}: type is required`);
322
- continue;
323
- }
324
-
325
- switch (action.type) {
326
- case 'read':
327
- case 'delete':
328
- case 'exists':
329
- case 'stats':
330
- if (!action.filePath) {
331
- errors.push(`Action ${index + 1}: file-path is required for ${action.type}`);
332
- }
333
- break;
334
-
335
- case 'write':
336
- if (!action.outputPath) {
337
- errors.push(`Action ${index + 1}: output-path is required for write`);
338
- }
339
- if (!action.content && action.content !== '') {
340
- errors.push(`Action ${index + 1}: content is required for write`);
341
- }
342
- break;
343
-
344
- case 'append':
345
- if (!action.filePath) {
346
- errors.push(`Action ${index + 1}: file-path is required for append`);
347
- }
348
- if (!action.content && action.content !== '') {
349
- errors.push(`Action ${index + 1}: content is required for append`);
350
- }
351
- break;
352
-
353
- case 'copy':
354
- case 'move':
355
- if (!action.sourcePath) {
356
- errors.push(`Action ${index + 1}: source-path is required for ${action.type}`);
357
- }
358
- if (!action.destPath) {
359
- errors.push(`Action ${index + 1}: dest-path is required for ${action.type}`);
360
- }
361
- break;
362
-
363
- case 'create-dir':
364
- case 'list':
365
- if (!action.directory) {
366
- errors.push(`Action ${index + 1}: directory is required for ${action.type}`);
367
- }
368
- break;
369
-
370
- default:
371
- errors.push(`Action ${index + 1}: unknown action type: ${action.type}`);
372
- }
373
-
374
- // Validate file extensions if specified
375
- if (action.filePath && !this.isAllowedFileExtension(action.filePath)) {
376
- errors.push(`Action ${index + 1}: file type not allowed: ${path.extname(action.filePath)}`);
377
- }
378
- if (action.outputPath && !this.isAllowedFileExtension(action.outputPath)) {
379
- errors.push(`Action ${index + 1}: file type not allowed: ${path.extname(action.outputPath)}`);
380
- }
381
- }
382
- }
383
-
384
- return {
385
- valid: errors.length === 0,
386
- errors
387
- };
388
- }
389
-
390
- /**
391
- * Execute tool with parsed parameters
392
- * @param {Object} params - Parsed parameters
393
- * @param {Object} context - Execution context
394
- * @returns {Promise<Object>} Execution result
395
- */
396
- async execute(params, context) {
397
- // Validate params structure
398
- if (!params || typeof params !== 'object') {
399
- throw new Error('Invalid parameters: params must be an object');
400
- }
401
-
402
- const { actions } = params;
403
-
404
- // Validate actions array
405
- if (!actions) {
406
- throw new Error('Invalid parameters: actions is required. Received params: ' + JSON.stringify(Object.keys(params)));
407
- }
408
-
409
- if (!Array.isArray(actions)) {
410
- throw new Error('Invalid parameters: actions must be an array. Received type: ' + typeof actions);
411
- }
412
-
413
- if (actions.length === 0) {
414
- throw new Error('Invalid parameters: actions array is empty');
415
- }
416
-
417
- const { projectDir, agentId, directoryAccess } = context;
418
-
419
- // Get directory access configuration from agent or create default
420
- const accessConfig = directoryAccess ||
421
- this.directoryAccessManager.createDirectoryAccess({
422
- workingDirectory: projectDir || process.cwd(),
423
- writeEnabledDirectories: [projectDir || process.cwd()],
424
- restrictToProject: true
425
- });
426
-
427
- // IMPORTANT: If the agent has directoryAccess configured, use its workingDirectory
428
- // This ensures UI-configured project directories are respected
429
- if (directoryAccess && directoryAccess.workingDirectory) {
430
- // Agent has explicitly configured working directory from UI - use it
431
- console.log('FileSystem DEBUG: Using agent configured working directory:', directoryAccess.workingDirectory);
432
- console.log('FileSystem DEBUG: Full directoryAccess object:', JSON.stringify(directoryAccess, null, 2));
433
- } else {
434
- // Using fallback to projectDir or process.cwd()
435
- console.log('FileSystem DEBUG: Using fallback working directory:', projectDir || process.cwd());
436
- console.log('FileSystem DEBUG: directoryAccess is:', directoryAccess);
437
- console.log('FileSystem DEBUG: projectDir is:', projectDir);
438
- }
439
-
440
- const results = [];
441
-
442
- for (const action of actions) {
443
- try {
444
- let result;
445
-
446
- switch (action.type) {
447
- case 'read':
448
- result = await this.readFile(action.filePath, accessConfig, action.encoding);
449
- break;
450
-
451
- case 'write':
452
- result = await this.writeFile(action.outputPath, action.content, accessConfig, {
453
- encoding: action.encoding,
454
- createDirs: action.createDirs
455
- });
456
- break;
457
-
458
- case 'append':
459
- result = await this.appendToFile(action.filePath, action.content, accessConfig, action.encoding);
460
- break;
461
-
462
- case 'delete':
463
- result = await this.deleteFile(action.filePath, accessConfig);
464
- break;
465
-
466
- case 'copy':
467
- result = await this.copyFile(action.sourcePath, action.destPath, accessConfig);
468
- break;
469
-
470
- case 'move':
471
- result = await this.moveFile(action.sourcePath, action.destPath, accessConfig);
472
- break;
473
-
474
- case 'create-dir':
475
- result = await this.createDirectory(action.directory, accessConfig);
476
- break;
477
-
478
- case 'list':
479
- result = await this.listDirectory(action.directory, accessConfig);
480
- break;
481
-
482
- case 'exists':
483
- result = await this.checkExists(action.filePath, accessConfig);
484
- break;
485
-
486
- case 'stats':
487
- result = await this.getFileStats(action.filePath, accessConfig);
488
- break;
489
-
490
- default:
491
- throw new Error(`Unknown action type: ${action.type}`);
492
- }
493
-
494
- results.push(result);
495
- this.addToHistory(action, result, context.agentId);
496
-
497
- } catch (error) {
498
- const errorResult = {
499
- success: false,
500
- action: action.type,
501
- error: error.message,
502
- filePath: action.filePath || action.outputPath || action.directory
503
- };
504
-
505
- results.push(errorResult);
506
- this.addToHistory(action, errorResult, context.agentId);
507
- }
508
- }
509
-
510
- return {
511
- success: true,
512
- actions: results,
513
- executedActions: actions.length,
514
- toolUsed: 'filesys'
515
- };
516
- }
517
-
518
- /**
519
- * Read file contents
520
- * @private
521
- */
522
- async readFile(filePath, accessConfig, encoding = 'utf8') {
523
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
524
- const fullPath = this.resolvePath(filePath, workingDir);
525
-
526
- // Validate read access using DirectoryAccessManager
527
- const accessResult = this.directoryAccessManager.validateReadAccess(fullPath, accessConfig);
528
- if (!accessResult.allowed) {
529
- throw new Error(`Read access denied: ${accessResult.reason} (${accessResult.path})`);
530
- }
531
-
532
- try {
533
- const stats = await fs.stat(fullPath);
534
-
535
- if (stats.size > this.maxFileSize) {
536
- throw new Error(`File too large: ${stats.size} bytes (max ${this.maxFileSize})`);
537
- }
538
-
539
- const content = await fs.readFile(fullPath, encoding);
540
-
541
- return {
542
- success: true,
543
- action: 'read',
544
- filePath: this.directoryAccessManager.createRelativePath(fullPath, accessConfig),
545
- content,
546
- size: stats.size,
547
- encoding,
548
- lastModified: stats.mtime.toISOString(),
549
- message: `Read ${stats.size} bytes from ${filePath}`
550
- };
551
-
552
- } catch (error) {
553
- throw new Error(`Failed to read file ${filePath}: ${error.message}`);
554
- }
555
- }
556
-
557
- /**
558
- * Write content to file
559
- * @private
560
- */
561
- async writeFile(outputPath, content, accessConfig, options = {}) {
562
- const { encoding = 'utf8', createDirs = true } = options;
563
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
564
- const fullPath = this.resolvePath(outputPath, workingDir);
565
-
566
- // Validate write access using DirectoryAccessManager
567
- const accessResult = this.directoryAccessManager.validateWriteAccess(fullPath, accessConfig);
568
- if (!accessResult.allowed) {
569
- throw new Error(`Write access denied: ${accessResult.reason} (${accessResult.path})`);
570
- }
571
-
572
- try {
573
- // Check content size
574
- const contentSize = Buffer.byteLength(content, encoding);
575
- if (contentSize > this.maxFileSize) {
576
- throw new Error(`Content too large: ${contentSize} bytes (max ${this.maxFileSize})`);
577
- }
578
-
579
- // Create parent directories if requested
580
- if (createDirs) {
581
- const dirPath = path.dirname(fullPath);
582
- await fs.mkdir(dirPath, { recursive: true });
583
- }
584
-
585
- // Create backup if file exists
586
- let backupPath = null;
587
- try {
588
- await fs.access(fullPath);
589
- backupPath = `${fullPath}.backup-${Date.now()}`;
590
- await fs.copyFile(fullPath, backupPath);
591
- } catch {
592
- // File doesn't exist, no backup needed
593
- }
594
-
595
- await fs.writeFile(fullPath, content, encoding);
596
-
597
- const stats = await fs.stat(fullPath);
598
-
599
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
600
-
601
- return {
602
- success: true,
603
- action: 'write',
604
- outputPath: relativePath,
605
- fullPath: fullPath,
606
- size: stats.size,
607
- encoding,
608
- backupPath: backupPath ? this.directoryAccessManager.createRelativePath(backupPath, accessConfig) : null,
609
- backupFullPath: backupPath || null,
610
- message: `Wrote ${stats.size} bytes to ${fullPath}`
611
- };
612
-
613
- } catch (error) {
614
- throw new Error(`Failed to write file ${fullPath}: ${error.message}`);
615
- }
616
- }
617
-
618
- /**
619
- * Append content to file
620
- * @private
621
- */
622
- async appendToFile(filePath, content, accessConfig, encoding = 'utf8') {
623
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
624
- const fullPath = this.resolvePath(filePath, workingDir);
625
-
626
- // Validate write access using DirectoryAccessManager
627
- const accessResult = this.directoryAccessManager.validateWriteAccess(fullPath, accessConfig);
628
- if (!accessResult.allowed) {
629
- throw new Error(`Write access denied: ${accessResult.reason} (${accessResult.path})`);
630
- }
631
-
632
- try {
633
- // Check if file exists and get current size
634
- let currentSize = 0;
635
- try {
636
- const stats = await fs.stat(fullPath);
637
- currentSize = stats.size;
638
- } catch {
639
- // File doesn't exist, will be created
640
- }
641
-
642
- const contentSize = Buffer.byteLength(content, encoding);
643
- if (currentSize + contentSize > this.maxFileSize) {
644
- throw new Error(`File would become too large: ${currentSize + contentSize} bytes (max ${this.maxFileSize})`);
645
- }
646
-
647
- await fs.appendFile(fullPath, content, encoding);
648
-
649
- const stats = await fs.stat(fullPath);
650
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
651
-
652
- return {
653
- success: true,
654
- action: 'append',
655
- filePath: relativePath,
656
- fullPath: fullPath,
657
- appendedBytes: contentSize,
658
- totalSize: stats.size,
659
- encoding,
660
- message: `Appended ${contentSize} bytes to ${fullPath}`
661
- };
662
-
663
- } catch (error) {
664
- throw new Error(`Failed to append to file ${fullPath}: ${error.message}`);
665
- }
666
- }
667
-
668
- /**
669
- * Delete file
670
- * @private
671
- */
672
- async deleteFile(filePath, accessConfig) {
673
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
674
- const fullPath = this.resolvePath(filePath, workingDir);
675
-
676
- // Validate write access for deletion
677
- const accessResult = this.directoryAccessManager.validateWriteAccess(fullPath, accessConfig);
678
- if (!accessResult.allowed) {
679
- throw new Error(`Delete access denied: ${accessResult.reason} (${accessResult.path})`);
680
- }
681
-
682
- try {
683
- const stats = await fs.stat(fullPath);
684
-
685
- // Create backup before deletion
686
- const backupPath = `${fullPath}.deleted-backup-${Date.now()}`;
687
- await fs.copyFile(fullPath, backupPath);
688
-
689
- await fs.unlink(fullPath);
690
-
691
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
692
- const backupRelativePath = this.directoryAccessManager.createRelativePath(backupPath, accessConfig);
693
-
694
- return {
695
- success: true,
696
- action: 'delete',
697
- filePath: relativePath,
698
- fullPath: fullPath,
699
- size: stats.size,
700
- backupPath: backupRelativePath,
701
- backupFullPath: backupPath,
702
- message: `Deleted ${fullPath} (backup created)`
703
- };
704
-
705
- } catch (error) {
706
- throw new Error(`Failed to delete file ${fullPath}: ${error.message}`);
707
- }
708
- }
709
-
710
- /**
711
- * Copy file
712
- * @private
713
- */
714
- async copyFile(sourcePath, destPath, accessConfig) {
715
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
716
- const fullSourcePath = this.resolvePath(sourcePath, workingDir);
717
- const fullDestPath = this.resolvePath(destPath, workingDir);
718
-
719
- // Validate read access for source
720
- const sourceAccessResult = this.directoryAccessManager.validateReadAccess(fullSourcePath, accessConfig);
721
- if (!sourceAccessResult.allowed) {
722
- throw new Error(`Source read access denied: ${sourceAccessResult.reason} (${sourceAccessResult.path})`);
723
- }
724
-
725
- // Validate write access for destination
726
- const destAccessResult = this.directoryAccessManager.validateWriteAccess(fullDestPath, accessConfig);
727
- if (!destAccessResult.allowed) {
728
- throw new Error(`Destination write access denied: ${destAccessResult.reason} (${destAccessResult.path})`);
729
- }
730
-
731
- try {
732
- const sourceStats = await fs.stat(fullSourcePath);
733
-
734
- if (sourceStats.size > this.maxFileSize) {
735
- throw new Error(`Source file too large: ${sourceStats.size} bytes`);
736
- }
737
-
738
- // Create destination directory if needed
739
- const destDir = path.dirname(fullDestPath);
740
- await fs.mkdir(destDir, { recursive: true });
741
-
742
- await fs.copyFile(fullSourcePath, fullDestPath);
743
-
744
- const sourceRelativePath = this.directoryAccessManager.createRelativePath(fullSourcePath, accessConfig);
745
- const destRelativePath = this.directoryAccessManager.createRelativePath(fullDestPath, accessConfig);
746
-
747
- return {
748
- success: true,
749
- action: 'copy',
750
- sourcePath: sourceRelativePath,
751
- destPath: destRelativePath,
752
- sourceFullPath: fullSourcePath,
753
- destFullPath: fullDestPath,
754
- size: sourceStats.size,
755
- message: `Copied ${fullSourcePath} to ${fullDestPath}`
756
- };
757
-
758
- } catch (error) {
759
- throw new Error(`Failed to copy ${fullSourcePath} to ${fullDestPath}: ${error.message}`);
760
- }
761
- }
762
-
763
- /**
764
- * Move/rename file
765
- * @private
766
- */
767
- async moveFile(sourcePath, destPath, accessConfig) {
768
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
769
- const fullSourcePath = this.resolvePath(sourcePath, workingDir);
770
- const fullDestPath = this.resolvePath(destPath, workingDir);
771
-
772
- // Validate read access for source
773
- const readResult = this.directoryAccessManager.validateReadAccess(fullSourcePath, accessConfig);
774
- if (!readResult.allowed) {
775
- throw new Error(`Read access denied for source: ${readResult.reason} (${readResult.path})`);
776
- }
777
-
778
- // Validate write access for destination
779
- const writeResult = this.directoryAccessManager.validateWriteAccess(fullDestPath, accessConfig);
780
- if (!writeResult.allowed) {
781
- throw new Error(`Write access denied for destination: ${writeResult.reason} (${writeResult.path})`);
782
- }
783
-
784
- try {
785
- const sourceStats = await fs.stat(fullSourcePath);
786
-
787
- // Create destination directory if needed
788
- const destDir = path.dirname(fullDestPath);
789
- await fs.mkdir(destDir, { recursive: true });
790
-
791
- await fs.rename(fullSourcePath, fullDestPath);
792
-
793
- const relativeSource = this.directoryAccessManager.createRelativePath(fullSourcePath, accessConfig);
794
- const relativeDest = this.directoryAccessManager.createRelativePath(fullDestPath, accessConfig);
795
-
796
- return {
797
- success: true,
798
- action: 'move',
799
- sourcePath: relativeSource,
800
- destPath: relativeDest,
801
- fullSourcePath: fullSourcePath,
802
- fullDestPath: fullDestPath,
803
- size: sourceStats.size,
804
- message: `Moved ${sourcePath} to ${destPath}`
805
- };
806
-
807
- } catch (error) {
808
- throw new Error(`Failed to move ${sourcePath} to ${destPath}: ${error.message}`);
809
- }
810
- }
811
-
812
- /**
813
- * Create directory
814
- * @private
815
- */
816
- async createDirectory(directory, accessConfig) {
817
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
818
- const fullPath = this.resolvePath(directory, workingDir);
819
-
820
- // Validate write access using DirectoryAccessManager
821
- const accessResult = this.directoryAccessManager.validateWriteAccess(fullPath, accessConfig);
822
- if (!accessResult.allowed) {
823
- throw new Error(`Write access denied: ${accessResult.reason} (${accessResult.path})`);
824
- }
825
-
826
- try {
827
- await fs.mkdir(fullPath, { recursive: true });
828
-
829
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
830
-
831
- return {
832
- success: true,
833
- action: 'create-dir',
834
- directory: relativePath,
835
- fullPath: fullPath,
836
- message: `Created directory ${directory}`
837
- };
838
-
839
- } catch (error) {
840
- throw new Error(`Failed to create directory ${directory}: ${error.message}`);
841
- }
842
- }
843
-
844
- /**
845
- * List directory contents
846
- * @private
847
- */
848
- async listDirectory(directory, accessConfig) {
849
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
850
- const fullPath = this.resolvePath(directory, workingDir);
851
-
852
- // Validate read access using DirectoryAccessManager
853
- const accessResult = this.directoryAccessManager.validateReadAccess(fullPath, accessConfig);
854
- if (!accessResult.allowed) {
855
- throw new Error(`Read access denied: ${accessResult.reason} (${accessResult.path})`);
856
- }
857
-
858
- try {
859
- const entries = await fs.readdir(fullPath, { withFileTypes: true });
860
-
861
- const contents = [];
862
- for (const entry of entries) {
863
- const entryPath = path.join(fullPath, entry.name);
864
- const stats = await fs.stat(entryPath);
865
-
866
- contents.push({
867
- name: entry.name,
868
- type: entry.isDirectory() ? 'directory' : 'file',
869
- size: entry.isFile() ? stats.size : undefined,
870
- lastModified: stats.mtime.toISOString(),
871
- permissions: stats.mode,
872
- isSymlink: entry.isSymbolicLink()
873
- });
874
- }
875
-
876
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
877
-
878
- return {
879
- success: true,
880
- action: 'list',
881
- directory: relativePath,
882
- fullPath: fullPath,
883
- contents,
884
- totalItems: contents.length,
885
- directories: contents.filter(item => item.type === 'directory').length,
886
- files: contents.filter(item => item.type === 'file').length,
887
- message: `Listed ${contents.length} items in ${directory}`
888
- };
889
-
890
- } catch (error) {
891
- throw new Error(`Failed to list directory ${directory}: ${error.message}`);
892
- }
893
- }
894
-
895
- /**
896
- * Check if file/directory exists
897
- * @private
898
- */
899
- async checkExists(filePath, accessConfig) {
900
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
901
- const fullPath = this.resolvePath(filePath, workingDir);
902
-
903
- // Validate read access
904
- const accessResult = this.directoryAccessManager.validateReadAccess(fullPath, accessConfig);
905
- if (!accessResult.allowed) {
906
- throw new Error(`Read access denied: ${accessResult.reason} (${accessResult.path})`);
907
- }
908
-
909
- try {
910
- const stats = await fs.stat(fullPath);
911
-
912
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
913
-
914
- return {
915
- success: true,
916
- action: 'exists',
917
- filePath: relativePath,
918
- fullPath: fullPath,
919
- exists: true,
920
- type: stats.isDirectory() ? 'directory' : 'file',
921
- message: `${filePath} exists as ${stats.isDirectory() ? 'directory' : 'file'}`
922
- };
923
-
924
- } catch (error) {
925
- if (error.code === 'ENOENT') {
926
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
927
- return {
928
- success: true,
929
- action: 'exists',
930
- filePath: relativePath,
931
- fullPath: fullPath,
932
- exists: false,
933
- message: `${filePath} does not exist`
934
- };
935
- }
936
-
937
- throw new Error(`Failed to check existence of ${filePath}: ${error.message}`);
938
- }
939
- }
940
-
941
- /**
942
- * Get file statistics
943
- * @private
944
- */
945
- async getFileStats(filePath, accessConfig) {
946
- const workingDir = this.directoryAccessManager.getWorkingDirectory(accessConfig);
947
- const fullPath = this.resolvePath(filePath, workingDir);
948
-
949
- // Validate read access
950
- const accessResult = this.directoryAccessManager.validateReadAccess(fullPath, accessConfig);
951
- if (!accessResult.allowed) {
952
- throw new Error(`Read access denied: ${accessResult.reason} (${accessResult.path})`);
953
- }
954
-
955
- try {
956
- const stats = await fs.stat(fullPath);
957
-
958
- const relativePath = this.directoryAccessManager.createRelativePath(fullPath, accessConfig);
959
-
960
- return {
961
- success: true,
962
- action: 'stats',
963
- filePath: relativePath,
964
- fullPath: fullPath,
965
- stats: {
966
- size: stats.size,
967
- type: stats.isDirectory() ? 'directory' : 'file',
968
- lastModified: stats.mtime.toISOString(),
969
- lastAccessed: stats.atime.toISOString(),
970
- created: stats.birthtime.toISOString(),
971
- permissions: stats.mode,
972
- isSymlink: stats.isSymbolicLink()
973
- },
974
- message: `Retrieved stats for ${filePath}`
975
- };
976
-
977
- } catch (error) {
978
- throw new Error(`Failed to get stats for ${filePath}: ${error.message}`);
979
- }
980
- }
981
-
982
- /**
983
- * Resolve file path safely (legacy method for compatibility)
984
- * @private
985
- */
986
- resolvePath(filePath, workingDir) {
987
- if (path.isAbsolute(filePath)) {
988
- return path.normalize(filePath);
989
- }
990
- return path.resolve(workingDir, filePath);
991
- }
992
-
993
- /**
994
- * Validate path access using DirectoryAccessManager
995
- * @private
996
- */
997
- validatePathAccess(fullPath, accessConfig, operation = 'read') {
998
- const accessResult = operation === 'write'
999
- ? this.directoryAccessManager.validateWriteAccess(fullPath, accessConfig)
1000
- : this.directoryAccessManager.validateReadAccess(fullPath, accessConfig);
1001
-
1002
- if (!accessResult.allowed) {
1003
- throw new Error(`${operation} access denied: ${accessResult.reason} (${accessResult.path})`);
1004
- }
1005
-
1006
- return accessResult;
1007
- }
1008
-
1009
- /**
1010
- * Check if file extension is allowed
1011
- * @private
1012
- */
1013
- isAllowedFileExtension(filePath) {
1014
- const ext = path.extname(filePath).toLowerCase();
1015
-
1016
- if (this.blockedExtensions.includes(ext)) {
1017
- return false;
1018
- }
1019
-
1020
- if (this.allowedExtensions && !this.allowedExtensions.includes(ext)) {
1021
- return false;
1022
- }
1023
-
1024
- return true;
1025
- }
1026
-
1027
- /**
1028
- * Add operation to history
1029
- * @private
1030
- */
1031
- addToHistory(action, result, agentId) {
1032
- const historyEntry = {
1033
- timestamp: new Date().toISOString(),
1034
- agentId,
1035
- action: action.type,
1036
- filePath: action.filePath || action.outputPath || action.directory,
1037
- success: result.success,
1038
- size: result.size
1039
- };
1040
-
1041
- this.operationHistory.push(historyEntry);
1042
-
1043
- // Keep only last 200 entries
1044
- if (this.operationHistory.length > 200) {
1045
- this.operationHistory = this.operationHistory.slice(-200);
1046
- }
1047
- }
1048
-
1049
- /**
1050
- * Get supported actions for this tool
1051
- * @returns {Array<string>} Array of supported action names
1052
- */
1053
- getSupportedActions() {
1054
- return [
1055
- 'read', 'write', 'append', 'delete', 'copy', 'move',
1056
- 'create-dir', 'list', 'exists', 'stats'
1057
- ];
1058
- }
1059
-
1060
- /**
1061
- * Get parameter schema for validation
1062
- * @returns {Object} Parameter schema
1063
- */
1064
- getParameterSchema() {
1065
- return {
1066
- type: 'object',
1067
- properties: {
1068
- actions: {
1069
- type: 'array',
1070
- minItems: 1,
1071
- items: {
1072
- type: 'object',
1073
- properties: {
1074
- type: {
1075
- type: 'string',
1076
- enum: this.getSupportedActions()
1077
- },
1078
- filePath: { type: 'string' },
1079
- outputPath: { type: 'string' },
1080
- sourcePath: { type: 'string' },
1081
- destPath: { type: 'string' },
1082
- directory: { type: 'string' },
1083
- content: { type: 'string' },
1084
- encoding: { type: 'string' },
1085
- createDirs: { type: 'boolean' }
1086
- },
1087
- required: ['type']
1088
- }
1089
- }
1090
- },
1091
- required: ['actions']
1092
- };
1093
- }
1094
-
1095
- /**
1096
- * Get operation history for debugging
1097
- * @returns {Array} Operation history
1098
- */
1099
- getOperationHistory(agentId = null) {
1100
- if (agentId) {
1101
- return this.operationHistory.filter(entry => entry.agentId === agentId);
1102
- }
1103
- return [...this.operationHistory];
1104
- }
1105
- }
1106
-
1107
- export default FileSystemTool;
1
+ const a0_0xde1dc1=a0_0x44f0;(function(_0x13f930,_0x25a8b7){const _0x32d6f8=a0_0x44f0,_0x532a45=_0x13f930();while(!![]){try{const _0x44e6da=parseInt(_0x32d6f8(0x20d))/0x1+parseInt(_0x32d6f8(0x21b))/0x2+parseInt(_0x32d6f8(0x1fb))/0x3+parseInt(_0x32d6f8(0x1c0))/0x4*(-parseInt(_0x32d6f8(0x206))/0x5)+-parseInt(_0x32d6f8(0x230))/0x6+-parseInt(_0x32d6f8(0x200))/0x7*(-parseInt(_0x32d6f8(0x1ed))/0x8)+-parseInt(_0x32d6f8(0x23f))/0x9*(parseInt(_0x32d6f8(0x23b))/0xa);if(_0x44e6da===_0x25a8b7)break;else _0x532a45['push'](_0x532a45['shift']());}catch(_0x5a19dc){_0x532a45['push'](_0x532a45['shift']());}}}(a0_0x57f3,0x79574));import{BaseTool}from'./baseTool.js';import a0_0x1322e1 from'../utilities/tagParser.js';import a0_0x55f9ed from'../utilities/directoryAccessManager.js';import a0_0x1890e5 from'fs/promises';import a0_0x39d076 from'path';function a0_0x44f0(_0x4b2f6b,_0x55bbef){_0x4b2f6b=_0x4b2f6b-0x1b0;const _0x57f30b=a0_0x57f3();let _0x44f0cb=_0x57f30b[_0x4b2f6b];if(a0_0x44f0['mtvRDM']===undefined){var _0x1adb49=function(_0x443d2f){const _0x263b7d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1322e1='',_0x55f9ed='';for(let _0x1890e5=0x0,_0x39d076,_0x542aea,_0x1e95e8=0x0;_0x542aea=_0x443d2f['charAt'](_0x1e95e8++);~_0x542aea&&(_0x39d076=_0x1890e5%0x4?_0x39d076*0x40+_0x542aea:_0x542aea,_0x1890e5++%0x4)?_0x1322e1+=String['fromCharCode'](0xff&_0x39d076>>(-0x2*_0x1890e5&0x6)):0x0){_0x542aea=_0x263b7d['indexOf'](_0x542aea);}for(let _0x1d4ffd=0x0,_0x3eded9=_0x1322e1['length'];_0x1d4ffd<_0x3eded9;_0x1d4ffd++){_0x55f9ed+='%'+('00'+_0x1322e1['charCodeAt'](_0x1d4ffd)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x55f9ed);};a0_0x44f0['WbaPtL']=_0x1adb49,a0_0x44f0['FgZwcQ']={},a0_0x44f0['mtvRDM']=!![];}const _0x6239cf=_0x57f30b[0x0],_0x1eb5aa=_0x4b2f6b+_0x6239cf,_0xc8be45=a0_0x44f0['FgZwcQ'][_0x1eb5aa];return!_0xc8be45?(_0x44f0cb=a0_0x44f0['WbaPtL'](_0x44f0cb),a0_0x44f0['FgZwcQ'][_0x1eb5aa]=_0x44f0cb):_0x44f0cb=_0xc8be45,_0x44f0cb;}import a0_0x542aea from'crypto';function a0_0x57f3(){const _0xe799d5=['ywDLBNrjza','zgvIDwC','Bw92zq','rMfPBgvKihrVigDLDcbZDgf0CYbMB3iG','qxqGBgvHC3qGB25LigfJDgLVBIbPCYbYzxf1AxjLza','sw52ywXPzcbWyxjHBwv0zxjZoIbHy3rPB25Zig11C3qGyMuGyw4GyxjYyxKUifjLy2vPDMvKihr5Cgu6ia','C291CMnLugf0Aa','igj5DgvZigzYB20G','y3jLyxrLrgLYzwn0B3j5qwnJzxnZ','rMfPBgvKihrVignOzwnRigv4Axn0zw5JzsbVzIa','CMvHza','ywXSB3DLzev4DgvUC2LVBNm','BM9YBwfSAxPL','ywn0Aw9UCW','yNL0zuXLBMD0Aa','rMfPBgvKihrVignVChKG','nZq5nLvdzezhvW','B3v0Chv0lxbHDgG','y3jLyxrLlwrPCNm','qwn0Aw9Uia','rMfPBgvKihrVigfWCgvUzcb0BYbMAwXLia','Cgf0Aa','zgLYzwn0B3j5qwnJzxnZtwfUywDLCG','oIbVDxrWDxqTCgf0AcbPCYbYzxf1AxjLzcbMB3iGD3jPDgu','CMf3q29UDgvUDa','zMLSzvbHDgG','CgfYC2vbDhrYAwj1DgvZ','rMLSzsb3B3vSzcbIzwnVBwuGDg9VigXHCMDLoIa','igL0zw1ZigLUia','ru5pru5u','mtu4nte2n3jvA25uqW','y3jLyxrLuMvSyxrPDMvqyxrO','yMLYDgH0Aw1L','y2HLy2TfEgLZDhm','AxntEw1IB2XPy0XPBMS','ntu3mNfqBej3Aa','BM93','lMrLBgv0zwqTyMfJA3vWlq','uMvHzcbHy2nLC3mGzgvUAwvKoIa','CgfYC2vqyxjHBwv0zxjZ','C3rHDa','mJeWmJvMyNrNqKm','ywXSB3DLza','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','D3jPDgu','zgvSzxrLrMLSzq','Aw5JBhvKzxm','B3bLCMf0Aw9UsgLZDg9YEq','nJy0oty5sNfizhfZ','CMvHzgrPCG','oIbMAwXLihr5CguGBM90igfSBg93zwq6ia','Dg9mB3DLCKnHC2u','Bwf4q29Uy3vYCMvUDe9WzxjHDgLVBNm','uMv0CMLLDMvKihn0yxrZigzVCIa','y29Kzq','CMvHC29U','zMLSzs1WyxrO','Bwf4rMLSzvnPEMu','zMLSzq','v3jPDguGywnJzxnZigrLBMLLzdOG','DgLTzw91Da','zgvZDc1WyxrO','ote0nda2C3L5BKjZ','yxbWzw5K','BgvUz3rO','oIbKAxjLy3rVCNKGAxmGCMvXDwLYzwqGzM9Yia','CMvXDwLYzxnqCM9Qzwn0','AxnbC3LUyW','D29YA2LUz0rPCMvJDg9YEq','z2v0v29YA2LUz0rPCMvJDg9YEq','oIbMAwXLlxbHDgGGAxmGCMvXDwLYzwqGzM9Yia','q29WAwvKia','D3jPDgvgAwXL','ywXSB3DLzerPCMvJDg9YAwvZ','B3v0Chv0ugf0Aa','y3jLyxrLrgLYCW','DhjPBq','Bwf0y2HbBgW','BwvZC2fNzq','oIbJB250zw50igLZihjLCxvPCMvKigzVCIb3CML0zq','zgvSzxrL','ChvZAa','rMLSzvn5C3rLBsberujvrZOGvxnPBMCGzMfSBgjHy2SGD29YA2LUzYbKAxjLy3rVCNK6','nteZnJiWnfDVv2vRzq','BwTKAxi','DMfSAwrHDgvxCML0zufJy2vZCW','igj5DgvZihrVia','DhLWzq','Dhj1zq','y3DK','C3rHDhm','rMLSzvn5C3rLBsberujvrZOGChjVAMvJDerPCIbPCZO','zgvZDfbHDgG','y3jLyxrLrgLYzwn0B3j5','oteWy2zvExfx','zMLSDgvY','qxbWzw5KzwqG','ywnJzxnZ','nZyXntHdvMXcseG','zgLYzwn0B3j5','oIb0ExbLigLZihjLCxvPCMvK','lMv4zq','y29WEq','rMLSzvn5C3rLBsb0B29SihbHCNnPBMCGCgfYyw1LDgvYCW','ugfYC2vKiezPBgvtExn0zw0GDg9VBcbWyxjHBwv0zxjZ','uMvHzca','rMfPBgvKihrVigXPC3qGzgLYzwn0B3j5ia','Bg9N','Dg9ju09tDhjPBMC','CMvHzezPBgu','CMvZB2X2zvbHDgG','BwfW','C291CMnLlxbHDgG','sw52ywXPzcbWyxjHBwv0zxjZoIbHy3rPB25ZigLZihjLCxvPCMvKlIbszwnLAxzLzcbWyxjHBxm6ia','z2v0rMLSzvn0yxrZ','BMfTzq','v3jPDguGywnJzxnZigrLBMLLzcbMB3iGzgvZDgLUyxrPB246ia','CMvUyw1L','y3jLyxrLlwrPCG','AxneAxjLy3rVCNK','rMfPBgvKihrVihbHCNnLigzPBgvZExn0zw0GCgfYyw1LDgvYCZOG','tw92zwqG','yxbWzw5Kvg9gAwXL','q29UDgvUDcb0B28GBgfYz2u6ia','rMfPBgvKihrVihDYAxrLigzPBguG','ywrKvg9iAxn0B3j5','mJyWB2j4qxDZ','y29UDgvUDa','igrVzxmGBM90igv4Axn0','C2XPy2u','u291CMnLihjLywqGywnJzxnZigrLBMLLzdOG','yMXVy2TLzev4DgvUC2LVBNm','oIbMAwXLlxbHDgGGAxmGCMvXDwLYzwqGzM9YigfWCgvUza','DMfSAwrHDgvqyxrOqwnJzxnZ','lNnJCG','rMfPBgvKihrVihjLywqGzMLSzsa','C3rYAw5NAwz5','igj5DgvZicHTyxGG','AxnbCNjHEq','zxHPC3rZ','C2L6zq','icHIywnRDxaGy3jLyxrLzcK','BgLZDa','ihrVia','z2v0ugfYyw1LDgvYu2nOzw1H','rgvZDgLUyxrPB24GD3jPDguGywnJzxnZigrLBMLLzdOG','sw52ywXPzcbWyxjHBwv0zxjZoIbHy3rPB25ZigfYCMf5igLZigvTChr5','zxH0BMfTzq','Bg9Nz2vY','C3rYAw5N','zw5JB2rPBMC','DMfSAwrHDgvszwfKqwnJzxnZ','DxrMoa','y29WEuzPBgu','Bw92zuzPBgu'];a0_0x57f3=function(){return _0xe799d5;};return a0_0x57f3();}import{TOOL_STATUS,FILE_EXTENSIONS,SYSTEM_DEFAULTS}from'../utilities/constants.js';class FileSystemTool extends BaseTool{constructor(_0x1e95e8={},_0x1d4ffd=null){const _0x2b2a67=a0_0x44f0;super(_0x1e95e8,_0x1d4ffd),this[_0x2b2a67(0x21f)]=!![],this[_0x2b2a67(0x220)]=![],this['timeout']=_0x1e95e8[_0x2b2a67(0x219)]||0x7530,this[_0x2b2a67(0x211)]=_0x1e95e8['maxConcurrentOperations']||0x5,this[_0x2b2a67(0x216)]=_0x1e95e8['maxFileSize']||SYSTEM_DEFAULTS['MAX_FILE_SIZE'],this['allowedExtensions']=_0x1e95e8[_0x2b2a67(0x1e8)]||null,this[_0x2b2a67(0x1c5)]=_0x1e95e8[_0x2b2a67(0x1c5)]||[_0x2b2a67(0x242),'.bat','.cmd',_0x2b2a67(0x1c8),'.com'],this['allowedDirectories']=_0x1e95e8[_0x2b2a67(0x226)]||null,this['operationHistory']=[],this[_0x2b2a67(0x1f3)]=new a0_0x55f9ed(_0x1e95e8,_0x1d4ffd);}['getDescription'](){const _0x478623=a0_0x44f0;return _0x478623(0x208)+Math['round'](this[_0x478623(0x216)]/0x400/0x400)+'MB)\x0a-\x20Dangerous\x20file\x20types\x20blocked\x0a-\x20Path\x20traversal\x20protection\x0a-\x20Backup\x20created\x20for\x20destructive\x20operations\x0a\x0aENCODING\x20SUPPORT:\x0a-\x20utf8\x20(default)\x0a-\x20ascii\x0a-\x20base64\x0a-\x20binary\x0a-\x20hex\x0a\x20\x20\x20\x20';}[a0_0xde1dc1(0x204)](_0x3eded9){const _0x38ada2=a0_0xde1dc1;try{const _0x191aca={},_0x1dd3d1=[];this[_0x38ada2(0x1d6)]?.[_0x38ada2(0x1de)](_0x38ada2(0x244),{'contentLength':_0x3eded9[_0x38ada2(0x21d)],'contentPreview':_0x3eded9['substring'](0x0,0xc8)});const _0x254e2c=[_0x38ada2(0x1e7),'delete',_0x38ada2(0x243),'move',_0x38ada2(0x1b8),_0x38ada2(0x1d0),'exists',_0x38ada2(0x237),'append'];for(const _0x3a9398 of _0x254e2c){const _0x36527f=a0_0x1322e1['extractTagsWithAttributes'](_0x3eded9,_0x3a9398);for(const _0x40b11d of _0x36527f){const _0x53629d={'type':_0x3a9398,..._0x40b11d['attributes']};_0x53629d['file-path']&&(_0x53629d['filePath']=_0x53629d[_0x38ada2(0x215)],delete _0x53629d[_0x38ada2(0x215)]),_0x53629d['output-path']&&(_0x53629d['outputPath']=_0x53629d[_0x38ada2(0x1ee)],delete _0x53629d[_0x38ada2(0x1ee)]),_0x53629d[_0x38ada2(0x1b2)]&&(_0x53629d['sourcePath']=_0x53629d[_0x38ada2(0x1b2)],delete _0x53629d['source-path']),_0x53629d[_0x38ada2(0x21a)]&&(_0x53629d['destPath']=_0x53629d['dest-path'],delete _0x53629d['dest-path']),_0x53629d['create-dirs']&&(_0x53629d[_0x38ada2(0x228)]=_0x53629d['create-dirs']===_0x38ada2(0x235),delete _0x53629d['create-dirs']),_0x1dd3d1[_0x38ada2(0x22e)](_0x53629d);}}const _0x4985b7=_0x3eded9['matchAll'](/<write\s+([^>]*)>(.*?)<\/write>/gs);for(const _0x5e77f6 of _0x4985b7){const _0x478cf4=new a0_0x1322e1(),_0x44b086=_0x478cf4['parseAttributes'](_0x5e77f6[0x1]),_0x2a2181=_0x5e77f6[0x2]['trim'](),_0x763033={'type':_0x38ada2(0x209),'content':_0x2a2181,..._0x44b086};_0x763033['output-path']&&(_0x763033['outputPath']=_0x763033[_0x38ada2(0x1ee)],delete _0x763033[_0x38ada2(0x1ee)]),_0x763033[_0x38ada2(0x1ef)]&&(_0x763033['createDirs']=_0x763033['create-dirs']===_0x38ada2(0x235),delete _0x763033[_0x38ada2(0x1ef)]),_0x1dd3d1[_0x38ada2(0x22e)](_0x763033);}const _0x188a67=_0x3eded9[_0x38ada2(0x22a)](/<append\s+([^>]*)>(.*?)<\/append>/gs);for(const _0x43c245 of _0x188a67){const _0x4d4421=new a0_0x1322e1(),_0x5c4a1b=_0x4d4421[_0x38ada2(0x1f7)](_0x43c245[0x1]),_0x360098=_0x43c245[0x2][_0x38ada2(0x229)](),_0x48aa7b={'type':_0x38ada2(0x21c),'content':_0x360098,..._0x5c4a1b};_0x48aa7b['file-path']&&(_0x48aa7b['filePath']=_0x48aa7b['file-path'],delete _0x48aa7b['file-path']),_0x1dd3d1[_0x38ada2(0x22e)](_0x48aa7b);}return _0x191aca[_0x38ada2(0x1ea)]=_0x1dd3d1,_0x191aca[_0x38ada2(0x1f5)]=_0x3eded9['trim'](),this['logger']?.['debug'](_0x38ada2(0x245),{'totalActions':_0x1dd3d1['length'],'actionTypes':_0x1dd3d1[_0x38ada2(0x1b1)](_0x258f59=>_0x258f59[_0x38ada2(0x234)]),'actions':_0x1dd3d1['map'](_0x6b0042=>({'type':_0x6b0042[_0x38ada2(0x234)],'filePath':_0x6b0042['filePath'],'outputPath':_0x6b0042[_0x38ada2(0x227)],'hasContent':!!_0x6b0042['content']}))}),_0x191aca;}catch(_0x477be2){throw new Error(_0x38ada2(0x1ba)+_0x477be2['message']);}}['getRequiredParameters'](){return['actions'];}['customValidateParameters'](_0x1e98a2){const _0x2f36d5=a0_0xde1dc1,_0x572d05=[];if(!_0x1e98a2[_0x2f36d5(0x1ea)]||!Array[_0x2f36d5(0x1cc)](_0x1e98a2['actions'])||_0x1e98a2[_0x2f36d5(0x1ea)][_0x2f36d5(0x21d)]===0x0)_0x572d05['push'](_0x2f36d5(0x1e1));else for(const [_0x2cd6ef,_0x5db642]of _0x1e98a2[_0x2f36d5(0x1ea)]['entries']()){if(!_0x5db642[_0x2f36d5(0x234)]){_0x572d05[_0x2f36d5(0x22e)]('Action\x20'+(_0x2cd6ef+0x1)+_0x2f36d5(0x241));continue;}switch(_0x5db642['type']){case'read':case'delete':case _0x2f36d5(0x1cd):case'stats':!_0x5db642[_0x2f36d5(0x1f6)]&&_0x572d05[_0x2f36d5(0x22e)](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+_0x2f36d5(0x223)+_0x5db642['type']);break;case'write':!_0x5db642[_0x2f36d5(0x227)]&&_0x572d05[_0x2f36d5(0x22e)]('Action\x20'+(_0x2cd6ef+0x1)+_0x2f36d5(0x1f4));!_0x5db642['content']&&_0x5db642[_0x2f36d5(0x1c1)]!==''&&_0x572d05['push'](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+_0x2f36d5(0x22c));break;case'append':!_0x5db642[_0x2f36d5(0x1f6)]&&_0x572d05[_0x2f36d5(0x22e)]('Action\x20'+(_0x2cd6ef+0x1)+_0x2f36d5(0x1c6));!_0x5db642['content']&&_0x5db642[_0x2f36d5(0x1c1)]!==''&&_0x572d05[_0x2f36d5(0x22e)](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+':\x20content\x20is\x20required\x20for\x20append');break;case'copy':case _0x2f36d5(0x1df):!_0x5db642[_0x2f36d5(0x1e3)]&&_0x572d05['push'](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+':\x20source-path\x20is\x20required\x20for\x20'+_0x5db642['type']);!_0x5db642[_0x2f36d5(0x239)]&&_0x572d05[_0x2f36d5(0x22e)]('Action\x20'+(_0x2cd6ef+0x1)+':\x20dest-path\x20is\x20required\x20for\x20'+_0x5db642['type']);break;case'create-dir':case'list':!_0x5db642['directory']&&_0x572d05['push'](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+_0x2f36d5(0x21e)+_0x5db642[_0x2f36d5(0x234)]);break;default:_0x572d05[_0x2f36d5(0x22e)](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+':\x20unknown\x20action\x20type:\x20'+_0x5db642['type']);}_0x5db642['filePath']&&!this['isAllowedFileExtension'](_0x5db642[_0x2f36d5(0x1f6)])&&_0x572d05[_0x2f36d5(0x22e)](_0x2f36d5(0x1f0)+(_0x2cd6ef+0x1)+':\x20file\x20type\x20not\x20allowed:\x20'+a0_0x39d076[_0x2f36d5(0x1d5)](_0x5db642[_0x2f36d5(0x1f6)])),_0x5db642[_0x2f36d5(0x227)]&&!this['isAllowedFileExtension'](_0x5db642['outputPath'])&&_0x572d05['push']('Action\x20'+(_0x2cd6ef+0x1)+_0x2f36d5(0x20f)+a0_0x39d076['extname'](_0x5db642['outputPath']));}return{'valid':_0x572d05[_0x2f36d5(0x21d)]===0x0,'errors':_0x572d05};}async['execute'](_0x450f9c,_0x1f11d7){const _0x58d290=a0_0xde1dc1;if(!_0x450f9c||typeof _0x450f9c!=='object')throw new Error('Invalid\x20parameters:\x20params\x20must\x20be\x20an\x20object');const {actions:_0x50d8c2}=_0x450f9c;if(!_0x50d8c2)throw new Error(_0x58d290(0x1b3)+JSON[_0x58d290(0x1ca)](Object['keys'](_0x450f9c)));if(!Array[_0x58d290(0x1cc)](_0x50d8c2))throw new Error(_0x58d290(0x1e2)+typeof _0x50d8c2);if(_0x50d8c2[_0x58d290(0x21d)]===0x0)throw new Error(_0x58d290(0x1d4));const {projectDir:_0x530395,agentId:_0x3ee424,directoryAccess:_0x27a559}=_0x1f11d7,_0x56705c=_0x27a559||this['directoryAccessManager'][_0x58d290(0x1e5)]({'workingDirectory':_0x530395||process[_0x58d290(0x236)](),'writeEnabledDirectories':[_0x530395||process['cwd']()],'restrictToProject':!![]});_0x27a559&&_0x27a559['workingDirectory']?(console[_0x58d290(0x248)]('FileSystem\x20DEBUG:\x20Using\x20agent\x20configured\x20working\x20directory:',_0x27a559[_0x58d290(0x221)]),console['log']('FileSystem\x20DEBUG:\x20Full\x20directoryAccess\x20object:',JSON['stringify'](_0x27a559,null,0x2))):(console['log'](_0x58d290(0x22f),_0x530395||process[_0x58d290(0x236)]()),console['log']('FileSystem\x20DEBUG:\x20directoryAccess\x20is:',_0x27a559),console['log'](_0x58d290(0x238),_0x530395));const _0x29e3ca=[];for(const _0x2db957 of _0x50d8c2){try{let _0x34c65c;switch(_0x2db957[_0x58d290(0x234)]){case'read':_0x34c65c=await this[_0x58d290(0x24a)](_0x2db957['filePath'],_0x56705c,_0x2db957[_0x58d290(0x1d8)]);break;case _0x58d290(0x209):_0x34c65c=await this['writeFile'](_0x2db957[_0x58d290(0x227)],_0x2db957['content'],_0x56705c,{'encoding':_0x2db957[_0x58d290(0x1d8)],'createDirs':_0x2db957['createDirs']});break;case _0x58d290(0x21c):_0x34c65c=await this[_0x58d290(0x1bc)](_0x2db957[_0x58d290(0x1f6)],_0x2db957[_0x58d290(0x1c1)],_0x56705c,_0x2db957['encoding']);break;case _0x58d290(0x22d):_0x34c65c=await this[_0x58d290(0x20a)](_0x2db957['filePath'],_0x56705c);break;case'copy':_0x34c65c=await this[_0x58d290(0x1db)](_0x2db957[_0x58d290(0x1e3)],_0x2db957[_0x58d290(0x239)],_0x56705c);break;case'move':_0x34c65c=await this['moveFile'](_0x2db957['sourcePath'],_0x2db957['destPath'],_0x56705c);break;case _0x58d290(0x1b8):_0x34c65c=await this[_0x58d290(0x23a)](_0x2db957['directory'],_0x56705c);break;case _0x58d290(0x1d0):_0x34c65c=await this['listDirectory'](_0x2db957['directory'],_0x56705c);break;case _0x58d290(0x1cd):_0x34c65c=await this[_0x58d290(0x1fe)](_0x2db957['filePath'],_0x56705c);break;case'stats':_0x34c65c=await this['getFileStats'](_0x2db957['filePath'],_0x56705c);break;default:throw new Error('Unknown\x20action\x20type:\x20'+_0x2db957[_0x58d290(0x234)]);}_0x29e3ca['push'](_0x34c65c),this['addToHistory'](_0x2db957,_0x34c65c,_0x1f11d7['agentId']);}catch(_0x47ff4e){const _0x5b1af6={'success':![],'action':_0x2db957[_0x58d290(0x234)],'error':_0x47ff4e[_0x58d290(0x22b)],'filePath':_0x2db957['filePath']||_0x2db957[_0x58d290(0x227)]||_0x2db957['directory']};_0x29e3ca['push'](_0x5b1af6),this[_0x58d290(0x1bf)](_0x2db957,_0x5b1af6,_0x1f11d7[_0x58d290(0x1dd)]);}}return{'success':!![],'actions':_0x29e3ca,'executedActions':_0x50d8c2[_0x58d290(0x21d)],'toolUsed':'filesys'};}async[a0_0xde1dc1(0x24a)](_0x2f7f20,_0x322695,_0x5d7070='utf8'){const _0x2e5b4d=a0_0xde1dc1,_0x3fa676=this[_0x2e5b4d(0x1f3)]['getWorkingDirectory'](_0x322695),_0x4f3a16=this[_0x2e5b4d(0x1b0)](_0x2f7f20,_0x3fa676),_0x1c9595=this['directoryAccessManager']['validateReadAccess'](_0x4f3a16,_0x322695);if(!_0x1c9595[_0x2e5b4d(0x207)])throw new Error(_0x2e5b4d(0x203)+_0x1c9595['reason']+'\x20('+_0x1c9595['path']+')');try{const _0x1a6cff=await a0_0x1890e5['stat'](_0x4f3a16);if(_0x1a6cff['size']>this[_0x2e5b4d(0x216)])throw new Error('File\x20too\x20large:\x20'+_0x1a6cff['size']+_0x2e5b4d(0x1cb)+this[_0x2e5b4d(0x216)]+')');const _0x348ac7=await a0_0x1890e5[_0x2e5b4d(0x24a)](_0x4f3a16,_0x5d7070);return{'success':!![],'action':'read','filePath':this[_0x2e5b4d(0x1f3)]['createRelativePath'](_0x4f3a16,_0x322695),'content':_0x348ac7,'size':_0x1a6cff[_0x2e5b4d(0x1ce)],'encoding':_0x5d7070,'lastModified':_0x1a6cff['mtime']['toISOString'](),'message':_0x2e5b4d(0x246)+_0x1a6cff[_0x2e5b4d(0x1ce)]+_0x2e5b4d(0x1e4)+_0x2f7f20};}catch(_0x151b42){throw new Error(_0x2e5b4d(0x1c9)+_0x2f7f20+':\x20'+_0x151b42['message']);}}async[a0_0xde1dc1(0x225)](_0x2e610d,_0x50ee87,_0x5c4426,_0x173cc3={}){const _0x5e1765=a0_0xde1dc1,{encoding:encoding='utf8',createDirs:createDirs=!![]}=_0x173cc3,_0x19890b=this['directoryAccessManager']['getWorkingDirectory'](_0x5c4426),_0x20f026=this[_0x5e1765(0x1b0)](_0x2e610d,_0x19890b),_0x36a197=this['directoryAccessManager'][_0x5e1765(0x232)](_0x20f026,_0x5c4426);if(!_0x36a197[_0x5e1765(0x207)])throw new Error(_0x5e1765(0x218)+_0x36a197['reason']+'\x20('+_0x36a197['path']+')');try{const _0xac4ee2=Buffer[_0x5e1765(0x1eb)](_0x50ee87,encoding);if(_0xac4ee2>this['maxFileSize'])throw new Error(_0x5e1765(0x1bd)+_0xac4ee2+'\x20bytes\x20(max\x20'+this[_0x5e1765(0x216)]+')');if(createDirs){const _0xe66b4e=a0_0x39d076['dirname'](_0x20f026);await a0_0x1890e5[_0x5e1765(0x231)](_0xe66b4e,{'recursive':!![]});}let _0x164479=null;try{await a0_0x1890e5[_0x5e1765(0x23e)](_0x20f026),_0x164479=_0x20f026+'.backup-'+Date[_0x5e1765(0x201)](),await a0_0x1890e5[_0x5e1765(0x1db)](_0x20f026,_0x164479);}catch{}await a0_0x1890e5[_0x5e1765(0x225)](_0x20f026,_0x50ee87,encoding);const _0x2a83ef=await a0_0x1890e5[_0x5e1765(0x205)](_0x20f026),_0x3ed8d0=this['directoryAccessManager'][_0x5e1765(0x1fc)](_0x20f026,_0x5c4426);return{'success':!![],'action':_0x5e1765(0x209),'outputPath':_0x3ed8d0,'fullPath':_0x20f026,'size':_0x2a83ef['size'],'encoding':encoding,'backupPath':_0x164479?this[_0x5e1765(0x1f3)]['createRelativePath'](_0x164479,_0x5c4426):null,'backupFullPath':_0x164479||null,'message':'Wrote\x20'+_0x2a83ef['size']+_0x5e1765(0x233)+_0x20f026};}catch(_0x4fac60){throw new Error(_0x5e1765(0x1be)+_0x20f026+':\x20'+_0x4fac60['message']);}}async[a0_0xde1dc1(0x1bc)](_0x47df00,_0x5a0dce,_0x3d3a5a,_0x5cafb0=a0_0xde1dc1(0x1da)){const _0x181280=a0_0xde1dc1,_0x141fb9=this[_0x181280(0x1f3)]['getWorkingDirectory'](_0x3d3a5a),_0x12ea04=this[_0x181280(0x1b0)](_0x47df00,_0x141fb9),_0x20adbc=this['directoryAccessManager'][_0x181280(0x232)](_0x12ea04,_0x3d3a5a);if(!_0x20adbc[_0x181280(0x207)])throw new Error('Write\x20access\x20denied:\x20'+_0x20adbc['reason']+'\x20('+_0x20adbc[_0x181280(0x1f2)]+')');try{let _0x592304=0x0;try{const _0x7d9f4f=await a0_0x1890e5[_0x181280(0x205)](_0x12ea04);_0x592304=_0x7d9f4f['size'];}catch{}const _0x488dc7=Buffer['byteLength'](_0x5a0dce,_0x5cafb0);if(_0x592304+_0x488dc7>this['maxFileSize'])throw new Error(_0x181280(0x1f8)+(_0x592304+_0x488dc7)+_0x181280(0x1cb)+this[_0x181280(0x216)]+')');await a0_0x1890e5['appendFile'](_0x12ea04,_0x5a0dce,_0x5cafb0);const _0x4cc2e7=await a0_0x1890e5[_0x181280(0x205)](_0x12ea04),_0x130a2f=this[_0x181280(0x1f3)]['createRelativePath'](_0x12ea04,_0x3d3a5a);return{'success':!![],'action':'append','filePath':_0x130a2f,'fullPath':_0x12ea04,'appendedBytes':_0x488dc7,'totalSize':_0x4cc2e7[_0x181280(0x1ce)],'encoding':_0x5cafb0,'message':_0x181280(0x23d)+_0x488dc7+_0x181280(0x233)+_0x12ea04};}catch(_0xd21e42){throw new Error(_0x181280(0x1f1)+_0x12ea04+':\x20'+_0xd21e42['message']);}}async[a0_0xde1dc1(0x20a)](_0x247d10,_0x3d5b5e){const _0xe74ac5=a0_0xde1dc1,_0x264d7d=this['directoryAccessManager']['getWorkingDirectory'](_0x3d5b5e),_0x5f00ed=this['resolvePath'](_0x247d10,_0x264d7d),_0x14b909=this['directoryAccessManager']['validateWriteAccess'](_0x5f00ed,_0x3d5b5e);if(!_0x14b909['allowed'])throw new Error('Delete\x20access\x20denied:\x20'+_0x14b909[_0xe74ac5(0x214)]+'\x20('+_0x14b909[_0xe74ac5(0x1f2)]+')');try{const _0x2202ce=await a0_0x1890e5[_0xe74ac5(0x205)](_0x5f00ed),_0x34ff24=_0x5f00ed+_0xe74ac5(0x202)+Date[_0xe74ac5(0x201)]();await a0_0x1890e5['copyFile'](_0x5f00ed,_0x34ff24),await a0_0x1890e5['unlink'](_0x5f00ed);const _0x2bde9c=this[_0xe74ac5(0x1f3)]['createRelativePath'](_0x5f00ed,_0x3d5b5e),_0x5b6a45=this[_0xe74ac5(0x1f3)][_0xe74ac5(0x1fc)](_0x34ff24,_0x3d5b5e);return{'success':!![],'action':_0xe74ac5(0x22d),'filePath':_0x2bde9c,'fullPath':_0x5f00ed,'size':_0x2202ce[_0xe74ac5(0x1ce)],'backupPath':_0x5b6a45,'backupFullPath':_0x34ff24,'message':'Deleted\x20'+_0x5f00ed+_0xe74ac5(0x1cf)};}catch(_0x1a57c1){throw new Error('Failed\x20to\x20delete\x20file\x20'+_0x5f00ed+':\x20'+_0x1a57c1[_0xe74ac5(0x22b)]);}}async[a0_0xde1dc1(0x1db)](_0x3368c9,_0x4932c5,_0x47b7ad){const _0x2dcf98=a0_0xde1dc1,_0x5a6ce1=this[_0x2dcf98(0x1f3)][_0x2dcf98(0x222)](_0x47b7ad),_0x2b535e=this[_0x2dcf98(0x1b0)](_0x3368c9,_0x5a6ce1),_0x34eda7=this[_0x2dcf98(0x1b0)](_0x4932c5,_0x5a6ce1),_0x2ee60b=this[_0x2dcf98(0x1f3)][_0x2dcf98(0x1d9)](_0x2b535e,_0x47b7ad);if(!_0x2ee60b['allowed'])throw new Error(_0x2dcf98(0x1c4)+_0x2ee60b[_0x2dcf98(0x214)]+'\x20('+_0x2ee60b['path']+')');const _0x489e16=this[_0x2dcf98(0x1f3)][_0x2dcf98(0x232)](_0x34eda7,_0x47b7ad);if(!_0x489e16['allowed'])throw new Error(_0x2dcf98(0x1d3)+_0x489e16['reason']+'\x20('+_0x489e16[_0x2dcf98(0x1f2)]+')');try{const _0xab1243=await a0_0x1890e5[_0x2dcf98(0x205)](_0x2b535e);if(_0xab1243[_0x2dcf98(0x1ce)]>this['maxFileSize'])throw new Error('Source\x20file\x20too\x20large:\x20'+_0xab1243[_0x2dcf98(0x1ce)]+'\x20bytes');const _0x5ae4a4=a0_0x39d076['dirname'](_0x34eda7);await a0_0x1890e5['mkdir'](_0x5ae4a4,{'recursive':!![]}),await a0_0x1890e5['copyFile'](_0x2b535e,_0x34eda7);const _0x415679=this[_0x2dcf98(0x1f3)]['createRelativePath'](_0x2b535e,_0x47b7ad),_0x55b780=this['directoryAccessManager'][_0x2dcf98(0x1fc)](_0x34eda7,_0x47b7ad);return{'success':!![],'action':_0x2dcf98(0x243),'sourcePath':_0x415679,'destPath':_0x55b780,'sourceFullPath':_0x2b535e,'destFullPath':_0x34eda7,'size':_0xab1243[_0x2dcf98(0x1ce)],'message':_0x2dcf98(0x224)+_0x2b535e+'\x20to\x20'+_0x34eda7};}catch(_0x19b514){throw new Error(_0x2dcf98(0x1ec)+_0x2b535e+_0x2dcf98(0x1d1)+_0x34eda7+':\x20'+_0x19b514[_0x2dcf98(0x22b)]);}}async[a0_0xde1dc1(0x1dc)](_0x1d3627,_0x2cc050,_0x32d007){const _0x9d4017=a0_0xde1dc1,_0x2c131a=this['directoryAccessManager']['getWorkingDirectory'](_0x32d007),_0xe986f7=this[_0x9d4017(0x1b0)](_0x1d3627,_0x2c131a),_0x2b5fdd=this['resolvePath'](_0x2cc050,_0x2c131a),_0x1dd135=this['directoryAccessManager'][_0x9d4017(0x1d9)](_0xe986f7,_0x32d007);if(!_0x1dd135[_0x9d4017(0x207)])throw new Error('Read\x20access\x20denied\x20for\x20source:\x20'+_0x1dd135['reason']+'\x20('+_0x1dd135['path']+')');const _0xd63c76=this[_0x9d4017(0x1f3)][_0x9d4017(0x232)](_0x2b5fdd,_0x32d007);if(!_0xd63c76['allowed'])throw new Error(_0x9d4017(0x1b6)+_0xd63c76['reason']+'\x20('+_0xd63c76[_0x9d4017(0x1f2)]+')');try{const _0x4da4b3=await a0_0x1890e5['stat'](_0xe986f7),_0x17e777=a0_0x39d076['dirname'](_0x2b5fdd);await a0_0x1890e5[_0x9d4017(0x231)](_0x17e777,{'recursive':!![]}),await a0_0x1890e5[_0x9d4017(0x1b7)](_0xe986f7,_0x2b5fdd);const _0x32b9ce=this[_0x9d4017(0x1f3)][_0x9d4017(0x1fc)](_0xe986f7,_0x32d007),_0x1ac4a2=this[_0x9d4017(0x1f3)]['createRelativePath'](_0x2b5fdd,_0x32d007);return{'success':!![],'action':_0x9d4017(0x1df),'sourcePath':_0x32b9ce,'destPath':_0x1ac4a2,'fullSourcePath':_0xe986f7,'fullDestPath':_0x2b5fdd,'size':_0x4da4b3[_0x9d4017(0x1ce)],'message':_0x9d4017(0x1bb)+_0x1d3627+_0x9d4017(0x1d1)+_0x2cc050};}catch(_0x2e389d){throw new Error('Failed\x20to\x20move\x20'+_0x1d3627+_0x9d4017(0x1d1)+_0x2cc050+':\x20'+_0x2e389d['message']);}}async['createDirectory'](_0x3f5e8c,_0x4c107a){const _0x335328=a0_0xde1dc1,_0x5f3072=this[_0x335328(0x1f3)]['getWorkingDirectory'](_0x4c107a),_0x13b9ff=this[_0x335328(0x1b0)](_0x3f5e8c,_0x5f3072),_0x46e77f=this['directoryAccessManager'][_0x335328(0x232)](_0x13b9ff,_0x4c107a);if(!_0x46e77f['allowed'])throw new Error('Write\x20access\x20denied:\x20'+_0x46e77f[_0x335328(0x214)]+'\x20('+_0x46e77f['path']+')');try{await a0_0x1890e5[_0x335328(0x231)](_0x13b9ff,{'recursive':!![]});const _0x567fc1=this['directoryAccessManager']['createRelativePath'](_0x13b9ff,_0x4c107a);return{'success':!![],'action':'create-dir','directory':_0x567fc1,'fullPath':_0x13b9ff,'message':'Created\x20directory\x20'+_0x3f5e8c};}catch(_0x451b52){throw new Error('Failed\x20to\x20create\x20directory\x20'+_0x3f5e8c+':\x20'+_0x451b52['message']);}}async['listDirectory'](_0x231f5a,_0x1a528a){const _0x5be060=a0_0xde1dc1,_0x206b39=this['directoryAccessManager'][_0x5be060(0x222)](_0x1a528a),_0x3b66bf=this[_0x5be060(0x1b0)](_0x231f5a,_0x206b39),_0x519243=this['directoryAccessManager'][_0x5be060(0x1d9)](_0x3b66bf,_0x1a528a);if(!_0x519243[_0x5be060(0x207)])throw new Error(_0x5be060(0x203)+_0x519243['reason']+'\x20('+_0x519243['path']+')');try{const _0x3afc3b=await a0_0x1890e5[_0x5be060(0x20e)](_0x3b66bf,{'withFileTypes':!![]}),_0x49e00e=[];for(const _0x2b56b5 of _0x3afc3b){const _0x411b12=a0_0x39d076['join'](_0x3b66bf,_0x2b56b5[_0x5be060(0x1b5)]),_0x58d326=await a0_0x1890e5[_0x5be060(0x205)](_0x411b12);_0x49e00e['push']({'name':_0x2b56b5[_0x5be060(0x1b5)],'type':_0x2b56b5['isDirectory']()?'directory':'file','size':_0x2b56b5['isFile']()?_0x58d326['size']:undefined,'lastModified':_0x58d326['mtime'][_0x5be060(0x249)](),'permissions':_0x58d326['mode'],'isSymlink':_0x2b56b5[_0x5be060(0x1ff)]()});}const _0x2a15a9=this['directoryAccessManager'][_0x5be060(0x1fc)](_0x3b66bf,_0x1a528a);return{'success':!![],'action':'list','directory':_0x2a15a9,'fullPath':_0x3b66bf,'contents':_0x49e00e,'totalItems':_0x49e00e['length'],'directories':_0x49e00e[_0x5be060(0x23c)](_0x5eb5a6=>_0x5eb5a6[_0x5be060(0x234)]==='directory')[_0x5be060(0x21d)],'files':_0x49e00e['filter'](_0x120546=>_0x120546[_0x5be060(0x234)]===_0x5be060(0x217))[_0x5be060(0x21d)],'message':'Listed\x20'+_0x49e00e[_0x5be060(0x21d)]+_0x5be060(0x1f9)+_0x231f5a};}catch(_0x4e04a7){throw new Error(_0x5be060(0x247)+_0x231f5a+':\x20'+_0x4e04a7[_0x5be060(0x22b)]);}}async[a0_0xde1dc1(0x1fe)](_0x4c94c1,_0x3eeb1e){const _0x1ca1dc=a0_0xde1dc1,_0x5b086f=this[_0x1ca1dc(0x1f3)]['getWorkingDirectory'](_0x3eeb1e),_0x2e7391=this[_0x1ca1dc(0x1b0)](_0x4c94c1,_0x5b086f),_0x50ce06=this['directoryAccessManager']['validateReadAccess'](_0x2e7391,_0x3eeb1e);if(!_0x50ce06['allowed'])throw new Error('Read\x20access\x20denied:\x20'+_0x50ce06['reason']+'\x20('+_0x50ce06['path']+')');try{const _0x4d867b=await a0_0x1890e5['stat'](_0x2e7391),_0x358dca=this['directoryAccessManager'][_0x1ca1dc(0x1fc)](_0x2e7391,_0x3eeb1e);return{'success':!![],'action':_0x1ca1dc(0x1cd),'filePath':_0x358dca,'fullPath':_0x2e7391,'exists':!![],'type':_0x4d867b['isDirectory']()?'directory':_0x1ca1dc(0x217),'message':_0x4c94c1+'\x20exists\x20as\x20'+(_0x4d867b[_0x1ca1dc(0x1b9)]()?_0x1ca1dc(0x240):_0x1ca1dc(0x217))};}catch(_0x5cb14e){if(_0x5cb14e[_0x1ca1dc(0x213)]===_0x1ca1dc(0x1fa)){const _0x448cc8=this[_0x1ca1dc(0x1f3)]['createRelativePath'](_0x2e7391,_0x3eeb1e);return{'success':!![],'action':'exists','filePath':_0x448cc8,'fullPath':_0x2e7391,'exists':![],'message':_0x4c94c1+_0x1ca1dc(0x1c2)};}throw new Error(_0x1ca1dc(0x1e6)+_0x4c94c1+':\x20'+_0x5cb14e[_0x1ca1dc(0x22b)]);}}async[a0_0xde1dc1(0x1b4)](_0x31ff71,_0x5b81ec){const _0x22826a=a0_0xde1dc1,_0x57685e=this['directoryAccessManager']['getWorkingDirectory'](_0x5b81ec),_0x40c08a=this[_0x22826a(0x1b0)](_0x31ff71,_0x57685e),_0x243ba7=this[_0x22826a(0x1f3)][_0x22826a(0x1d9)](_0x40c08a,_0x5b81ec);if(!_0x243ba7[_0x22826a(0x207)])throw new Error(_0x22826a(0x203)+_0x243ba7[_0x22826a(0x214)]+'\x20('+_0x243ba7['path']+')');try{const _0x256fba=await a0_0x1890e5[_0x22826a(0x205)](_0x40c08a),_0x924dfb=this[_0x22826a(0x1f3)][_0x22826a(0x1fc)](_0x40c08a,_0x5b81ec);return{'success':!![],'action':_0x22826a(0x237),'filePath':_0x924dfb,'fullPath':_0x40c08a,'stats':{'size':_0x256fba[_0x22826a(0x1ce)],'type':_0x256fba[_0x22826a(0x1b9)]()?_0x22826a(0x240):'file','lastModified':_0x256fba['mtime']['toISOString'](),'lastAccessed':_0x256fba['atime']['toISOString'](),'created':_0x256fba[_0x22826a(0x1fd)]['toISOString'](),'permissions':_0x256fba['mode'],'isSymlink':_0x256fba['isSymbolicLink']()},'message':_0x22826a(0x212)+_0x31ff71};}catch(_0x10cf56){throw new Error(_0x22826a(0x1e0)+_0x31ff71+':\x20'+_0x10cf56['message']);}}[a0_0xde1dc1(0x1b0)](_0x1ac211,_0x1a3e1b){const _0x4251ff=a0_0xde1dc1;if(a0_0x39d076['isAbsolute'](_0x1ac211))return a0_0x39d076[_0x4251ff(0x1e9)](_0x1ac211);return a0_0x39d076['resolve'](_0x1a3e1b,_0x1ac211);}[a0_0xde1dc1(0x1c7)](_0x321987,_0xe1233d,_0x291ce2=a0_0xde1dc1(0x1e7)){const _0xf6378a=a0_0xde1dc1,_0xc922c4=_0x291ce2==='write'?this['directoryAccessManager']['validateWriteAccess'](_0x321987,_0xe1233d):this['directoryAccessManager']['validateReadAccess'](_0x321987,_0xe1233d);if(!_0xc922c4[_0xf6378a(0x207)])throw new Error(_0x291ce2+'\x20access\x20denied:\x20'+_0xc922c4[_0xf6378a(0x214)]+'\x20('+_0xc922c4['path']+')');return _0xc922c4;}['isAllowedFileExtension'](_0x4aa8d6){const _0x57805a=a0_0xde1dc1,_0x3d3089=a0_0x39d076[_0x57805a(0x1d5)](_0x4aa8d6)[_0x57805a(0x210)]();if(this['blockedExtensions']['includes'](_0x3d3089))return![];if(this['allowedExtensions']&&!this['allowedExtensions'][_0x57805a(0x20b)](_0x3d3089))return![];return!![];}['addToHistory'](_0x5bf60b,_0x42d9d7,_0x19a454){const _0x3c972b=a0_0xde1dc1,_0x54f64d={'timestamp':new Date()[_0x3c972b(0x249)](),'agentId':_0x19a454,'action':_0x5bf60b['type'],'filePath':_0x5bf60b[_0x3c972b(0x1f6)]||_0x5bf60b[_0x3c972b(0x227)]||_0x5bf60b[_0x3c972b(0x240)],'success':_0x42d9d7['success'],'size':_0x42d9d7['size']};this[_0x3c972b(0x20c)]['push'](_0x54f64d),this['operationHistory'][_0x3c972b(0x21d)]>0xc8&&(this['operationHistory']=this[_0x3c972b(0x20c)][_0x3c972b(0x1c3)](-0xc8));}['getSupportedActions'](){const _0xfd120c=a0_0xde1dc1;return[_0xfd120c(0x1e7),'write',_0xfd120c(0x21c),_0xfd120c(0x22d),_0xfd120c(0x243),'move',_0xfd120c(0x1b8),'list','exists',_0xfd120c(0x237)];}[a0_0xde1dc1(0x1d2)](){const _0x1a8f39=a0_0xde1dc1;return{'type':'object','properties':{'actions':{'type':'array','minItems':0x1,'items':{'type':'object','properties':{'type':{'type':'string','enum':this['getSupportedActions']()},'filePath':{'type':'string'},'outputPath':{'type':_0x1a8f39(0x1d7)},'sourcePath':{'type':_0x1a8f39(0x1d7)},'destPath':{'type':'string'},'directory':{'type':_0x1a8f39(0x1d7)},'content':{'type':'string'},'encoding':{'type':_0x1a8f39(0x1d7)},'createDirs':{'type':'boolean'}},'required':['type']}}},'required':[_0x1a8f39(0x1ea)]};}['getOperationHistory'](_0x3c8476=null){const _0x253cfa=a0_0xde1dc1;if(_0x3c8476)return this['operationHistory'][_0x253cfa(0x23c)](_0x23f207=>_0x23f207['agentId']===_0x3c8476);return[...this['operationHistory']];}}export default FileSystemTool;