@loxia-labs/loxia-autopilot-one 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +15 -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_0x4a8135=a0_0x16d8;(function(_0x46c182,_0x135876){const _0x273188=a0_0x16d8,_0x28b8af=_0x46c182();while(!![]){try{const _0xb1597=parseInt(_0x273188(0x113))/0x1*(parseInt(_0x273188(0xed))/0x2)+parseInt(_0x273188(0x119))/0x3+parseInt(_0x273188(0xf0))/0x4+parseInt(_0x273188(0xfe))/0x5+parseInt(_0x273188(0x111))/0x6+-parseInt(_0x273188(0xfb))/0x7+-parseInt(_0x273188(0x10b))/0x8;if(_0xb1597===_0x135876)break;else _0x28b8af['push'](_0x28b8af['shift']());}catch(_0x1cd831){_0x28b8af['push'](_0x28b8af['shift']());}}}(a0_0x4755,0xce4e3));import{BaseTool}from'./baseTool.js';import a0_0x14816d from'../utilities/tagParser.js';import a0_0x2d08cc from'../utilities/directoryAccessManager.js';import a0_0xa233b7 from'fs/promises';import a0_0x291fbd from'path';function a0_0x4755(){const _0x511d9f=['C2XPy2u','mZG0nZm4rNvKtffH','C291CMnLugf0Aa','mtK0nJaXrM9Pzu1W','zgvSzxrL','rMfPBgvKihrVihjLywqGzMLSzsa','ihrVia','oIbKAxjLy3rVCNKGAxmGCMvXDwLYzwqGzM9Yia','BM93','nda2mZi4nfnbqLbArq','A2v5CW','rMfPBgvKihrVihbHCNnLigzPBgvZExn0zw0GCgfYyw1LDgvYCZOG','ywXSB3DLzerPCMvJDg9YAwvZ','C291CMnLlxbHDgG','rMfPBgvKihrVigDLDcbZDgf0CYbMB3iG','ywn0Aw9UCW','oIbZB3vYy2uTCgf0AcbPCYbYzxf1AxjLzcbMB3iG','oIbVDxrWDxqTCgf0AcbPCYbYzxf1AxjLzcbMB3iGD3jPDgu','rMLSzvn5C3rLBsberujvrZOGChjVAMvJDerPCIbPCZO','C3rHDa','y3jLyxrLlwrPCG','DgLTzw91Da','yxbWzw5KrMLSzq','y3jLyxrLrgLYzwn0B3j5qwnJzxnZ','BMfTzq','igj5DgvZicHTyxGG','DhjPBq','qxqGBgvHC3qGB25LigfJDgLVBIbPCYbYzxf1AxjLza','z2v0uMvXDwLYzwrqyxjHBwv0zxjZ','q3jLyxrLzcbKAxjLy3rVCNKG','C2L6zq','CMvHzezPBgu','CMvUyw1L','Dhj1zq','tuiPcI0GrgfUz2vYB3vZigzPBguGDhLWzxmGyMXVy2TLzaOTifbHDgGGDhjHDMvYC2fSihbYB3rLy3rPB24klsbcywnRDxaGy3jLyxrLzcbMB3iGzgvZDhj1y3rPDMuGB3bLCMf0Aw9UCWOkru5dt0rjtKCGu1vque9svdOklsb1Dgy4icHKzwzHDwX0kqOTigfZy2LPcI0GyMfZzty0cI0GyMLUyxj5cI0GAgv4cIaGica','igj5DgvZigzYB20G','sw52ywXPzcbWyxjHBwv0zxjZoIbHy3rPB25Zig11C3qGyMuGyw4GyxjYyxKUifjLy2vPDMvKihr5Cgu6ia','y29UDgvUDa','oIbMAwXLihr5CguGBM90igfSBg93zwq6ia','oIbMAwXLlxbHDgGGAxmGCMvXDwLYzwqGzM9Yia','C3rYAw5N','zgvZDc1WyxrO','BgLZDa','D3jPDgu','igL0zw1ZigLUia','DxrMoa','oIb0ExbLigLZihjLCxvPCMvK','Bw92zuzPBgu','ru5pru5u','rMfPBgvKihrVigrLBgv0zsbMAwXLia','C3rYAw5NAwz5','lMnTza','Bg9Nz2vY','ywXSB3DLza','rMfPBgvKihrVigXPC3qGzgLYzwn0B3j5ia','CMvHza','v3jPDguGywnJzxnZigrLBMLLzdOG','Bwf4q29Uy3vYCMvUDe9WzxjHDgLVBNm','q29WAwvKia','DhLWzq','zgLYzwn0B3j5','ywnJzxnZ','BgvUz3rO','zgvZDfbHDgG','Bg9N','B3bLCMf0Aw9UsgLZDg9YEq','C3rHDhm','zgLYzwn0B3j5qwnJzxnZtwfUywDLCG','uMvHzcbHy2nLC3mGzgvUAwvKoIa','ywXSB3DLzev4DgvUC2LVBNm','zMLSzvbHDgG','AxneAxjLy3rVCNK','C3vIC3rYAw5N','AxnbBgXVD2vKrMLSzuv4DgvUC2LVBG','CgfYC2vbDhrYAwj1DgvZ','z2v0v29YA2LUz0rPCMvJDg9YEq','lMv4zq','u291CMnLihjLywqGywnJzxnZigrLBMLLzdOG','y3jLyxrLlwrPCNm','y29Kzq','rMfPBgvKihrVig1VDMuG','zgLYBMfTzq','CMf3q29UDgvUDa','Bwf4rMLSzvnPEMu','y3DK','zgvSzxrLrMLSzq','rMLSzvn5C3rLBsb0B29SihbHCNnPBMCGCgfYyw1LDgvYCW','B3v0Chv0ugf0Aa','AxntEw1IB2XPy0XPBMS','sw52ywXPzcbWyxjHBwv0zxjZoIbWyxjHBxmGBxvZDcbIzsbHBIbVyMPLy3q','rMLSzvn5C3rLBsberujvrZOGvxnPBMCGywDLBNqGy29UzMLNDxjLzcb3B3jRAw5NigrPCMvJDg9YEtO','rMfPBgvKihrVignOzwnRigv4Axn0zw5JzsbVzIa','BgLZDerPCMvJDg9YEq','z2v0u3vWCg9YDgvKqwn0Aw9UCW','ywrKvg9iAxn0B3j5','CMvHC29U','BwTKAxi','zxH0CMfJDfrHz3nxAxrOqxr0CMLIDxrLCW','DMfSAwrHDgvszwfKqwnJzxnZ','zgvIDwC','rMLSzvn5C3rLBsberujvrZOGzgLYzwn0B3j5qwnJzxnZigLZoG','yNL0zuXLBMD0Aa','B2jQzwn0','oIbKzxn0lxbHDgGGAxmGCMvXDwLYzwqGzM9Yia','B3v0Chv0lxbHDgG','AxngAwXL','Bw92zq','rgvZDgLUyxrPB24GD3jPDguGywnJzxnZigrLBMLLzdOG','Dg9ju09tDhjPBMC','rgvSzxrLzca','AxnbCNjHEq','zxHPC3rZ','BwfW','Cgf0Aa','yMXVy2TLzev4DgvUC2LVBNm','zMLSDgvY','zMLSzq','mtjdq3PnwNG','igj5DgvZihrVia','yxbWzw5K','nJCYmtuWohPPBg54Ba','y3jLyxrLrgLYCW','rMLSzvn5C3rLBsberujvrZOGrNvSBcbKAxjLy3rVCNLby2nLC3mGB2jQzwn0oG','y3jLyxrLuMvSyxrPDMvqyxrO','DMfSAwrHDgvqyxrOqwnJzxnZ','zw5JB2rPBMC','CMvZB2X2zq','BxrPBwu','qwn0Aw9Uia','BM9YBwfSAxPL','y29WEq','mZm0otm1m3PywfvTuW','Aw5JBhvKzxm','DMfSAwrHDgvxCML0zufJy2vZCW','ntm0otCYme56sg5RAq','BwvZC2fNzq','rMfPBgvKihrVihDYAxrLigzPBguG','uMv0CMLLDMvKihn0yxrZigzVCIa','y3jLyxrLrgLYzwn0B3j5','ChvZAa','lMnVBq','Dg9mB3DLCKnHC2u','CMvZB2X2zvbHDgG','y29WEuzPBgu','zMLSzs1WyxrO','zxH0BMfTzq','z2v0rMLSzvn0yxrZ','mZiXmdm3nZznAwPuCwu','z2v0rgvZy3jPChrPB24','igrVzxmGBM90igv4Axn0','rMfPBgvKihrVignVChKG','y3vZDg9TvMfSAwrHDgvqyxjHBwv0zxjZ'];a0_0x4755=function(){return _0x511d9f;};return a0_0x4755();}import a0_0x17ea40 from'crypto';import{TOOL_STATUS,FILE_EXTENSIONS,SYSTEM_DEFAULTS}from'../utilities/constants.js';class FileSystemTool extends BaseTool{constructor(_0x3cf2f4={},_0x3d13dd=null){const _0x5dcd83=a0_0x16d8;super(_0x3cf2f4,_0x3d13dd),this['requiresProject']=!![],this['isAsync']=![],this[_0x5dcd83(0x125)]=_0x3cf2f4[_0x5dcd83(0x125)]||0x7530,this[_0x5dcd83(0x149)]=_0x3cf2f4['maxConcurrentOperations']||0x5,this['maxFileSize']=_0x3cf2f4['maxFileSize']||SYSTEM_DEFAULTS['MAX_FILE_SIZE'],this[_0x5dcd83(0x155)]=_0x3cf2f4[_0x5dcd83(0x155)]||null,this['blockedExtensions']=_0x3cf2f4[_0x5dcd83(0xea)]||[_0x5dcd83(0x15c),'.bat',_0x5dcd83(0x143),'.scr',_0x5dcd83(0x104)],this[_0x5dcd83(0x11c)]=_0x3cf2f4['allowedDirectories']||null,this[_0x5dcd83(0x151)]=[],this[_0x5dcd83(0x153)]=new a0_0x2d08cc(_0x3cf2f4,_0x3d13dd);}[a0_0x4a8135(0x10c)](){const _0x2215f0=a0_0x4a8135;return'\x0aFile\x20System\x20Tool:\x20Perform\x20file\x20and\x20directory\x20operations\x20safely\x20within\x20the\x20project\x20scope.\x0a\x0aCRITICAL:\x20Both\x20XML\x20and\x20JSON\x20formats\x20are\x20fully\x20supported.\x20When\x20using\x20XML\x20format,\x20commands\x20are\x20automatically\x20converted\x20to\x20the\x20appropriate\x20structure\x20internally\x20-\x20you\x20don\x27t\x20need\x20to\x20manually\x20wrap\x20them\x20in\x20an\x20actions\x20array.\x0a\x0aUSAGE\x20-\x20TWO\x20FORMATS\x20SUPPORTED:\x0a\x0aFORMAT\x201\x20-\x20XML\x20STYLE\x20(Recommended):\x0a[tool\x20id=\x22filesystem\x22]\x0a<read\x20file-path=\x22src/index.js\x22\x20/>\x0a<write\x20output-path=\x22src/components/Button.js\x22>\x0aconst\x20Button\x20=\x20()\x20=>\x20{\x0a\x20\x20return\x20<button>Click\x20me</button>;\x0a};\x0aexport\x20default\x20Button;\x0a</write>\x0a[/tool]\x0a\x0aFORMAT\x202\x20-\x20JSON\x20STYLE:\x0a```json\x0a{\x0a\x20\x20\x22toolId\x22:\x20\x22filesystem\x22,\x20\x0a\x20\x20\x22actions\x22:\x20[\x0a\x20\x20\x20\x20{\x0a\x20\x20\x20\x20\x20\x20\x22type\x22:\x20\x22read\x22,\x0a\x20\x20\x20\x20\x20\x20\x22filePath\x22:\x20\x22src/index.js\x22\x0a\x20\x20\x20\x20},\x0a\x20\x20\x20\x20{\x0a\x20\x20\x20\x20\x20\x20\x22type\x22:\x20\x22write\x22,\x20\x0a\x20\x20\x20\x20\x20\x20\x22outputPath\x22:\x20\x22src/components/Button.js\x22,\x0a\x20\x20\x20\x20\x20\x20\x22content\x22:\x20\x22const\x20Button\x20=\x20()\x20=>\x20{\x20return\x20<button>Click\x20me</button>;\x20};\x22\x0a\x20\x20\x20\x20}\x0a\x20\x20]\x0a}\x0a```\x0a\x0aIMPORTANT:\x20\x0a-\x20Use\x20either\x20format\x20consistently.\x20Do\x20NOT\x20mix\x20formats\x20in\x20a\x20single\x20command.\x0a-\x20XML\x20format\x20is\x20recommended\x20for\x20single\x20operations\x20and\x20better\x20readability\x0a-\x20JSON\x20format\x20is\x20recommended\x20for\x20complex\x20multi-action\x20operations\x0a-\x20Both\x20formats\x20work\x20equally\x20well\x20and\x20produce\x20the\x20same\x20results\x0a\x0aSUPPORTED\x20ACTIONS:\x0a-\x20read:\x20Read\x20file\x20contents\x0a-\x20write:\x20Write\x20content\x20to\x20file\x0a-\x20append:\x20Append\x20content\x20to\x20existing\x20file\x0a-\x20delete:\x20Delete\x20a\x20file\x0a-\x20copy:\x20Copy\x20file\x20from\x20source\x20to\x20destination\x0a-\x20move:\x20Move/rename\x20file\x0a-\x20create-dir:\x20Create\x20directory\x0a-\x20list:\x20List\x20directory\x20contents\x0a-\x20exists:\x20Check\x20if\x20file/directory\x20exists\x0a-\x20stats:\x20Get\x20file/directory\x20metadata\x0a\x0aPARAMETERS:\x0a-\x20file-path:\x20Path\x20to\x20file\x20to\x20read\x0a-\x20output-path:\x20Path\x20where\x20to\x20write/create\x20file\x0a-\x20source-path:\x20Source\x20path\x20for\x20copy/move\x20operations\x0a-\x20dest-path:\x20Destination\x20path\x20for\x20copy/move\x20operations\x0a-\x20directory:\x20Directory\x20path\x20for\x20directory\x20operations\x0a-\x20content:\x20Content\x20to\x20write/append\x0a-\x20encoding:\x20File\x20encoding\x20(default:\x20utf8)\x0a-\x20create-dirs:\x20Create\x20parent\x20directories\x20if\x20they\x20don\x27t\x20exist\x20(true/false)\x0a\x0aEXAMPLES:\x0a\x0aSIMPLE\x20FILE\x20CREATION\x20(XML\x20format\x20-\x20recommended):\x0a[tool\x20id=\x22filesystem\x22]\x0a<write\x20output-path=\x22hello.c\x22>\x0a#include\x20<stdio.h>\x0a\x0aint\x20main()\x20{\x0a\x20\x20\x20\x20printf(\x22Hello,\x20World!\x5cn\x22);\x0a\x20\x20\x20\x20return\x200;\x0a}\x0a</write>\x0a[/tool]\x0a\x0aREADING\x20FILES\x20(XML\x20format):\x0a[tool\x20id=\x22filesystem\x22]\x0a<read\x20file-path=\x22package.json\x22\x20/>\x0a[/tool]\x0a\x0aMULTIPLE\x20OPERATIONS\x20(JSON\x20format\x20recommended):\x0a```json\x0a{\x0a\x20\x20\x22toolId\x22:\x20\x22filesystem\x22,\x0a\x20\x20\x22actions\x22:\x20[\x0a\x20\x20\x20\x20{\x0a\x20\x20\x20\x20\x20\x20\x22type\x22:\x20\x22read\x22,\x0a\x20\x20\x20\x20\x20\x20\x22filePath\x22:\x20\x22src/index.js\x22\x0a\x20\x20\x20\x20},\x0a\x20\x20\x20\x20{\x0a\x20\x20\x20\x20\x20\x20\x22type\x22:\x20\x22write\x22,\x0a\x20\x20\x20\x20\x20\x20\x22outputPath\x22:\x20\x22src/backup.js\x22,\x0a\x20\x20\x20\x20\x20\x20\x22content\x22:\x20\x22//\x20Backup\x20file\x5cnconsole.log(\x27backup\x27);\x22\x0a\x20\x20\x20\x20}\x0a\x20\x20]\x0a}\x0a```\x0a\x0aOTHER\x20XML\x20EXAMPLES:\x0a[tool\x20id=\x22filesystem\x22]\x0a<copy\x20source-path=\x22template.js\x22\x20dest-path=\x22src/component.js\x22\x20/>\x0a<create-dir\x20directory=\x22src/components/ui\x22\x20/>\x0a<list\x20directory=\x22src\x22\x20/>\x0a[/tool]\x0a\x0aSECURITY:\x0a-\x20Operations\x20restricted\x20to\x20project\x20directory\x0a-\x20File\x20size\x20limits\x20enforced\x20(max\x20'+Math['round'](this[_0x2215f0(0x163)]/0x400/0x400)+_0x2215f0(0x132);}['parseParameters'](_0x4f26d4){const _0x3c325b=a0_0x4a8135;try{const _0x17bc6e={},_0x4ad2b7=[];this[_0x3c325b(0x144)]?.[_0x3c325b(0x173)](_0x3c325b(0x166),{'contentLength':_0x4f26d4['length'],'contentPreview':_0x4f26d4[_0x3c325b(0x158)](0x0,0xc8)});const _0x7e344=['read',_0x3c325b(0x114),_0x3c325b(0xfa),'move',_0x3c325b(0x124),_0x3c325b(0x13a),_0x3c325b(0xe7),'stats',_0x3c325b(0xef)];for(const _0x490cd0 of _0x7e344){const _0x2c1161=a0_0x14816d[_0x3c325b(0x171)](_0x4f26d4,_0x490cd0);for(const _0x676378 of _0x2c1161){const _0x887e62={'type':_0x490cd0,..._0x676378['attributes']};_0x887e62[_0x3c325b(0x108)]&&(_0x887e62['filePath']=_0x887e62[_0x3c325b(0x108)],delete _0x887e62['file-path']),_0x887e62[_0x3c325b(0x178)]&&(_0x887e62['outputPath']=_0x887e62[_0x3c325b(0x178)],delete _0x887e62[_0x3c325b(0x178)]),_0x887e62[_0x3c325b(0x11d)]&&(_0x887e62[_0x3c325b(0x112)]=_0x887e62['source-path'],delete _0x887e62['source-path']),_0x887e62['dest-path']&&(_0x887e62[_0x3c325b(0x14f)]=_0x887e62['dest-path'],delete _0x887e62[_0x3c325b(0x139)]),_0x887e62['create-dirs']&&(_0x887e62[_0x3c325b(0xf1)]=_0x887e62['create-dirs']===_0x3c325b(0x131),delete _0x887e62['create-dirs']),_0x4ad2b7[_0x3c325b(0x103)](_0x887e62);}}const _0x484749=_0x4f26d4['matchAll'](/<write\s+([^>]*)>(.*?)<\/write>/gs);for(const _0x5e7443 of _0x484749){const _0x288084=new a0_0x14816d(),_0x42e71b=_0x288084['parseAttributes'](_0x5e7443[0x1]),_0x149804=_0x5e7443[0x2]['trim'](),_0x55b092={'type':'write','content':_0x149804,..._0x42e71b};_0x55b092['output-path']&&(_0x55b092[_0x3c325b(0x167)]=_0x55b092['output-path'],delete _0x55b092['output-path']),_0x55b092['create-dirs']&&(_0x55b092[_0x3c325b(0xf1)]=_0x55b092[_0x3c325b(0x15e)]==='true',delete _0x55b092[_0x3c325b(0x15e)]),_0x4ad2b7['push'](_0x55b092);}const _0x2acabd=_0x4f26d4['matchAll'](/<append\s+([^>]*)>(.*?)<\/append>/gs);for(const _0x5e551c of _0x2acabd){const _0x53864d=new a0_0x14816d(),_0x4cdb4e=_0x53864d[_0x3c325b(0x15a)](_0x5e551c[0x1]),_0x490f7f=_0x5e551c[0x2][_0x3c325b(0x12a)](),_0x578af8={'type':'append','content':_0x490f7f,..._0x4cdb4e};_0x578af8['file-path']&&(_0x578af8['filePath']=_0x578af8['file-path'],delete _0x578af8[_0x3c325b(0x108)]),_0x4ad2b7['push'](_0x578af8);}return _0x17bc6e['actions']=_0x4ad2b7,_0x17bc6e[_0x3c325b(0x162)]=_0x4f26d4[_0x3c325b(0x12a)](),this['logger']?.[_0x3c325b(0x173)]('Parsed\x20FileSystem\x20tool\x20parameters',{'totalActions':_0x4ad2b7['length'],'actionTypes':_0x4ad2b7['map'](_0x509978=>_0x509978['type']),'actions':_0x4ad2b7[_0x3c325b(0xe8)](_0x10a4fc=>({'type':_0x10a4fc['type'],'filePath':_0x10a4fc['filePath'],'outputPath':_0x10a4fc['outputPath'],'hasContent':!!_0x10a4fc['content']}))}),_0x17bc6e;}catch(_0x255516){throw new Error(_0x3c325b(0x11b)+_0x255516['message']);}}[a0_0x4a8135(0x12c)](){return['actions'];}[a0_0x4a8135(0x10f)](_0x2fc070){const _0x5d7286=a0_0x4a8135,_0x4af72b=[];if(!_0x2fc070[_0x5d7286(0x11f)]||!Array[_0x5d7286(0xe6)](_0x2fc070['actions'])||_0x2fc070['actions'][_0x5d7286(0x14e)]===0x0)_0x4af72b['push'](_0x5d7286(0x12b));else for(const [_0x13e38b,_0x5e6ba8]of _0x2fc070[_0x5d7286(0x11f)]['entries']()){if(!_0x5e6ba8[_0x5d7286(0x14b)]){_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x13e));continue;}switch(_0x5e6ba8[_0x5d7286(0x14b)]){case _0x5d7286(0x147):case'delete':case _0x5d7286(0xe7):case'stats':!_0x5e6ba8['filePath']&&_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x137)+_0x5e6ba8['type']);break;case'write':!_0x5e6ba8['outputPath']&&_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x121));!_0x5e6ba8['content']&&_0x5e6ba8[_0x5d7286(0x135)]!==''&&_0x4af72b[_0x5d7286(0x103)](_0x5d7286(0xf8)+(_0x13e38b+0x1)+':\x20content\x20is\x20required\x20for\x20write');break;case'append':!_0x5e6ba8[_0x5d7286(0x156)]&&_0x4af72b['push']('Action\x20'+(_0x13e38b+0x1)+':\x20file-path\x20is\x20required\x20for\x20append');!_0x5e6ba8['content']&&_0x5e6ba8['content']!==''&&_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+':\x20content\x20is\x20required\x20for\x20append');break;case _0x5d7286(0xfa):case'move':!_0x5e6ba8['sourcePath']&&_0x4af72b['push']('Action\x20'+(_0x13e38b+0x1)+_0x5d7286(0x120)+_0x5e6ba8['type']);!_0x5e6ba8[_0x5d7286(0x14f)]&&_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x177)+_0x5e6ba8['type']);break;case _0x5d7286(0x124):case _0x5d7286(0x13a):!_0x5e6ba8['directory']&&_0x4af72b[_0x5d7286(0x103)](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x117)+_0x5e6ba8['type']);break;default:_0x4af72b[_0x5d7286(0x103)]('Action\x20'+(_0x13e38b+0x1)+':\x20unknown\x20action\x20type:\x20'+_0x5e6ba8['type']);}_0x5e6ba8[_0x5d7286(0x156)]&&!this['isAllowedFileExtension'](_0x5e6ba8[_0x5d7286(0x156)])&&_0x4af72b['push'](_0x5d7286(0xf8)+(_0x13e38b+0x1)+_0x5d7286(0x136)+a0_0x291fbd['extname'](_0x5e6ba8['filePath'])),_0x5e6ba8['outputPath']&&!this[_0x5d7286(0x159)](_0x5e6ba8[_0x5d7286(0x167)])&&_0x4af72b['push']('Action\x20'+(_0x13e38b+0x1)+':\x20file\x20type\x20not\x20allowed:\x20'+a0_0x291fbd[_0x5d7286(0x109)](_0x5e6ba8['outputPath']));}return{'valid':_0x4af72b['length']===0x0,'errors':_0x4af72b};}async['execute'](_0x4f6b6e,_0x479384){const _0x2b534b=a0_0x4a8135;if(!_0x4f6b6e||typeof _0x4f6b6e!==_0x2b534b(0x176))throw new Error(_0x2b534b(0x169));const {actions:_0x4cf380}=_0x4f6b6e;if(!_0x4cf380)throw new Error('Invalid\x20parameters:\x20actions\x20is\x20required.\x20Received\x20params:\x20'+JSON[_0x2b534b(0x142)](Object[_0x2b534b(0x11a)](_0x4f6b6e)));if(!Array[_0x2b534b(0xe6)](_0x4cf380))throw new Error(_0x2b534b(0x134)+typeof _0x4cf380);if(_0x4cf380[_0x2b534b(0x14e)]===0x0)throw new Error('Invalid\x20parameters:\x20actions\x20array\x20is\x20empty');const {projectDir:_0x553cba,agentId:_0xab7ce0,directoryAccess:_0x3adcf3}=_0x479384,_0x1e64e1=_0x3adcf3||this['directoryAccessManager'][_0x2b534b(0x127)]({'workingDirectory':_0x553cba||process[_0x2b534b(0x164)](),'writeEnabledDirectories':[_0x553cba||process['cwd']()],'restrictToProject':!![]});_0x3adcf3&&_0x3adcf3['workingDirectory']?(console[_0x2b534b(0x150)](_0x2b534b(0x16a),_0x3adcf3['workingDirectory']),console[_0x2b534b(0x150)](_0x2b534b(0xf2),JSON[_0x2b534b(0x142)](_0x3adcf3,null,0x2))):(console['log']('FileSystem\x20DEBUG:\x20Using\x20fallback\x20working\x20directory:',_0x553cba||process[_0x2b534b(0x164)]()),console['log'](_0x2b534b(0x174),_0x3adcf3),console['log'](_0x2b534b(0x122),_0x553cba));const _0x5196ae=[];for(const _0x1319c4 of _0x4cf380){try{let _0x1dd747;switch(_0x1319c4['type']){case _0x2b534b(0x147):_0x1dd747=await this['readFile'](_0x1319c4['filePath'],_0x1e64e1,_0x1319c4[_0x2b534b(0xf5)]);break;case _0x2b534b(0x13b):_0x1dd747=await this['writeFile'](_0x1319c4['outputPath'],_0x1319c4[_0x2b534b(0x135)],_0x1e64e1,{'encoding':_0x1319c4[_0x2b534b(0xf5)],'createDirs':_0x1319c4[_0x2b534b(0xf1)]});break;case'append':_0x1dd747=await this['appendToFile'](_0x1319c4['filePath'],_0x1319c4[_0x2b534b(0x135)],_0x1e64e1,_0x1319c4[_0x2b534b(0xf5)]);break;case'delete':_0x1dd747=await this['deleteFile'](_0x1319c4[_0x2b534b(0x156)],_0x1e64e1);break;case'copy':_0x1dd747=await this['copyFile'](_0x1319c4[_0x2b534b(0x112)],_0x1319c4[_0x2b534b(0x14f)],_0x1e64e1);break;case _0x2b534b(0xe2):_0x1dd747=await this['moveFile'](_0x1319c4['sourcePath'],_0x1319c4[_0x2b534b(0x14f)],_0x1e64e1);break;case _0x2b534b(0x124):_0x1dd747=await this[_0x2b534b(0x102)](_0x1319c4['directory'],_0x1e64e1);break;case _0x2b534b(0x13a):_0x1dd747=await this[_0x2b534b(0x16c)](_0x1319c4['directory'],_0x1e64e1);break;case _0x2b534b(0xe7):_0x1dd747=await this['checkExists'](_0x1319c4['filePath'],_0x1e64e1);break;case _0x2b534b(0x152):_0x1dd747=await this[_0x2b534b(0x10a)](_0x1319c4[_0x2b534b(0x156)],_0x1e64e1);break;default:throw new Error('Unknown\x20action\x20type:\x20'+_0x1319c4['type']);}_0x5196ae['push'](_0x1dd747),this[_0x2b534b(0x16e)](_0x1319c4,_0x1dd747,_0x479384['agentId']);}catch(_0x20510a){const _0x8f9687={'success':![],'action':_0x1319c4[_0x2b534b(0x14b)],'error':_0x20510a[_0x2b534b(0xff)],'filePath':_0x1319c4['filePath']||_0x1319c4[_0x2b534b(0x167)]||_0x1319c4['directory']};_0x5196ae[_0x2b534b(0x103)](_0x8f9687),this['addToHistory'](_0x1319c4,_0x8f9687,_0x479384['agentId']);}}return{'success':!![],'actions':_0x5196ae,'executedActions':_0x4cf380[_0x2b534b(0x14e)],'toolUsed':'filesys'};}async['readFile'](_0x5224ab,_0x51a05b,_0x26395e=a0_0x4a8135(0x13d)){const _0x4b6637=a0_0x4a8135,_0xcf98db=this['directoryAccessManager'][_0x4b6637(0x15b)](_0x51a05b),_0x524a69=this[_0x4b6637(0x106)](_0x5224ab,_0xcf98db),_0x505b57=this[_0x4b6637(0x153)][_0x4b6637(0x172)](_0x524a69,_0x51a05b);if(!_0x505b57[_0x4b6637(0x145)])throw new Error(_0x4b6637(0x154)+_0x505b57['reason']+'\x20('+_0x505b57[_0x4b6637(0xe9)]+')');try{const _0x58d2da=await a0_0xa233b7[_0x4b6637(0x123)](_0x524a69);if(_0x58d2da[_0x4b6637(0x12e)]>this[_0x4b6637(0x163)])throw new Error('File\x20too\x20large:\x20'+_0x58d2da[_0x4b6637(0x12e)]+'\x20bytes\x20(max\x20'+this[_0x4b6637(0x163)]+')');const _0x56eb09=await a0_0xa233b7[_0x4b6637(0x12f)](_0x524a69,_0x26395e);return{'success':!![],'action':'read','filePath':this[_0x4b6637(0x153)][_0x4b6637(0xf3)](_0x524a69,_0x51a05b),'content':_0x56eb09,'size':_0x58d2da['size'],'encoding':_0x26395e,'lastModified':_0x58d2da[_0x4b6637(0xf7)][_0x4b6637(0xe4)](),'message':'Read\x20'+_0x58d2da['size']+_0x4b6637(0x133)+_0x5224ab};}catch(_0x3dab67){throw new Error(_0x4b6637(0x115)+_0x5224ab+':\x20'+_0x3dab67[_0x4b6637(0xff)]);}}async['writeFile'](_0x49c506,_0x3b0057,_0x15cd2a,_0x1b1427={}){const _0x17e6d2=a0_0x4a8135,{encoding:encoding='utf8',createDirs:createDirs=!![]}=_0x1b1427,_0x42088c=this['directoryAccessManager'][_0x17e6d2(0x15b)](_0x15cd2a),_0x1e9aa1=this[_0x17e6d2(0x106)](_0x49c506,_0x42088c),_0x28c364=this['directoryAccessManager']['validateWriteAccess'](_0x1e9aa1,_0x15cd2a);if(!_0x28c364['allowed'])throw new Error('Write\x20access\x20denied:\x20'+_0x28c364[_0x17e6d2(0x16f)]+'\x20('+_0x28c364[_0x17e6d2(0xe9)]+')');try{const _0x1c2ecb=Buffer['byteLength'](_0x3b0057,encoding);if(_0x1c2ecb>this['maxFileSize'])throw new Error('Content\x20too\x20large:\x20'+_0x1c2ecb+'\x20bytes\x20(max\x20'+this['maxFileSize']+')');if(createDirs){const _0x15a08c=a0_0x291fbd[_0x17e6d2(0x161)](_0x1e9aa1);await a0_0xa233b7[_0x17e6d2(0x170)](_0x15a08c,{'recursive':!![]});}let _0x1bebb6=null;try{await a0_0xa233b7[_0x17e6d2(0x14d)](_0x1e9aa1),_0x1bebb6=_0x1e9aa1+'.backup-'+Date['now'](),await a0_0xa233b7[_0x17e6d2(0x107)](_0x1e9aa1,_0x1bebb6);}catch{}await a0_0xa233b7['writeFile'](_0x1e9aa1,_0x3b0057,encoding);const _0x1af95a=await a0_0xa233b7[_0x17e6d2(0x123)](_0x1e9aa1),_0x588d2d=this[_0x17e6d2(0x153)][_0x17e6d2(0xf3)](_0x1e9aa1,_0x15cd2a);return{'success':!![],'action':_0x17e6d2(0x13b),'outputPath':_0x588d2d,'fullPath':_0x1e9aa1,'size':_0x1af95a[_0x17e6d2(0x12e)],'encoding':encoding,'backupPath':_0x1bebb6?this[_0x17e6d2(0x153)][_0x17e6d2(0xf3)](_0x1bebb6,_0x15cd2a):null,'backupFullPath':_0x1bebb6||null,'message':'Wrote\x20'+_0x1af95a[_0x17e6d2(0x12e)]+_0x17e6d2(0xee)+_0x1e9aa1};}catch(_0x1bc40c){throw new Error(_0x17e6d2(0x100)+_0x1e9aa1+':\x20'+_0x1bc40c[_0x17e6d2(0xff)]);}}async['appendToFile'](_0x2d3baf,_0x96952c,_0x40ae0e,_0x4bddd9='utf8'){const _0x464f14=a0_0x4a8135,_0x5a629e=this['directoryAccessManager']['getWorkingDirectory'](_0x40ae0e),_0x507118=this[_0x464f14(0x106)](_0x2d3baf,_0x5a629e),_0x13fb8b=this['directoryAccessManager'][_0x464f14(0xfd)](_0x507118,_0x40ae0e);if(!_0x13fb8b['allowed'])throw new Error('Write\x20access\x20denied:\x20'+_0x13fb8b['reason']+'\x20('+_0x13fb8b[_0x464f14(0xe9)]+')');try{let _0x13bd7c=0x0;try{const _0x256308=await a0_0xa233b7['stat'](_0x507118);_0x13bd7c=_0x256308[_0x464f14(0x12e)];}catch{}const _0x36e5cd=Buffer[_0x464f14(0x175)](_0x96952c,_0x4bddd9);if(_0x13bd7c+_0x36e5cd>this['maxFileSize'])throw new Error('File\x20would\x20become\x20too\x20large:\x20'+(_0x13bd7c+_0x36e5cd)+_0x464f14(0x129)+this['maxFileSize']+')');await a0_0xa233b7[_0x464f14(0x126)](_0x507118,_0x96952c,_0x4bddd9);const _0x2277e8=await a0_0xa233b7['stat'](_0x507118),_0x7a03e9=this['directoryAccessManager'][_0x464f14(0xf3)](_0x507118,_0x40ae0e);return{'success':!![],'action':'append','filePath':_0x7a03e9,'fullPath':_0x507118,'appendedBytes':_0x36e5cd,'totalSize':_0x2277e8[_0x464f14(0x12e)],'encoding':_0x4bddd9,'message':'Appended\x20'+_0x36e5cd+'\x20bytes\x20to\x20'+_0x507118};}catch(_0x36df66){throw new Error('Failed\x20to\x20append\x20to\x20file\x20'+_0x507118+':\x20'+_0x36df66['message']);}}async[a0_0x4a8135(0x165)](_0x563345,_0x108b84){const _0x1ce8ee=a0_0x4a8135,_0x1d553c=this[_0x1ce8ee(0x153)][_0x1ce8ee(0x15b)](_0x108b84),_0x53e994=this['resolvePath'](_0x563345,_0x1d553c),_0x4b1762=this[_0x1ce8ee(0x153)][_0x1ce8ee(0xfd)](_0x53e994,_0x108b84);if(!_0x4b1762['allowed'])throw new Error('Delete\x20access\x20denied:\x20'+_0x4b1762[_0x1ce8ee(0x16f)]+'\x20('+_0x4b1762['path']+')');try{const _0x21079e=await a0_0xa233b7['stat'](_0x53e994),_0x3d6890=_0x53e994+'.deleted-backup-'+Date[_0x1ce8ee(0x118)]();await a0_0xa233b7[_0x1ce8ee(0x107)](_0x53e994,_0x3d6890),await a0_0xa233b7['unlink'](_0x53e994);const _0x32294c=this[_0x1ce8ee(0x153)][_0x1ce8ee(0xf3)](_0x53e994,_0x108b84),_0x31b247=this[_0x1ce8ee(0x153)]['createRelativePath'](_0x3d6890,_0x108b84);return{'success':!![],'action':_0x1ce8ee(0x114),'filePath':_0x32294c,'fullPath':_0x53e994,'size':_0x21079e['size'],'backupPath':_0x31b247,'backupFullPath':_0x3d6890,'message':_0x1ce8ee(0xe5)+_0x53e994+'\x20(backup\x20created)'};}catch(_0x38e418){throw new Error(_0x1ce8ee(0x141)+_0x53e994+':\x20'+_0x38e418[_0x1ce8ee(0xff)]);}}async['copyFile'](_0xa4dbf0,_0x597efd,_0x142d16){const _0x5724ac=a0_0x4a8135,_0x1dde45=this['directoryAccessManager'][_0x5724ac(0x15b)](_0x142d16),_0x24de14=this['resolvePath'](_0xa4dbf0,_0x1dde45),_0x586493=this[_0x5724ac(0x106)](_0x597efd,_0x1dde45),_0x12a062=this[_0x5724ac(0x153)][_0x5724ac(0x172)](_0x24de14,_0x142d16);if(!_0x12a062['allowed'])throw new Error(_0x5724ac(0x15d)+_0x12a062['reason']+'\x20('+_0x12a062['path']+')');const _0x3090f1=this[_0x5724ac(0x153)][_0x5724ac(0xfd)](_0x586493,_0x142d16);if(!_0x3090f1['allowed'])throw new Error(_0x5724ac(0xe3)+_0x3090f1['reason']+'\x20('+_0x3090f1['path']+')');try{const _0x5a7bbf=await a0_0xa233b7[_0x5724ac(0x123)](_0x24de14);if(_0x5a7bbf['size']>this[_0x5724ac(0x163)])throw new Error('Source\x20file\x20too\x20large:\x20'+_0x5a7bbf['size']+'\x20bytes');const _0x30cec6=a0_0x291fbd['dirname'](_0x586493);await a0_0xa233b7[_0x5724ac(0x170)](_0x30cec6,{'recursive':!![]}),await a0_0xa233b7['copyFile'](_0x24de14,_0x586493);const _0x13c241=this[_0x5724ac(0x153)][_0x5724ac(0xf3)](_0x24de14,_0x142d16),_0x325294=this['directoryAccessManager'][_0x5724ac(0xf3)](_0x586493,_0x142d16);return{'success':!![],'action':_0x5724ac(0xfa),'sourcePath':_0x13c241,'destPath':_0x325294,'sourceFullPath':_0x24de14,'destFullPath':_0x586493,'size':_0x5a7bbf['size'],'message':_0x5724ac(0x14a)+_0x24de14+_0x5724ac(0x116)+_0x586493};}catch(_0x35c9d9){throw new Error(_0x5724ac(0x10e)+_0x24de14+'\x20to\x20'+_0x586493+':\x20'+_0x35c9d9[_0x5724ac(0xff)]);}}async[a0_0x4a8135(0x13f)](_0x5cbcf6,_0x4ed61f,_0x41f1a6){const _0x32b16d=a0_0x4a8135,_0x131c45=this[_0x32b16d(0x153)]['getWorkingDirectory'](_0x41f1a6),_0x3f46fa=this[_0x32b16d(0x106)](_0x5cbcf6,_0x131c45),_0x1d89af=this[_0x32b16d(0x106)](_0x4ed61f,_0x131c45),_0x113624=this['directoryAccessManager'][_0x32b16d(0x172)](_0x3f46fa,_0x41f1a6);if(!_0x113624['allowed'])throw new Error('Read\x20access\x20denied\x20for\x20source:\x20'+_0x113624['reason']+'\x20('+_0x113624['path']+')');const _0x262d97=this['directoryAccessManager']['validateWriteAccess'](_0x1d89af,_0x41f1a6);if(!_0x262d97['allowed'])throw new Error('Write\x20access\x20denied\x20for\x20destination:\x20'+_0x262d97[_0x32b16d(0x16f)]+'\x20('+_0x262d97['path']+')');try{const _0x588ae9=await a0_0xa233b7['stat'](_0x3f46fa),_0x24646e=a0_0x291fbd['dirname'](_0x1d89af);await a0_0xa233b7['mkdir'](_0x24646e,{'recursive':!![]}),await a0_0xa233b7[_0x32b16d(0x130)](_0x3f46fa,_0x1d89af);const _0x1af727=this[_0x32b16d(0x153)][_0x32b16d(0xf3)](_0x3f46fa,_0x41f1a6),_0x174a00=this[_0x32b16d(0x153)]['createRelativePath'](_0x1d89af,_0x41f1a6);return{'success':!![],'action':'move','sourcePath':_0x1af727,'destPath':_0x174a00,'fullSourcePath':_0x3f46fa,'fullDestPath':_0x1d89af,'size':_0x588ae9['size'],'message':'Moved\x20'+_0x5cbcf6+_0x32b16d(0x116)+_0x4ed61f};}catch(_0x23fe05){throw new Error(_0x32b16d(0x160)+_0x5cbcf6+'\x20to\x20'+_0x4ed61f+':\x20'+_0x23fe05[_0x32b16d(0xff)]);}}async['createDirectory'](_0x8b4ee1,_0x2d2ba1){const _0x47960e=a0_0x4a8135,_0x4bfa97=this[_0x47960e(0x153)][_0x47960e(0x15b)](_0x2d2ba1),_0x3be836=this['resolvePath'](_0x8b4ee1,_0x4bfa97),_0x13b7e4=this['directoryAccessManager'][_0x47960e(0xfd)](_0x3be836,_0x2d2ba1);if(!_0x13b7e4[_0x47960e(0x145)])throw new Error(_0x47960e(0x148)+_0x13b7e4['reason']+'\x20('+_0x13b7e4[_0x47960e(0xe9)]+')');try{await a0_0xa233b7['mkdir'](_0x3be836,{'recursive':!![]});const _0x32772e=this['directoryAccessManager'][_0x47960e(0xf3)](_0x3be836,_0x2d2ba1);return{'success':!![],'action':'create-dir','directory':_0x32772e,'fullPath':_0x3be836,'message':_0x47960e(0x12d)+_0x8b4ee1};}catch(_0x357e2e){throw new Error('Failed\x20to\x20create\x20directory\x20'+_0x8b4ee1+':\x20'+_0x357e2e[_0x47960e(0xff)]);}}async[a0_0x4a8135(0x16c)](_0x500883,_0x282379){const _0x283e3b=a0_0x4a8135,_0xe6159=this[_0x283e3b(0x153)][_0x283e3b(0x15b)](_0x282379),_0x20847b=this['resolvePath'](_0x500883,_0xe6159),_0x47e38d=this['directoryAccessManager'][_0x283e3b(0x172)](_0x20847b,_0x282379);if(!_0x47e38d[_0x283e3b(0x145)])throw new Error('Read\x20access\x20denied:\x20'+_0x47e38d['reason']+'\x20('+_0x47e38d[_0x283e3b(0xe9)]+')');try{const _0x11da56=await a0_0xa233b7['readdir'](_0x20847b,{'withFileTypes':!![]}),_0x2f81ac=[];for(const _0x3908c9 of _0x11da56){const _0x5a18dd=a0_0x291fbd['join'](_0x20847b,_0x3908c9[_0x283e3b(0x128)]),_0xfacd8f=await a0_0xa233b7['stat'](_0x5a18dd);_0x2f81ac[_0x283e3b(0x103)]({'name':_0x3908c9[_0x283e3b(0x128)],'type':_0x3908c9['isDirectory']()?'directory':_0x283e3b(0xec),'size':_0x3908c9[_0x283e3b(0xe1)]()?_0xfacd8f[_0x283e3b(0x12e)]:undefined,'lastModified':_0xfacd8f['mtime'][_0x283e3b(0xe4)](),'permissions':_0xfacd8f['mode'],'isSymlink':_0x3908c9['isSymbolicLink']()});}const _0x5c6e31=this['directoryAccessManager']['createRelativePath'](_0x20847b,_0x282379);return{'success':!![],'action':_0x283e3b(0x13a),'directory':_0x5c6e31,'fullPath':_0x20847b,'contents':_0x2f81ac,'totalItems':_0x2f81ac['length'],'directories':_0x2f81ac[_0x283e3b(0xeb)](_0x304053=>_0x304053['type']===_0x283e3b(0x14c))['length'],'files':_0x2f81ac['filter'](_0xcdbe34=>_0xcdbe34[_0x283e3b(0x14b)]==='file')[_0x283e3b(0x14e)],'message':'Listed\x20'+_0x2f81ac[_0x283e3b(0x14e)]+_0x283e3b(0x13c)+_0x500883};}catch(_0x3241da){throw new Error(_0x283e3b(0x146)+_0x500883+':\x20'+_0x3241da['message']);}}async['checkExists'](_0x248409,_0x3d3ae0){const _0x23e4b9=a0_0x4a8135,_0x3085fd=this['directoryAccessManager']['getWorkingDirectory'](_0x3d3ae0),_0x2259dd=this[_0x23e4b9(0x106)](_0x248409,_0x3085fd),_0x5cb5ab=this['directoryAccessManager']['validateReadAccess'](_0x2259dd,_0x3d3ae0);if(!_0x5cb5ab[_0x23e4b9(0x145)])throw new Error('Read\x20access\x20denied:\x20'+_0x5cb5ab['reason']+'\x20('+_0x5cb5ab[_0x23e4b9(0xe9)]+')');try{const _0x57b79b=await a0_0xa233b7['stat'](_0x2259dd),_0x416867=this['directoryAccessManager'][_0x23e4b9(0xf3)](_0x2259dd,_0x3d3ae0);return{'success':!![],'action':_0x23e4b9(0xe7),'filePath':_0x416867,'fullPath':_0x2259dd,'exists':!![],'type':_0x57b79b[_0x23e4b9(0x157)]()?'directory':_0x23e4b9(0xec),'message':_0x248409+'\x20exists\x20as\x20'+(_0x57b79b[_0x23e4b9(0x157)]()?'directory':_0x23e4b9(0xec))};}catch(_0x25217f){if(_0x25217f[_0x23e4b9(0x15f)]===_0x23e4b9(0x140)){const _0x412aad=this[_0x23e4b9(0x153)][_0x23e4b9(0xf3)](_0x2259dd,_0x3d3ae0);return{'success':!![],'action':'exists','filePath':_0x412aad,'fullPath':_0x2259dd,'exists':![],'message':_0x248409+_0x23e4b9(0x10d)};}throw new Error(_0x23e4b9(0x16b)+_0x248409+':\x20'+_0x25217f[_0x23e4b9(0xff)]);}}async[a0_0x4a8135(0x10a)](_0x22a14d,_0x335e44){const _0x49a790=a0_0x4a8135,_0x5ccf5f=this['directoryAccessManager'][_0x49a790(0x15b)](_0x335e44),_0x17c21c=this[_0x49a790(0x106)](_0x22a14d,_0x5ccf5f),_0x445633=this['directoryAccessManager'][_0x49a790(0x172)](_0x17c21c,_0x335e44);if(!_0x445633['allowed'])throw new Error(_0x49a790(0x154)+_0x445633['reason']+'\x20('+_0x445633[_0x49a790(0xe9)]+')');try{const _0x5c2a75=await a0_0xa233b7['stat'](_0x17c21c),_0x3c660b=this['directoryAccessManager']['createRelativePath'](_0x17c21c,_0x335e44);return{'success':!![],'action':_0x49a790(0x152),'filePath':_0x3c660b,'fullPath':_0x17c21c,'stats':{'size':_0x5c2a75['size'],'type':_0x5c2a75[_0x49a790(0x157)]()?'directory':'file','lastModified':_0x5c2a75[_0x49a790(0xf7)][_0x49a790(0xe4)](),'lastAccessed':_0x5c2a75['atime']['toISOString'](),'created':_0x5c2a75['birthtime'][_0x49a790(0xe4)](),'permissions':_0x5c2a75['mode'],'isSymlink':_0x5c2a75[_0x49a790(0x168)]()},'message':_0x49a790(0x101)+_0x22a14d};}catch(_0x26cd2d){throw new Error(_0x49a790(0x11e)+_0x22a14d+':\x20'+_0x26cd2d['message']);}}['resolvePath'](_0x40165b,_0x22defa){const _0x58f948=a0_0x4a8135;if(a0_0x291fbd['isAbsolute'](_0x40165b))return a0_0x291fbd[_0x58f948(0xf9)](_0x40165b);return a0_0x291fbd[_0x58f948(0xf6)](_0x22defa,_0x40165b);}[a0_0x4a8135(0xf4)](_0x3eb273,_0x1c8d10,_0x496a0f='read'){const _0x9470da=a0_0x4a8135,_0x2d032c=_0x496a0f===_0x9470da(0x13b)?this[_0x9470da(0x153)]['validateWriteAccess'](_0x3eb273,_0x1c8d10):this['directoryAccessManager']['validateReadAccess'](_0x3eb273,_0x1c8d10);if(!_0x2d032c[_0x9470da(0x145)])throw new Error(_0x496a0f+'\x20access\x20denied:\x20'+_0x2d032c['reason']+'\x20('+_0x2d032c['path']+')');return _0x2d032c;}[a0_0x4a8135(0x159)](_0x121998){const _0x1814b3=a0_0x4a8135,_0x31b99c=a0_0x291fbd['extname'](_0x121998)[_0x1814b3(0x105)]();if(this['blockedExtensions'][_0x1814b3(0xfc)](_0x31b99c))return![];if(this['allowedExtensions']&&!this[_0x1814b3(0x155)][_0x1814b3(0xfc)](_0x31b99c))return![];return!![];}[a0_0x4a8135(0x16e)](_0x19b137,_0x4f0ef1,_0x12dc1f){const _0x427a00=a0_0x4a8135,_0xa6d44b={'timestamp':new Date()['toISOString'](),'agentId':_0x12dc1f,'action':_0x19b137[_0x427a00(0x14b)],'filePath':_0x19b137[_0x427a00(0x156)]||_0x19b137['outputPath']||_0x19b137['directory'],'success':_0x4f0ef1['success'],'size':_0x4f0ef1[_0x427a00(0x12e)]};this[_0x427a00(0x151)]['push'](_0xa6d44b),this[_0x427a00(0x151)][_0x427a00(0x14e)]>0xc8&&(this['operationHistory']=this[_0x427a00(0x151)][_0x427a00(0x110)](-0xc8));}[a0_0x4a8135(0x16d)](){const _0x4028f1=a0_0x4a8135;return[_0x4028f1(0x147),'write',_0x4028f1(0xef),_0x4028f1(0x114),'copy','move','create-dir',_0x4028f1(0x13a),'exists',_0x4028f1(0x152)];}['getParameterSchema'](){const _0xddf9ec=a0_0x4a8135;return{'type':'object','properties':{'actions':{'type':'array','minItems':0x1,'items':{'type':'object','properties':{'type':{'type':_0xddf9ec(0x138),'enum':this[_0xddf9ec(0x16d)]()},'filePath':{'type':_0xddf9ec(0x138)},'outputPath':{'type':'string'},'sourcePath':{'type':'string'},'destPath':{'type':_0xddf9ec(0x138)},'directory':{'type':_0xddf9ec(0x138)},'content':{'type':'string'},'encoding':{'type':_0xddf9ec(0x138)},'createDirs':{'type':'boolean'}},'required':['type']}}},'required':['actions']};}['getOperationHistory'](_0x1095f8=null){const _0xc29acc=a0_0x4a8135;if(_0x1095f8)return this['operationHistory'][_0xc29acc(0xeb)](_0x503c94=>_0x503c94['agentId']===_0x1095f8);return[...this[_0xc29acc(0x151)]];}}function a0_0x16d8(_0x361deb,_0x372a6c){_0x361deb=_0x361deb-0xe1;const _0x4755a0=a0_0x4755();let _0x16d8df=_0x4755a0[_0x361deb];if(a0_0x16d8['qiyGGp']===undefined){var _0x4bf62e=function(_0x89574d){const _0x124c58='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x14816d='',_0x2d08cc='';for(let _0xa233b7=0x0,_0x291fbd,_0x17ea40,_0x3cf2f4=0x0;_0x17ea40=_0x89574d['charAt'](_0x3cf2f4++);~_0x17ea40&&(_0x291fbd=_0xa233b7%0x4?_0x291fbd*0x40+_0x17ea40:_0x17ea40,_0xa233b7++%0x4)?_0x14816d+=String['fromCharCode'](0xff&_0x291fbd>>(-0x2*_0xa233b7&0x6)):0x0){_0x17ea40=_0x124c58['indexOf'](_0x17ea40);}for(let _0x3d13dd=0x0,_0x4f26d4=_0x14816d['length'];_0x3d13dd<_0x4f26d4;_0x3d13dd++){_0x2d08cc+='%'+('00'+_0x14816d['charCodeAt'](_0x3d13dd)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x2d08cc);};a0_0x16d8['qQuPCz']=_0x4bf62e,a0_0x16d8['uipKqL']={},a0_0x16d8['qiyGGp']=!![];}const _0x2ee41a=_0x4755a0[0x0],_0x2b20d8=_0x361deb+_0x2ee41a,_0x14ac0a=a0_0x16d8['uipKqL'][_0x2b20d8];return!_0x14ac0a?(_0x16d8df=a0_0x16d8['qQuPCz'](_0x16d8df),a0_0x16d8['uipKqL'][_0x2b20d8]=_0x16d8df):_0x16d8df=_0x14ac0a,_0x16d8df;}export default FileSystemTool;