@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.
- package/README.md +44 -54
- package/bin/cli.js +1 -115
- package/bin/loxia-terminal-v2.js +3 -0
- package/bin/loxia-terminal.js +3 -0
- package/bin/start-with-terminal.js +3 -0
- package/package.json +14 -15
- package/scripts/install-scanners.js +1 -235
- package/src/analyzers/CSSAnalyzer.js +1 -297
- package/src/analyzers/ConfigValidator.js +1 -690
- package/src/analyzers/ESLintAnalyzer.js +1 -320
- package/src/analyzers/JavaScriptAnalyzer.js +1 -261
- package/src/analyzers/PrettierFormatter.js +1 -247
- package/src/analyzers/PythonAnalyzer.js +1 -266
- package/src/analyzers/SecurityAnalyzer.js +1 -729
- package/src/analyzers/TypeScriptAnalyzer.js +1 -247
- package/src/analyzers/codeCloneDetector/analyzer.js +1 -344
- package/src/analyzers/codeCloneDetector/detector.js +1 -203
- package/src/analyzers/codeCloneDetector/index.js +1 -160
- package/src/analyzers/codeCloneDetector/parser.js +1 -199
- package/src/analyzers/codeCloneDetector/reporter.js +1 -148
- package/src/analyzers/codeCloneDetector/scanner.js +1 -59
- package/src/core/agentPool.js +1 -1474
- package/src/core/agentScheduler.js +1 -2147
- package/src/core/contextManager.js +1 -709
- package/src/core/messageProcessor.js +1 -732
- package/src/core/orchestrator.js +1 -548
- package/src/core/stateManager.js +1 -877
- package/src/index.js +1 -631
- package/src/interfaces/cli.js +1 -549
- package/src/interfaces/terminal/__tests__/smoke/advancedFeatures.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agentControl.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/agents.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/components.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/connection.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/enhancements.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/imports.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/messages.test.js +1 -0
- package/src/interfaces/terminal/__tests__/smoke/tools.test.js +1 -0
- package/src/interfaces/terminal/api/apiClient.js +1 -0
- package/src/interfaces/terminal/api/messageRouter.js +1 -0
- package/src/interfaces/terminal/api/session.js +1 -0
- package/src/interfaces/terminal/api/websocket.js +1 -0
- package/src/interfaces/terminal/components/AgentCreator.js +1 -0
- package/src/interfaces/terminal/components/AgentEditor.js +1 -0
- package/src/interfaces/terminal/components/AgentSwitcher.js +1 -0
- package/src/interfaces/terminal/components/ErrorBoundary.js +1 -0
- package/src/interfaces/terminal/components/ErrorPanel.js +1 -0
- package/src/interfaces/terminal/components/Header.js +1 -0
- package/src/interfaces/terminal/components/HelpPanel.js +1 -0
- package/src/interfaces/terminal/components/InputBox.js +1 -0
- package/src/interfaces/terminal/components/Layout.js +1 -0
- package/src/interfaces/terminal/components/LoadingSpinner.js +1 -0
- package/src/interfaces/terminal/components/MessageList.js +1 -0
- package/src/interfaces/terminal/components/MultilineTextInput.js +1 -0
- package/src/interfaces/terminal/components/SearchPanel.js +1 -0
- package/src/interfaces/terminal/components/SettingsPanel.js +1 -0
- package/src/interfaces/terminal/components/StatusBar.js +1 -0
- package/src/interfaces/terminal/components/TextInput.js +1 -0
- package/src/interfaces/terminal/config/agentEditorConstants.js +1 -0
- package/src/interfaces/terminal/config/constants.js +1 -0
- package/src/interfaces/terminal/index.js +1 -0
- package/src/interfaces/terminal/state/useAgentControl.js +1 -0
- package/src/interfaces/terminal/state/useAgents.js +1 -0
- package/src/interfaces/terminal/state/useConnection.js +1 -0
- package/src/interfaces/terminal/state/useMessages.js +1 -0
- package/src/interfaces/terminal/state/useTools.js +1 -0
- package/src/interfaces/terminal/utils/debugLogger.js +1 -0
- package/src/interfaces/terminal/utils/settingsStorage.js +1 -0
- package/src/interfaces/terminal/utils/theme.js +1 -0
- package/src/interfaces/webServer.js +1 -2162
- package/src/modules/fileExplorer/controller.js +1 -280
- package/src/modules/fileExplorer/index.js +1 -37
- package/src/modules/fileExplorer/middleware.js +1 -92
- package/src/modules/fileExplorer/routes.js +1 -125
- package/src/modules/fileExplorer/types.js +1 -44
- package/src/services/aiService.js +1 -1232
- package/src/services/apiKeyManager.js +1 -164
- package/src/services/benchmarkService.js +1 -366
- package/src/services/budgetService.js +1 -539
- package/src/services/contextInjectionService.js +1 -247
- package/src/services/conversationCompactionService.js +1 -637
- package/src/services/errorHandler.js +1 -810
- package/src/services/fileAttachmentService.js +1 -544
- package/src/services/modelRouterService.js +1 -366
- package/src/services/modelsService.js +1 -322
- package/src/services/qualityInspector.js +1 -796
- package/src/services/tokenCountingService.js +1 -536
- package/src/tools/agentCommunicationTool.js +1 -1344
- package/src/tools/agentDelayTool.js +1 -485
- package/src/tools/asyncToolManager.js +1 -604
- package/src/tools/baseTool.js +1 -800
- package/src/tools/browserTool.js +1 -920
- package/src/tools/cloneDetectionTool.js +1 -621
- package/src/tools/dependencyResolverTool.js +1 -1215
- package/src/tools/fileContentReplaceTool.js +1 -875
- package/src/tools/fileSystemTool.js +1 -1107
- package/src/tools/fileTreeTool.js +1 -853
- package/src/tools/imageTool.js +1 -901
- package/src/tools/importAnalyzerTool.js +1 -1060
- package/src/tools/jobDoneTool.js +1 -248
- package/src/tools/seekTool.js +1 -956
- package/src/tools/staticAnalysisTool.js +1 -1778
- package/src/tools/taskManagerTool.js +1 -2873
- package/src/tools/terminalTool.js +1 -2304
- package/src/tools/webTool.js +1 -1430
- package/src/types/agent.js +1 -519
- package/src/types/contextReference.js +1 -972
- package/src/types/conversation.js +1 -730
- package/src/types/toolCommand.js +1 -747
- package/src/utilities/attachmentValidator.js +1 -292
- package/src/utilities/configManager.js +1 -582
- package/src/utilities/constants.js +1 -722
- package/src/utilities/directoryAccessManager.js +1 -535
- package/src/utilities/fileProcessor.js +1 -307
- package/src/utilities/logger.js +1 -436
- package/src/utilities/tagParser.js +1 -1246
- package/src/utilities/toolConstants.js +1 -317
- package/web-ui/build/index.html +2 -2
- package/web-ui/build/static/{index-Dy2bYbOa.css → index-CClD1090.css} +1 -1
- package/web-ui/build/static/{index-CjkkcnFA.js → index-lCBai6dX.js} +66 -67
|
@@ -1,853 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* FileTreeTool - Generate hierarchical file tree representations
|
|
3
|
-
*
|
|
4
|
-
* Purpose:
|
|
5
|
-
* - Generate ASCII tree of project directory structure
|
|
6
|
-
* - Help agents understand project organization
|
|
7
|
-
* - Support filtering by file types (whitelist/blacklist)
|
|
8
|
-
* - Respect directory access permissions
|
|
9
|
-
* - Provide focused views of codebases
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import { BaseTool } from './baseTool.js';
|
|
13
|
-
import { promises as fs } from 'fs';
|
|
14
|
-
import path from 'path';
|
|
15
|
-
|
|
16
|
-
// Configuration constants
|
|
17
|
-
const TREE_CONFIG = {
|
|
18
|
-
// Depth limits
|
|
19
|
-
DEFAULT_MAX_DEPTH: 3,
|
|
20
|
-
MAX_DEPTH_LIMIT: 10, // Absolute maximum to prevent performance issues
|
|
21
|
-
|
|
22
|
-
// Size limits
|
|
23
|
-
MAX_FILES_IN_TREE: 10000, // Maximum files to include
|
|
24
|
-
MAX_DIRECTORIES: 1000, // Maximum directories to scan
|
|
25
|
-
|
|
26
|
-
// Display settings
|
|
27
|
-
SHOW_FILES_DEFAULT: true,
|
|
28
|
-
SHOW_HIDDEN_DEFAULT: false,
|
|
29
|
-
SHOW_SIZES_DEFAULT: false,
|
|
30
|
-
|
|
31
|
-
// Tree symbols
|
|
32
|
-
SYMBOLS: {
|
|
33
|
-
BRANCH: '├── ',
|
|
34
|
-
LAST_BRANCH: '└── ',
|
|
35
|
-
VERTICAL: '│ ',
|
|
36
|
-
INDENT: ' '
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
// Default directories to ignore
|
|
41
|
-
const DEFAULT_IGNORE_DIRECTORIES = [
|
|
42
|
-
'node_modules',
|
|
43
|
-
'.git',
|
|
44
|
-
'dist',
|
|
45
|
-
'build',
|
|
46
|
-
'coverage',
|
|
47
|
-
'.next',
|
|
48
|
-
'.nuxt',
|
|
49
|
-
'.cache',
|
|
50
|
-
'out',
|
|
51
|
-
'target',
|
|
52
|
-
'vendor',
|
|
53
|
-
'bower_components',
|
|
54
|
-
'.vscode',
|
|
55
|
-
'.idea',
|
|
56
|
-
'.vs',
|
|
57
|
-
'__pycache__',
|
|
58
|
-
'venv',
|
|
59
|
-
'env',
|
|
60
|
-
'.env',
|
|
61
|
-
'.pytest_cache',
|
|
62
|
-
'.mypy_cache',
|
|
63
|
-
'eggs',
|
|
64
|
-
'.eggs',
|
|
65
|
-
'lib',
|
|
66
|
-
'lib64',
|
|
67
|
-
'parts',
|
|
68
|
-
'sdist',
|
|
69
|
-
'wheels',
|
|
70
|
-
'.tox',
|
|
71
|
-
'.nox',
|
|
72
|
-
'htmlcov',
|
|
73
|
-
'.hypothesis',
|
|
74
|
-
'tmp',
|
|
75
|
-
'temp',
|
|
76
|
-
'.tmp',
|
|
77
|
-
'.temp'
|
|
78
|
-
];
|
|
79
|
-
|
|
80
|
-
// Default file extensions to ignore (blacklist)
|
|
81
|
-
const DEFAULT_IGNORE_EXTENSIONS = [
|
|
82
|
-
'.map',
|
|
83
|
-
'.min.js',
|
|
84
|
-
'.min.css',
|
|
85
|
-
'.lock',
|
|
86
|
-
'.log',
|
|
87
|
-
'.tmp',
|
|
88
|
-
'.temp',
|
|
89
|
-
'.pyc',
|
|
90
|
-
'.pyo',
|
|
91
|
-
'.pyd',
|
|
92
|
-
'.so',
|
|
93
|
-
'.dll',
|
|
94
|
-
'.dylib',
|
|
95
|
-
'.exe',
|
|
96
|
-
'.obj',
|
|
97
|
-
'.o',
|
|
98
|
-
'.a',
|
|
99
|
-
'.class',
|
|
100
|
-
'.jar',
|
|
101
|
-
'.war'
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
// Common binary/media file extensions to optionally ignore
|
|
105
|
-
const BINARY_EXTENSIONS = [
|
|
106
|
-
'.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg',
|
|
107
|
-
'.pdf', '.zip', '.tar', '.gz', '.rar', '.7z',
|
|
108
|
-
'.mp3', '.mp4', '.avi', '.mov', '.wmv',
|
|
109
|
-
'.woff', '.woff2', '.ttf', '.eot',
|
|
110
|
-
'.bin', '.dat', '.db', '.sqlite'
|
|
111
|
-
];
|
|
112
|
-
|
|
113
|
-
class FileTreeTool extends BaseTool {
|
|
114
|
-
constructor(config = {}, logger = null) {
|
|
115
|
-
super(config, logger);
|
|
116
|
-
|
|
117
|
-
// Tool metadata
|
|
118
|
-
this.requiresProject = true;
|
|
119
|
-
this.isAsync = true;
|
|
120
|
-
this.timeout = config.timeout || 120000; // 2 minutes default
|
|
121
|
-
|
|
122
|
-
// Merge config with defaults
|
|
123
|
-
this.treeConfig = {
|
|
124
|
-
...TREE_CONFIG,
|
|
125
|
-
...config.treeConfig
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// Track statistics during tree generation
|
|
129
|
-
this.stats = {
|
|
130
|
-
filesCount: 0,
|
|
131
|
-
directoriesCount: 0,
|
|
132
|
-
skippedCount: 0
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Get tool description for LLM consumption
|
|
138
|
-
* @returns {string} Tool description
|
|
139
|
-
*/
|
|
140
|
-
getDescription() {
|
|
141
|
-
return `
|
|
142
|
-
File Tree Tool: Generate hierarchical tree representation of project directory structure.
|
|
143
|
-
|
|
144
|
-
XML USAGE:
|
|
145
|
-
<file-tree>
|
|
146
|
-
<directory>src</directory>
|
|
147
|
-
<max-depth>4</max-depth>
|
|
148
|
-
<include-extensions>.js,.jsx,.ts,.tsx</include-extensions>
|
|
149
|
-
<exclude-extensions>.test.js,.spec.js</exclude-extensions>
|
|
150
|
-
<show-files>true</show-files>
|
|
151
|
-
<show-hidden>false</show-hidden>
|
|
152
|
-
</file-tree>
|
|
153
|
-
|
|
154
|
-
JSON USAGE:
|
|
155
|
-
\`\`\`json
|
|
156
|
-
{
|
|
157
|
-
"toolId": "file-tree",
|
|
158
|
-
"directory": "src",
|
|
159
|
-
"maxDepth": 4,
|
|
160
|
-
"includeExtensions": [".js", ".jsx", ".ts", ".tsx"],
|
|
161
|
-
"excludeExtensions": [".test.js", ".spec.js"],
|
|
162
|
-
"showFiles": true,
|
|
163
|
-
"showHidden": false
|
|
164
|
-
}
|
|
165
|
-
\`\`\`
|
|
166
|
-
|
|
167
|
-
PARAMETERS:
|
|
168
|
-
|
|
169
|
-
directory (optional):
|
|
170
|
-
- Directory to scan (default: working directory)
|
|
171
|
-
- Can be relative or absolute path
|
|
172
|
-
- Examples: "src", "src/components", "/home/user/project"
|
|
173
|
-
|
|
174
|
-
maxDepth (optional):
|
|
175
|
-
- Maximum depth to scan (default: ${TREE_CONFIG.DEFAULT_MAX_DEPTH})
|
|
176
|
-
- Range: 1-${TREE_CONFIG.MAX_DEPTH_LIMIT}
|
|
177
|
-
- Deeper = more detail, slower performance
|
|
178
|
-
|
|
179
|
-
includeExtensions (optional - WHITELIST):
|
|
180
|
-
- Include ONLY these file extensions
|
|
181
|
-
- Comma-separated list
|
|
182
|
-
- Examples: ".js,.jsx,.ts,.tsx" or ".py,.pyw"
|
|
183
|
-
- Takes precedence over excludeExtensions
|
|
184
|
-
|
|
185
|
-
excludeExtensions (optional - BLACKLIST):
|
|
186
|
-
- Exclude these file extensions
|
|
187
|
-
- Comma-separated list
|
|
188
|
-
- Examples: ".test.js,.spec.js,.min.js"
|
|
189
|
-
- Only applies if includeExtensions is not set
|
|
190
|
-
|
|
191
|
-
excludeDirectories (optional):
|
|
192
|
-
- Additional directories to ignore
|
|
193
|
-
- Already ignores: node_modules, .git, dist, build, etc.
|
|
194
|
-
- Examples: "tests,fixtures,mocks"
|
|
195
|
-
|
|
196
|
-
showFiles (optional):
|
|
197
|
-
- Whether to show files (default: true)
|
|
198
|
-
- Set to false to show only directory structure
|
|
199
|
-
|
|
200
|
-
showHidden (optional):
|
|
201
|
-
- Whether to show hidden files/folders (default: false)
|
|
202
|
-
- Hidden = starts with '.'
|
|
203
|
-
|
|
204
|
-
showSizes (optional):
|
|
205
|
-
- Whether to show file sizes (default: false)
|
|
206
|
-
- Format: KB, MB
|
|
207
|
-
|
|
208
|
-
ignoreBinaryFiles (optional):
|
|
209
|
-
- Whether to ignore binary/media files (default: false)
|
|
210
|
-
- Ignores: images, videos, archives, fonts, etc.
|
|
211
|
-
|
|
212
|
-
FILTERING STRATEGIES:
|
|
213
|
-
|
|
214
|
-
Strategy 1: WHITELIST (Include Only)
|
|
215
|
-
<file-tree>
|
|
216
|
-
<directory>src</directory>
|
|
217
|
-
<include-extensions>.js,.jsx</include-extensions>
|
|
218
|
-
</file-tree>
|
|
219
|
-
Result: Shows ONLY .js and .jsx files
|
|
220
|
-
|
|
221
|
-
Strategy 2: BLACKLIST (Exclude)
|
|
222
|
-
<file-tree>
|
|
223
|
-
<directory>src</directory>
|
|
224
|
-
<exclude-extensions>.test.js,.spec.js</exclude-extensions>
|
|
225
|
-
</file-tree>
|
|
226
|
-
Result: Shows all files EXCEPT .test.js and .spec.js
|
|
227
|
-
|
|
228
|
-
Strategy 3: COMBINED
|
|
229
|
-
<file-tree>
|
|
230
|
-
<directory>src</directory>
|
|
231
|
-
<include-extensions>.js,.jsx,.ts,.tsx</include-extensions>
|
|
232
|
-
<exclude-extensions>.test.js,.spec.ts</exclude-extensions>
|
|
233
|
-
</file-tree>
|
|
234
|
-
Result: Shows JS/JSX/TS/TSX files, but excludes test files
|
|
235
|
-
|
|
236
|
-
EXAMPLES:
|
|
237
|
-
|
|
238
|
-
Example 1 - Basic tree:
|
|
239
|
-
<file-tree>
|
|
240
|
-
<directory>.</directory>
|
|
241
|
-
</file-tree>
|
|
242
|
-
|
|
243
|
-
Example 2 - JavaScript/TypeScript only:
|
|
244
|
-
<file-tree>
|
|
245
|
-
<directory>src</directory>
|
|
246
|
-
<include-extensions>.js,.jsx,.ts,.tsx</include-extensions>
|
|
247
|
-
<max-depth>5</max-depth>
|
|
248
|
-
</file-tree>
|
|
249
|
-
|
|
250
|
-
Example 3 - Python project structure:
|
|
251
|
-
<file-tree>
|
|
252
|
-
<directory>.</directory>
|
|
253
|
-
<include-extensions>.py</include-extensions>
|
|
254
|
-
<exclude-extensions>.pyc</exclude-extensions>
|
|
255
|
-
<show-files>true</show-files>
|
|
256
|
-
</file-tree>
|
|
257
|
-
|
|
258
|
-
Example 4 - Directory structure only:
|
|
259
|
-
<file-tree>
|
|
260
|
-
<directory>src</directory>
|
|
261
|
-
<show-files>false</show-files>
|
|
262
|
-
<max-depth>3</max-depth>
|
|
263
|
-
</file-tree>
|
|
264
|
-
|
|
265
|
-
Example 5 - Exclude test files:
|
|
266
|
-
<file-tree>
|
|
267
|
-
<directory>src</directory>
|
|
268
|
-
<exclude-extensions>.test.js,.spec.js,.test.ts,.spec.ts</exclude-extensions>
|
|
269
|
-
<exclude-directories>__tests__,tests,specs</exclude-directories>
|
|
270
|
-
</file-tree>
|
|
271
|
-
|
|
272
|
-
OUTPUT FORMAT:
|
|
273
|
-
src/
|
|
274
|
-
├── components/
|
|
275
|
-
│ ├── Header.jsx
|
|
276
|
-
│ ├── Footer.jsx
|
|
277
|
-
│ └── Layout.jsx
|
|
278
|
-
├── utils/
|
|
279
|
-
│ ├── helpers.js
|
|
280
|
-
│ └── config.js
|
|
281
|
-
└── index.js
|
|
282
|
-
|
|
283
|
-
AUTOMATIC IGNORES:
|
|
284
|
-
The tool automatically ignores common directories:
|
|
285
|
-
- node_modules, .git, dist, build, coverage
|
|
286
|
-
- .next, .nuxt, .cache, out, target
|
|
287
|
-
- .vscode, .idea, __pycache__, venv
|
|
288
|
-
And more (see full list in DEFAULT_IGNORE_DIRECTORIES)
|
|
289
|
-
|
|
290
|
-
LIMITATIONS:
|
|
291
|
-
- Maximum depth: ${TREE_CONFIG.MAX_DEPTH_LIMIT}
|
|
292
|
-
- Maximum files: ${TREE_CONFIG.MAX_FILES_IN_TREE}
|
|
293
|
-
- Maximum directories: ${TREE_CONFIG.MAX_DIRECTORIES}
|
|
294
|
-
- Binary files can be filtered with ignoreBinaryFiles option
|
|
295
|
-
|
|
296
|
-
MULTI-DIRECTORY SUPPORT:
|
|
297
|
-
Works with agent's configured accessible directories.
|
|
298
|
-
Validates paths against directoryAccess configuration.
|
|
299
|
-
`;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Parse parameters from tool command content
|
|
304
|
-
* @param {string} content - Raw tool command content
|
|
305
|
-
* @returns {Object} Parsed parameters
|
|
306
|
-
*/
|
|
307
|
-
parseParameters(content) {
|
|
308
|
-
try {
|
|
309
|
-
// Try JSON first
|
|
310
|
-
if (content.trim().startsWith('{')) {
|
|
311
|
-
const parsed = JSON.parse(content);
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
directory: parsed.directory || '.',
|
|
315
|
-
maxDepth: parsed.maxDepth || TREE_CONFIG.DEFAULT_MAX_DEPTH,
|
|
316
|
-
includeExtensions: parsed.includeExtensions || [],
|
|
317
|
-
excludeExtensions: parsed.excludeExtensions || [],
|
|
318
|
-
excludeDirectories: parsed.excludeDirectories || [],
|
|
319
|
-
showFiles: parsed.showFiles !== false,
|
|
320
|
-
showHidden: parsed.showHidden === true,
|
|
321
|
-
showSizes: parsed.showSizes === true,
|
|
322
|
-
ignoreBinaryFiles: parsed.ignoreBinaryFiles === true
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// XML parsing
|
|
327
|
-
const params = {
|
|
328
|
-
directory: '.',
|
|
329
|
-
maxDepth: TREE_CONFIG.DEFAULT_MAX_DEPTH,
|
|
330
|
-
includeExtensions: [],
|
|
331
|
-
excludeExtensions: [],
|
|
332
|
-
excludeDirectories: [],
|
|
333
|
-
showFiles: true,
|
|
334
|
-
showHidden: false,
|
|
335
|
-
showSizes: false,
|
|
336
|
-
ignoreBinaryFiles: false
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
// Extract directory
|
|
340
|
-
const dirPattern = /<directory>(.*?)<\/directory>/i;
|
|
341
|
-
const dirMatch = dirPattern.exec(content);
|
|
342
|
-
if (dirMatch) {
|
|
343
|
-
params.directory = dirMatch[1].trim();
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Extract max-depth
|
|
347
|
-
const depthPattern = /<max-depth>(\d+)<\/max-depth>/i;
|
|
348
|
-
const depthMatch = depthPattern.exec(content);
|
|
349
|
-
if (depthMatch) {
|
|
350
|
-
params.maxDepth = parseInt(depthMatch[1], 10);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Extract include-extensions (whitelist)
|
|
354
|
-
const includePattern = /<include-extensions>(.*?)<\/include-extensions>/i;
|
|
355
|
-
const includeMatch = includePattern.exec(content);
|
|
356
|
-
if (includeMatch) {
|
|
357
|
-
params.includeExtensions = includeMatch[1]
|
|
358
|
-
.split(',')
|
|
359
|
-
.map(ext => ext.trim())
|
|
360
|
-
.filter(ext => ext.length > 0);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// Extract exclude-extensions (blacklist)
|
|
364
|
-
const excludePattern = /<exclude-extensions>(.*?)<\/exclude-extensions>/i;
|
|
365
|
-
const excludeMatch = excludePattern.exec(content);
|
|
366
|
-
if (excludeMatch) {
|
|
367
|
-
params.excludeExtensions = excludeMatch[1]
|
|
368
|
-
.split(',')
|
|
369
|
-
.map(ext => ext.trim())
|
|
370
|
-
.filter(ext => ext.length > 0);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// Extract exclude-directories
|
|
374
|
-
const excludeDirsPattern = /<exclude-directories>(.*?)<\/exclude-directories>/i;
|
|
375
|
-
const excludeDirsMatch = excludeDirsPattern.exec(content);
|
|
376
|
-
if (excludeDirsMatch) {
|
|
377
|
-
params.excludeDirectories = excludeDirsMatch[1]
|
|
378
|
-
.split(',')
|
|
379
|
-
.map(dir => dir.trim())
|
|
380
|
-
.filter(dir => dir.length > 0);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Extract boolean flags
|
|
384
|
-
const showFilesPattern = /<show-files>(.*?)<\/show-files>/i;
|
|
385
|
-
const showFilesMatch = showFilesPattern.exec(content);
|
|
386
|
-
if (showFilesMatch) {
|
|
387
|
-
params.showFiles = showFilesMatch[1].trim().toLowerCase() !== 'false';
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const showHiddenPattern = /<show-hidden>(.*?)<\/show-hidden>/i;
|
|
391
|
-
const showHiddenMatch = showHiddenPattern.exec(content);
|
|
392
|
-
if (showHiddenMatch) {
|
|
393
|
-
params.showHidden = showHiddenMatch[1].trim().toLowerCase() === 'true';
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
const showSizesPattern = /<show-sizes>(.*?)<\/show-sizes>/i;
|
|
397
|
-
const showSizesMatch = showSizesPattern.exec(content);
|
|
398
|
-
if (showSizesMatch) {
|
|
399
|
-
params.showSizes = showSizesMatch[1].trim().toLowerCase() === 'true';
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
const ignoreBinaryPattern = /<ignore-binary-files>(.*?)<\/ignore-binary-files>/i;
|
|
403
|
-
const ignoreBinaryMatch = ignoreBinaryPattern.exec(content);
|
|
404
|
-
if (ignoreBinaryMatch) {
|
|
405
|
-
params.ignoreBinaryFiles = ignoreBinaryMatch[1].trim().toLowerCase() === 'true';
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
return params;
|
|
409
|
-
|
|
410
|
-
} catch (error) {
|
|
411
|
-
this.logger?.error('Failed to parse file-tree parameters', { error: error.message });
|
|
412
|
-
return {
|
|
413
|
-
directory: '.',
|
|
414
|
-
maxDepth: TREE_CONFIG.DEFAULT_MAX_DEPTH,
|
|
415
|
-
includeExtensions: [],
|
|
416
|
-
excludeExtensions: [],
|
|
417
|
-
excludeDirectories: [],
|
|
418
|
-
showFiles: true,
|
|
419
|
-
showHidden: false,
|
|
420
|
-
showSizes: false,
|
|
421
|
-
ignoreBinaryFiles: false,
|
|
422
|
-
parseError: error.message
|
|
423
|
-
};
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Get required parameters
|
|
429
|
-
* @returns {Array<string>} Array of required parameter names
|
|
430
|
-
*/
|
|
431
|
-
getRequiredParameters() {
|
|
432
|
-
return []; // All parameters are optional
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* Custom parameter validation
|
|
437
|
-
* @param {Object} params - Parameters to validate
|
|
438
|
-
* @returns {Object} Validation result
|
|
439
|
-
*/
|
|
440
|
-
customValidateParameters(params) {
|
|
441
|
-
const errors = [];
|
|
442
|
-
|
|
443
|
-
// Validate maxDepth
|
|
444
|
-
if (params.maxDepth !== undefined) {
|
|
445
|
-
if (typeof params.maxDepth !== 'number' || params.maxDepth < 1) {
|
|
446
|
-
errors.push('max-depth must be a positive number');
|
|
447
|
-
} else if (params.maxDepth > this.treeConfig.MAX_DEPTH_LIMIT) {
|
|
448
|
-
errors.push(`max-depth cannot exceed ${this.treeConfig.MAX_DEPTH_LIMIT}`);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Validate directory path
|
|
453
|
-
if (params.directory && params.directory.includes('..')) {
|
|
454
|
-
errors.push('Path traversal (..) not allowed for security');
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// Validate includeExtensions format
|
|
458
|
-
if (params.includeExtensions !== undefined && params.includeExtensions !== null) {
|
|
459
|
-
if (!Array.isArray(params.includeExtensions)) {
|
|
460
|
-
errors.push('includeExtensions must be an array');
|
|
461
|
-
} else {
|
|
462
|
-
for (const ext of params.includeExtensions) {
|
|
463
|
-
if (!ext.startsWith('.')) {
|
|
464
|
-
errors.push(`Extension "${ext}" must start with a dot (e.g., ".js")`);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Validate excludeExtensions format
|
|
471
|
-
if (params.excludeExtensions !== undefined && params.excludeExtensions !== null) {
|
|
472
|
-
if (!Array.isArray(params.excludeExtensions)) {
|
|
473
|
-
errors.push('excludeExtensions must be an array');
|
|
474
|
-
} else {
|
|
475
|
-
for (const ext of params.excludeExtensions) {
|
|
476
|
-
if (!ext.startsWith('.')) {
|
|
477
|
-
errors.push(`Extension "${ext}" must start with a dot (e.g., ".js")`);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Validate excludeDirectories format
|
|
484
|
-
if (params.excludeDirectories !== undefined && params.excludeDirectories !== null) {
|
|
485
|
-
if (!Array.isArray(params.excludeDirectories)) {
|
|
486
|
-
errors.push('excludeDirectories must be an array');
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Throw error if validation fails
|
|
491
|
-
if (errors.length > 0) {
|
|
492
|
-
throw new Error(`Parameter validation failed: ${errors.join(', ')}`);
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
return {
|
|
496
|
-
valid: true,
|
|
497
|
-
errors: []
|
|
498
|
-
};
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Execute tool with parsed parameters
|
|
503
|
-
* @param {Object} params - Parsed parameters
|
|
504
|
-
* @param {Object} context - Execution context
|
|
505
|
-
* @returns {Promise<Object>} Execution result
|
|
506
|
-
*/
|
|
507
|
-
async execute(params, context) {
|
|
508
|
-
// Extract params with defaults
|
|
509
|
-
const {
|
|
510
|
-
directory = '.',
|
|
511
|
-
maxDepth = TREE_CONFIG.DEFAULT_MAX_DEPTH,
|
|
512
|
-
includeExtensions = [],
|
|
513
|
-
excludeExtensions = [],
|
|
514
|
-
excludeDirectories = [],
|
|
515
|
-
showFiles = true,
|
|
516
|
-
showHidden = false,
|
|
517
|
-
showSizes = false,
|
|
518
|
-
ignoreBinaryFiles = false
|
|
519
|
-
} = params;
|
|
520
|
-
const { projectDir, agentId, directoryAccess } = context;
|
|
521
|
-
|
|
522
|
-
// Determine working directory (respect multi-directory access)
|
|
523
|
-
let workingDirectory = projectDir || process.cwd();
|
|
524
|
-
|
|
525
|
-
if (directoryAccess && directoryAccess.workingDirectory) {
|
|
526
|
-
workingDirectory = directoryAccess.workingDirectory;
|
|
527
|
-
this.logger?.info('Using agent configured working directory', {
|
|
528
|
-
workingDirectory: directoryAccess.workingDirectory,
|
|
529
|
-
agentId
|
|
530
|
-
});
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
// Resolve target directory
|
|
534
|
-
const targetDir = path.isAbsolute(directory)
|
|
535
|
-
? directory
|
|
536
|
-
: path.resolve(workingDirectory, directory);
|
|
537
|
-
|
|
538
|
-
// Validate directory exists
|
|
539
|
-
try {
|
|
540
|
-
const stats = await fs.stat(targetDir);
|
|
541
|
-
if (!stats.isDirectory()) {
|
|
542
|
-
throw new Error('Path is not a directory');
|
|
543
|
-
}
|
|
544
|
-
} catch (error) {
|
|
545
|
-
throw new Error(`Directory does not exist or is inaccessible: ${directory}`);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
this.logger?.info('Generating file tree', {
|
|
549
|
-
directory,
|
|
550
|
-
targetDir,
|
|
551
|
-
maxDepth,
|
|
552
|
-
includeExtensions: includeExtensions?.length || 0,
|
|
553
|
-
excludeExtensions: excludeExtensions?.length || 0,
|
|
554
|
-
agentId
|
|
555
|
-
});
|
|
556
|
-
|
|
557
|
-
// Reset statistics
|
|
558
|
-
this.stats = {
|
|
559
|
-
filesCount: 0,
|
|
560
|
-
directoriesCount: 0,
|
|
561
|
-
skippedCount: 0
|
|
562
|
-
};
|
|
563
|
-
|
|
564
|
-
// Build ignore lists (ensure arrays exist)
|
|
565
|
-
const ignoreDirs = [...DEFAULT_IGNORE_DIRECTORIES, ...(excludeDirectories || [])];
|
|
566
|
-
const ignoreExts = [...DEFAULT_IGNORE_EXTENSIONS];
|
|
567
|
-
|
|
568
|
-
if (ignoreBinaryFiles) {
|
|
569
|
-
ignoreExts.push(...BINARY_EXTENSIONS);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
// Generate tree (ensure arrays exist)
|
|
573
|
-
const tree = await this.buildTree(
|
|
574
|
-
targetDir,
|
|
575
|
-
targetDir,
|
|
576
|
-
0,
|
|
577
|
-
maxDepth,
|
|
578
|
-
ignoreDirs,
|
|
579
|
-
includeExtensions || [],
|
|
580
|
-
[...(excludeExtensions || []), ...ignoreExts],
|
|
581
|
-
showFiles,
|
|
582
|
-
showHidden,
|
|
583
|
-
showSizes
|
|
584
|
-
);
|
|
585
|
-
|
|
586
|
-
// Format tree as string
|
|
587
|
-
const treeString = this.formatTree(tree);
|
|
588
|
-
|
|
589
|
-
// Generate summary
|
|
590
|
-
const summary = this.generateSummary(directory, this.stats, maxDepth);
|
|
591
|
-
|
|
592
|
-
return {
|
|
593
|
-
success: true,
|
|
594
|
-
directory: targetDir,
|
|
595
|
-
tree: treeString,
|
|
596
|
-
summary,
|
|
597
|
-
maxDepth,
|
|
598
|
-
totalFiles: this.stats.filesCount,
|
|
599
|
-
totalDirectories: this.stats.directoriesCount,
|
|
600
|
-
skippedCount: this.stats.skippedCount,
|
|
601
|
-
statistics: { ...this.stats },
|
|
602
|
-
toolUsed: 'file-tree'
|
|
603
|
-
};
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
/**
|
|
607
|
-
* Build tree data structure recursively
|
|
608
|
-
* @param {string} basePath - Base path for relative calculations
|
|
609
|
-
* @param {string} currentPath - Current directory being processed
|
|
610
|
-
* @param {number} currentDepth - Current depth in tree
|
|
611
|
-
* @param {number} maxDepth - Maximum depth to scan
|
|
612
|
-
* @param {Array<string>} ignoreDirs - Directories to ignore
|
|
613
|
-
* @param {Array<string>} includeExts - Extensions to include (whitelist)
|
|
614
|
-
* @param {Array<string>} excludeExts - Extensions to exclude (blacklist)
|
|
615
|
-
* @param {boolean} showFiles - Whether to show files
|
|
616
|
-
* @param {boolean} showHidden - Whether to show hidden files/folders
|
|
617
|
-
* @param {boolean} showSizes - Whether to show file sizes
|
|
618
|
-
* @returns {Promise<Object>} Tree node
|
|
619
|
-
* @private
|
|
620
|
-
*/
|
|
621
|
-
async buildTree(
|
|
622
|
-
basePath,
|
|
623
|
-
currentPath,
|
|
624
|
-
currentDepth,
|
|
625
|
-
maxDepth,
|
|
626
|
-
ignoreDirs,
|
|
627
|
-
includeExts,
|
|
628
|
-
excludeExts,
|
|
629
|
-
showFiles,
|
|
630
|
-
showHidden,
|
|
631
|
-
showSizes
|
|
632
|
-
) {
|
|
633
|
-
// Check depth limit
|
|
634
|
-
if (currentDepth > maxDepth) {
|
|
635
|
-
return null;
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
// Check directory count limit
|
|
639
|
-
if (this.stats.directoriesCount >= this.treeConfig.MAX_DIRECTORIES) {
|
|
640
|
-
this.logger?.warn('Maximum directory count reached', {
|
|
641
|
-
maxDirectories: this.treeConfig.MAX_DIRECTORIES
|
|
642
|
-
});
|
|
643
|
-
return null;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
try {
|
|
647
|
-
const entries = await fs.readdir(currentPath, { withFileTypes: true });
|
|
648
|
-
|
|
649
|
-
const node = {
|
|
650
|
-
name: currentDepth === 0 ? path.basename(currentPath) + '/' : path.basename(currentPath),
|
|
651
|
-
path: path.relative(basePath, currentPath),
|
|
652
|
-
type: 'directory',
|
|
653
|
-
children: []
|
|
654
|
-
};
|
|
655
|
-
|
|
656
|
-
this.stats.directoriesCount++;
|
|
657
|
-
|
|
658
|
-
for (const entry of entries) {
|
|
659
|
-
// Check file count limit
|
|
660
|
-
if (this.stats.filesCount >= this.treeConfig.MAX_FILES_IN_TREE) {
|
|
661
|
-
this.logger?.warn('Maximum file count reached', {
|
|
662
|
-
maxFiles: this.treeConfig.MAX_FILES_IN_TREE
|
|
663
|
-
});
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Skip hidden files/folders if not showing hidden
|
|
668
|
-
if (!showHidden && entry.name.startsWith('.')) {
|
|
669
|
-
this.stats.skippedCount++;
|
|
670
|
-
continue;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
const entryPath = path.join(currentPath, entry.name);
|
|
674
|
-
|
|
675
|
-
if (entry.isDirectory()) {
|
|
676
|
-
// Skip ignored directories
|
|
677
|
-
if (ignoreDirs.includes(entry.name)) {
|
|
678
|
-
this.stats.skippedCount++;
|
|
679
|
-
continue;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
// Recursively build subtree
|
|
683
|
-
const subTree = await this.buildTree(
|
|
684
|
-
basePath,
|
|
685
|
-
entryPath,
|
|
686
|
-
currentDepth + 1,
|
|
687
|
-
maxDepth,
|
|
688
|
-
ignoreDirs,
|
|
689
|
-
includeExts,
|
|
690
|
-
excludeExts,
|
|
691
|
-
showFiles,
|
|
692
|
-
showHidden,
|
|
693
|
-
showSizes
|
|
694
|
-
);
|
|
695
|
-
|
|
696
|
-
if (subTree && (subTree.children.length > 0 || currentDepth === 0)) {
|
|
697
|
-
node.children.push(subTree);
|
|
698
|
-
}
|
|
699
|
-
} else if (entry.isFile() && showFiles) {
|
|
700
|
-
// Files are children of current directory, so they're at currentDepth + 1
|
|
701
|
-
// Don't show files if they would exceed maxDepth
|
|
702
|
-
if (currentDepth + 1 > maxDepth) {
|
|
703
|
-
continue;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
const ext = path.extname(entry.name);
|
|
707
|
-
|
|
708
|
-
// WHITELIST: If includeExtensions is specified, ONLY include those
|
|
709
|
-
if (includeExts.length > 0) {
|
|
710
|
-
if (!includeExts.includes(ext)) {
|
|
711
|
-
this.stats.skippedCount++;
|
|
712
|
-
continue;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
// BLACKLIST: Otherwise, exclude based on excludeExtensions
|
|
716
|
-
else if (excludeExts.includes(ext)) {
|
|
717
|
-
this.stats.skippedCount++;
|
|
718
|
-
continue;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// Get file size if requested
|
|
722
|
-
let sizeInfo = '';
|
|
723
|
-
if (showSizes) {
|
|
724
|
-
try {
|
|
725
|
-
const stats = await fs.stat(entryPath);
|
|
726
|
-
sizeInfo = ` (${this.formatFileSize(stats.size)})`;
|
|
727
|
-
} catch (error) {
|
|
728
|
-
// Ignore size errors
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
node.children.push({
|
|
733
|
-
name: entry.name + sizeInfo,
|
|
734
|
-
path: path.relative(basePath, entryPath),
|
|
735
|
-
type: 'file',
|
|
736
|
-
ext
|
|
737
|
-
});
|
|
738
|
-
|
|
739
|
-
this.stats.filesCount++;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
// Sort children: directories first, then files, both alphabetically
|
|
744
|
-
node.children.sort((a, b) => {
|
|
745
|
-
if (a.type === b.type) {
|
|
746
|
-
return a.name.localeCompare(b.name);
|
|
747
|
-
}
|
|
748
|
-
return a.type === 'directory' ? -1 : 1;
|
|
749
|
-
});
|
|
750
|
-
|
|
751
|
-
return node;
|
|
752
|
-
|
|
753
|
-
} catch (error) {
|
|
754
|
-
this.logger?.error('Error building tree', {
|
|
755
|
-
currentPath,
|
|
756
|
-
error: error.message
|
|
757
|
-
});
|
|
758
|
-
return {
|
|
759
|
-
name: path.basename(currentPath),
|
|
760
|
-
path: path.relative(basePath, currentPath),
|
|
761
|
-
type: 'directory',
|
|
762
|
-
error: error.message,
|
|
763
|
-
children: []
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
/**
|
|
769
|
-
* Format tree as ASCII string
|
|
770
|
-
* @param {Object} node - Tree node
|
|
771
|
-
* @param {string} prefix - Prefix for current line
|
|
772
|
-
* @param {boolean} isLast - Whether this is the last child
|
|
773
|
-
* @param {boolean} isRoot - Whether this is the root node
|
|
774
|
-
* @returns {string} Formatted tree string
|
|
775
|
-
* @private
|
|
776
|
-
*/
|
|
777
|
-
formatTree(node, prefix = '', isLast = true, isRoot = true) {
|
|
778
|
-
if (!node) return '';
|
|
779
|
-
|
|
780
|
-
const symbols = this.treeConfig.SYMBOLS;
|
|
781
|
-
let result = '';
|
|
782
|
-
|
|
783
|
-
// Root node special case
|
|
784
|
-
if (isRoot) {
|
|
785
|
-
result = `${node.name}\n`;
|
|
786
|
-
} else {
|
|
787
|
-
result = `${prefix}${isLast ? symbols.LAST_BRANCH : symbols.BRANCH}${node.name}\n`;
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
// Add children
|
|
791
|
-
if (node.children && node.children.length > 0) {
|
|
792
|
-
const childPrefix = isRoot ? '' : prefix + (isLast ? symbols.INDENT : symbols.VERTICAL);
|
|
793
|
-
|
|
794
|
-
node.children.forEach((child, index) => {
|
|
795
|
-
const isLastChild = index === node.children.length - 1;
|
|
796
|
-
result += this.formatTree(child, childPrefix, isLastChild, false);
|
|
797
|
-
});
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return result;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
/**
|
|
804
|
-
* Format file size in human-readable format
|
|
805
|
-
* @param {number} bytes - File size in bytes
|
|
806
|
-
* @returns {string} Formatted size
|
|
807
|
-
* @private
|
|
808
|
-
*/
|
|
809
|
-
formatFileSize(bytes) {
|
|
810
|
-
const KB = 1024;
|
|
811
|
-
const MB = KB * 1024;
|
|
812
|
-
const GB = MB * 1024;
|
|
813
|
-
|
|
814
|
-
if (bytes >= GB) {
|
|
815
|
-
return `${(bytes / GB).toFixed(2)} GB`;
|
|
816
|
-
} else if (bytes >= MB) {
|
|
817
|
-
return `${(bytes / MB).toFixed(2)} MB`;
|
|
818
|
-
} else if (bytes >= KB) {
|
|
819
|
-
return `${(bytes / KB).toFixed(2)} KB`;
|
|
820
|
-
} else {
|
|
821
|
-
return `${bytes} B`;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
/**
|
|
826
|
-
* Generate summary text
|
|
827
|
-
* @param {string} directory - Directory scanned
|
|
828
|
-
* @param {Object} stats - Statistics object
|
|
829
|
-
* @param {number} maxDepth - Maximum depth used
|
|
830
|
-
* @returns {string} Summary text
|
|
831
|
-
* @private
|
|
832
|
-
*/
|
|
833
|
-
generateSummary(directory, stats, maxDepth) {
|
|
834
|
-
return `
|
|
835
|
-
Directory: ${directory}
|
|
836
|
-
Max Depth: ${maxDepth}
|
|
837
|
-
Files: ${stats.filesCount}
|
|
838
|
-
Directories: ${stats.directoriesCount}
|
|
839
|
-
Skipped: ${stats.skippedCount}
|
|
840
|
-
`.trim();
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* Resource cleanup
|
|
845
|
-
* @param {string} operationId - Operation identifier
|
|
846
|
-
*/
|
|
847
|
-
async cleanup(operationId) {
|
|
848
|
-
// No persistent resources to clean up
|
|
849
|
-
this.logger?.info('File tree tool cleanup completed', { operationId });
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
export default FileTreeTool;
|
|
1
|
+
const a0_0x425ea5=a0_0xa249;(function(_0x4226de,_0xe54998){const _0x265593=a0_0xa249,_0x7448d4=_0x4226de();while(!![]){try{const _0xc78747=-parseInt(_0x265593(0x130))/0x1*(-parseInt(_0x265593(0x166))/0x2)+-parseInt(_0x265593(0x17c))/0x3*(-parseInt(_0x265593(0x13f))/0x4)+-parseInt(_0x265593(0x167))/0x5*(parseInt(_0x265593(0x139))/0x6)+parseInt(_0x265593(0x169))/0x7+parseInt(_0x265593(0x149))/0x8*(-parseInt(_0x265593(0x126))/0x9)+parseInt(_0x265593(0x15f))/0xa*(-parseInt(_0x265593(0x17e))/0xb)+parseInt(_0x265593(0x15c))/0xc;if(_0xc78747===_0xe54998)break;else _0x7448d4['push'](_0x7448d4['shift']());}catch(_0x33e2d8){_0x7448d4['push'](_0x7448d4['shift']());}}}(a0_0x9252,0x65472));import{BaseTool}from'./baseTool.js';function a0_0xa249(_0x49dda3,_0x16d430){_0x49dda3=_0x49dda3-0x11c;const _0x925281=a0_0x9252();let _0xa2497c=_0x925281[_0x49dda3];if(a0_0xa249['junlxP']===undefined){var _0x1a3964=function(_0x47b371){const _0x3c4b01='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0xf730f6='',_0x50cfc0='';for(let _0x3648b7=0x0,_0x59378d,_0x1e3878,_0x154cd9=0x0;_0x1e3878=_0x47b371['charAt'](_0x154cd9++);~_0x1e3878&&(_0x59378d=_0x3648b7%0x4?_0x59378d*0x40+_0x1e3878:_0x1e3878,_0x3648b7++%0x4)?_0xf730f6+=String['fromCharCode'](0xff&_0x59378d>>(-0x2*_0x3648b7&0x6)):0x0){_0x1e3878=_0x3c4b01['indexOf'](_0x1e3878);}for(let _0x8d5a52=0x0,_0x47ab82=_0xf730f6['length'];_0x8d5a52<_0x47ab82;_0x8d5a52++){_0x50cfc0+='%'+('00'+_0xf730f6['charCodeAt'](_0x8d5a52)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x50cfc0);};a0_0xa249['aoYrZJ']=_0x1a3964,a0_0xa249['DXFTpH']={},a0_0xa249['junlxP']=!![];}const _0x363199=_0x925281[0x0],_0x4d770b=_0x49dda3+_0x363199,_0x4ebad6=a0_0xa249['DXFTpH'][_0x4d770b];return!_0x4ebad6?(_0xa2497c=a0_0xa249['aoYrZJ'](_0xa2497c),a0_0xa249['DXFTpH'][_0x4d770b]=_0xa2497c):_0xa2497c=_0x4ebad6,_0xa2497c;}import{promises as a0_0xf730f6}from'fs';function a0_0x9252(){const _0x2ce180=['revgqvvmvf9nqvHFrevqveG','lMDPzG','rxjYB3iGyNvPBgrPBMCGDhjLzq','Dg1W','lNb5DgvZDf9JywnOzq','kqOGic0GuMfUz2u6ideT','tufyx0zjtevtx0Lox1rsruu','Aw5JBhvKzxm','zxHJBhvKzuv4DgvUC2LVBNmGBxvZDcbIzsbHBIbHCNjHEq','Dhj1zq','BNvTyMvY','zgLYzwn0B3jPzxndB3vUDa','D2HLzwXZ','C3rHCNrZv2L0Aa','lMf2Aq','zMLSDgvY','lM1WmW','zM9YBwf0vhjLzq','lMnSyxnZ','CgfYC2vqyxjHBwv0zxjZ','DgfYz2v0','lNbUzW','lNzZ','yM93zxjFy29TCg9Uzw50CW','Bwf4rgvWDgG','Bg9JywXLq29TCgfYzq','lNDTDG','y2HPBgrYzw4','zMLSzq','cI0Gtwf4Aw11BsbMAwXLCZOG','CMvHzgrPCG','Dg9mB3DLCKnHC2u','lMvNz3m','lNPPCa','iIbTDxn0ihn0yxj0ihDPDgGGysbKB3qGkguUzY4SiciUANmIkq','lNnV','C2HVD0zPBgvZ','mZyWndK1qw1fz0T4','AxneAxjLy3rVCNK','yNvPBgruCMvL','Bg9Nz2vY','zgLZDa','y292zxjHz2u','CMvXDwLYzxnqCM9Qzwn0','zxHLyW','C2TPChbLzenVDw50','DhjLzunVBMzPzW','ntmXnJi1r1Lzy0Xl','CMvSyxrPDMu','AM9PBG','BgvUz3rO','DhjPBq','DMvUzg9Y','lM1Wna','Dg9gAxHLza','zM9YBwf0rMLSzvnPEMu','nduYmJjfwNvVENi','lMrI','zxHJBhvKzurPCMvJDg9YAwvZig11C3qGyMuGyw4GyxjYyxK','ChvZAa','D2fYBG','zxHJBhvKzuv4DgvUC2LVBNm','nZq2ohHZv1rYDq','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','lM5LEhq','C3rHDhm','Aw5MBW','lM1HCa','lMH5Cg90AgvZAxm','lM1PBI5JC3m','zMLSzxndB3vUDa','lMrSBa','mtm2wLLSq2zo','Aw5JBhvKzuv4DgvUC2LVBNmGBxvZDcbIzsbHBIbHCNjHEq','lMvUDG','lMvVDa','zxHLy3v0zq','lNrLBxa','BwfW','lM1PBI5QCW','cKrPCMvJDg9YAwvZoIa','C2HVD1nPEMvZ','DgLTzw91Da','lJD6','CgfYC2u','D29YA2LUz0rPCMvJDg9YEq','twf4Aw11BsbMAwXLignVDw50ihjLywnOzwq','rMLSzsb0CMvLihrVB2WGy2XLyw51CcbJB21WBgv0zwq','lNzZy29Kzq','ugfYyw1LDgvYihzHBgLKyxrPB24GzMfPBgvKoIa','AxngAwXL','ndqZmteYmhvKsNvPta','zwDNCW','qLjbtKni','mtq0mhHcrNryrW','lNr0zG','lMjTCa','ieTc','AxnbC3LUyW','lNrHCG','z2v0rgvZy3jPChrPB24','mMPMwePQtG','mtG1A0vtsuPP','Aw5JBhvKzuv4DgvUC2LVBNm','ndG2mtu3mer6sgTZwq','yNvPBgq','zMLSzs10CMvL','lNrTCa','tufyx0rfufrix0XjtuLu','AwDUB3jLqMLUyxj5rMLSzxm','cKzPBgvZoIa','lNn2zW','lNb5BW','C3rHDa','CMvZB2X2zq','BgLI','BwvZC2fNzq','C3bSAxq','lMrHDa','lMv4zq','lMPWzW','lNb5yW','lNb5za','m29Trw1KqW','zM9YrwfJAa','mtCWmdzKq3PkDK0','z2v0uMvXDwLYzwrqyxjHBwv0zxjZ','cKrPCMvJDg9YEtOG','BMfTzq','vxnPBMCGywDLBNqGy29UzMLNDxjLzcb3B3jRAw5NigrPCMvJDg9YEq','rgLYzwn0B3j5igrVzxmGBM90igv4Axn0ig9YigLZigLUywnJzxnZAwjSztOG','zgLYzwn0B3j5'];a0_0x9252=function(){return _0x2ce180;};return a0_0x9252();}import a0_0x50cfc0 from'path';const TREE_CONFIG={'DEFAULT_MAX_DEPTH':0x3,'MAX_DEPTH_LIMIT':0xa,'MAX_FILES_IN_TREE':0x2710,'MAX_DIRECTORIES':0x3e8,'SHOW_FILES_DEFAULT':!![],'SHOW_HIDDEN_DEFAULT':![],'SHOW_SIZES_DEFAULT':![],'SYMBOLS':{'BRANCH':'├──\x20','LAST_BRANCH':'└──\x20','VERTICAL':'│\x20\x20\x20','INDENT':'\x20\x20\x20\x20'}},DEFAULT_IGNORE_DIRECTORIES=['node_modules','.git',a0_0x425ea5(0x12a),a0_0x425ea5(0x16a),a0_0x425ea5(0x12b),a0_0x425ea5(0x141),'.nuxt','.cache','out',a0_0x425ea5(0x199),a0_0x425ea5(0x135),a0_0x425ea5(0x19c),a0_0x425ea5(0x159),'.idea',a0_0x425ea5(0x19b),'__pycache__','venv','env',a0_0x425ea5(0x14b),a0_0x425ea5(0x189),'.mypy_cache',a0_0x425ea5(0x15d),a0_0x425ea5(0x121),a0_0x425ea5(0x174),'lib64','parts','sdist',a0_0x425ea5(0x191),'.tox','.nox','htmlcov',a0_0x425ea5(0x145),a0_0x425ea5(0x188),'temp',a0_0x425ea5(0x16c),a0_0x425ea5(0x14e)],DEFAULT_IGNORE_EXTENSIONS=[a0_0x425ea5(0x144),a0_0x425ea5(0x150),a0_0x425ea5(0x146),'.lock','.log',a0_0x425ea5(0x16c),'.temp',a0_0x425ea5(0x17a),a0_0x425ea5(0x171),a0_0x425ea5(0x17b),a0_0x425ea5(0x124),a0_0x425ea5(0x148),'.dylib',a0_0x425ea5(0x178),'.obj','.o','.a',a0_0x425ea5(0x197),'.jar','.war'],BINARY_EXTENSIONS=[a0_0x425ea5(0x19a),a0_0x425ea5(0x179),'.jpeg',a0_0x425ea5(0x186),a0_0x425ea5(0x161),'.ico',a0_0x425ea5(0x170),'.pdf',a0_0x425ea5(0x122),a0_0x425ea5(0x164),'.gz','.rar',a0_0x425ea5(0x154),a0_0x425ea5(0x195),a0_0x425ea5(0x136),a0_0x425ea5(0x193),'.mov',a0_0x425ea5(0x19f),'.woff','.woff2',a0_0x425ea5(0x160),a0_0x425ea5(0x14c),'.bin',a0_0x425ea5(0x177),a0_0x425ea5(0x13a),'.sqlite'];class FileTreeTool extends BaseTool{constructor(_0x3648b7={},_0x59378d=null){const _0x54f417=a0_0x425ea5;super(_0x3648b7,_0x59378d),this[_0x54f417(0x12c)]=!![],this[_0x54f417(0x163)]=!![],this[_0x54f417(0x153)]=_0x3648b7[_0x54f417(0x153)]||0x1d4c0,this[_0x54f417(0x12f)]={...TREE_CONFIG,..._0x3648b7['treeConfig']},this[_0x54f417(0x142)]={'filesCount':0x0,'directoriesCount':0x0,'skippedCount':0x0};}[a0_0x425ea5(0x165)](){const _0x520739=a0_0x425ea5;return'\x0aFile\x20Tree\x20Tool:\x20Generate\x20hierarchical\x20tree\x20representation\x20of\x20project\x20directory\x20structure.\x0a\x0aXML\x20USAGE:\x0a<file-tree>\x0a\x20\x20<directory>src</directory>\x0a\x20\x20<max-depth>4</max-depth>\x0a\x20\x20<include-extensions>.js,.jsx,.ts,.tsx</include-extensions>\x0a\x20\x20<exclude-extensions>.test.js,.spec.js</exclude-extensions>\x0a\x20\x20<show-files>true</show-files>\x0a\x20\x20<show-hidden>false</show-hidden>\x0a</file-tree>\x0a\x0aJSON\x20USAGE:\x0a```json\x0a{\x0a\x20\x20\x22toolId\x22:\x20\x22file-tree\x22,\x0a\x20\x20\x22directory\x22:\x20\x22src\x22,\x0a\x20\x20\x22maxDepth\x22:\x204,\x0a\x20\x20\x22includeExtensions\x22:\x20[\x22.js\x22,\x20\x22.jsx\x22,\x20\x22.ts\x22,\x20\x22.tsx\x22],\x0a\x20\x20\x22excludeExtensions\x22:\x20[\x22.test.js\x22,\x20\x22.spec.js\x22],\x0a\x20\x20\x22showFiles\x22:\x20true,\x0a\x20\x20\x22showHidden\x22:\x20false\x0a}\x0a```\x0a\x0aPARAMETERS:\x0a\x0adirectory\x20(optional):\x0a\x20\x20-\x20Directory\x20to\x20scan\x20(default:\x20working\x20directory)\x0a\x20\x20-\x20Can\x20be\x20relative\x20or\x20absolute\x20path\x0a\x20\x20-\x20Examples:\x20\x22src\x22,\x20\x22src/components\x22,\x20\x22/home/user/project\x22\x0a\x0amaxDepth\x20(optional):\x0a\x20\x20-\x20Maximum\x20depth\x20to\x20scan\x20(default:\x20'+TREE_CONFIG[_0x520739(0x185)]+_0x520739(0x18a)+TREE_CONFIG['MAX_DEPTH_LIMIT']+_0x520739(0x140)+TREE_CONFIG[_0x520739(0x16d)]+_0x520739(0x11e)+TREE_CONFIG[_0x520739(0x18b)]+'\x0a-\x20Maximum\x20directories:\x20'+TREE_CONFIG['MAX_DIRECTORIES']+'\x0a-\x20Binary\x20files\x20can\x20be\x20filtered\x20with\x20ignoreBinaryFiles\x20option\x0a\x0aMULTI-DIRECTORY\x20SUPPORT:\x0aWorks\x20with\x20agent\x27s\x20configured\x20accessible\x20directories.\x0aValidates\x20paths\x20against\x20directoryAccess\x20configuration.\x0a\x20\x20\x20\x20';}[a0_0x425ea5(0x198)](_0x1e3878){const _0x325cea=a0_0x425ea5;try{if(_0x1e3878[_0x325cea(0x134)]()[_0x325cea(0x192)]('{')){const _0x14a04e=JSON[_0x325cea(0x155)](_0x1e3878);return{'directory':_0x14a04e['directory']||'.','maxDepth':_0x14a04e[_0x325cea(0x19d)]||TREE_CONFIG['DEFAULT_MAX_DEPTH'],'includeExtensions':_0x14a04e[_0x325cea(0x168)]||[],'excludeExtensions':_0x14a04e['excludeExtensions']||[],'excludeDirectories':_0x14a04e['excludeDirectories']||[],'showFiles':_0x14a04e[_0x325cea(0x125)]!==![],'showHidden':_0x14a04e['showHidden']===!![],'showSizes':_0x14a04e[_0x325cea(0x152)]===!![],'ignoreBinaryFiles':_0x14a04e[_0x325cea(0x16e)]===!![]};}const _0x154cd9={'directory':'.','maxDepth':TREE_CONFIG[_0x325cea(0x185)],'includeExtensions':[],'excludeExtensions':[],'excludeDirectories':[],'showFiles':!![],'showHidden':![],'showSizes':![],'ignoreBinaryFiles':![]},_0x8d5a52=/<directory>(.*?)<\/directory>/i,_0x47ab82=_0x8d5a52[_0x325cea(0x12d)](_0x1e3878);_0x47ab82&&(_0x154cd9[_0x325cea(0x184)]=_0x47ab82[0x1]['trim']());const _0x3f8b1f=/<max-depth>(\d+)<\/max-depth>/i,_0xd8cab1=_0x3f8b1f[_0x325cea(0x12d)](_0x1e3878);_0xd8cab1&&(_0x154cd9[_0x325cea(0x19d)]=parseInt(_0xd8cab1[0x1],0xa));const _0x4230e8=/<include-extensions>(.*?)<\/include-extensions>/i,_0x4007b6=_0x4230e8[_0x325cea(0x12d)](_0x1e3878);_0x4007b6&&(_0x154cd9['includeExtensions']=_0x4007b6[0x1]['split'](',')['map'](_0x3f7e51=>_0x3f7e51['trim']())[_0x325cea(0x194)](_0x1871ac=>_0x1871ac[_0x325cea(0x133)]>0x0));const _0x359f52=/<exclude-extensions>(.*?)<\/exclude-extensions>/i,_0x47f3bb=_0x359f52[_0x325cea(0x12d)](_0x1e3878);_0x47f3bb&&(_0x154cd9['excludeExtensions']=_0x47f3bb[0x1]['split'](',')[_0x325cea(0x14f)](_0x2398fb=>_0x2398fb[_0x325cea(0x134)]())[_0x325cea(0x194)](_0x35120e=>_0x35120e[_0x325cea(0x133)]>0x0));const _0x50aec0=/<exclude-directories>(.*?)<\/exclude-directories>/i,_0xcf2720=_0x50aec0[_0x325cea(0x12d)](_0x1e3878);_0xcf2720&&(_0x154cd9['excludeDirectories']=_0xcf2720[0x1][_0x325cea(0x176)](',')[_0x325cea(0x14f)](_0x40f292=>_0x40f292['trim']())[_0x325cea(0x194)](_0x34bce5=>_0x34bce5[_0x325cea(0x133)]>0x0));const _0x6d13a5=/<show-files>(.*?)<\/show-files>/i,_0x5300b7=_0x6d13a5['exec'](_0x1e3878);_0x5300b7&&(_0x154cd9['showFiles']=_0x5300b7[0x1]['trim']()[_0x325cea(0x120)]()!=='false');const _0x4e39d1=/<show-hidden>(.*?)<\/show-hidden>/i,_0xc8af56=_0x4e39d1[_0x325cea(0x12d)](_0x1e3878);_0xc8af56&&(_0x154cd9['showHidden']=_0xc8af56[0x1][_0x325cea(0x134)]()[_0x325cea(0x120)]()===_0x325cea(0x18e));const _0x161835=/<show-sizes>(.*?)<\/show-sizes>/i,_0x1dd3f6=_0x161835[_0x325cea(0x12d)](_0x1e3878);_0x1dd3f6&&(_0x154cd9['showSizes']=_0x1dd3f6[0x1]['trim']()['toLowerCase']()===_0x325cea(0x18e));const _0x4ff1cf=/<ignore-binary-files>(.*?)<\/ignore-binary-files>/i,_0x9e1760=_0x4ff1cf[_0x325cea(0x12d)](_0x1e3878);return _0x9e1760&&(_0x154cd9['ignoreBinaryFiles']=_0x9e1760[0x1][_0x325cea(0x134)]()[_0x325cea(0x120)]()===_0x325cea(0x18e)),_0x154cd9;}catch(_0x2206cb){return this['logger']?.['error']('Failed\x20to\x20parse\x20file-tree\x20parameters',{'error':_0x2206cb['message']}),{'directory':'.','maxDepth':TREE_CONFIG['DEFAULT_MAX_DEPTH'],'includeExtensions':[],'excludeExtensions':[],'excludeDirectories':[],'showFiles':!![],'showHidden':![],'showSizes':![],'ignoreBinaryFiles':![],'parseError':_0x2206cb[_0x325cea(0x175)]};}}[a0_0x425ea5(0x17f)](){return[];}['customValidateParameters'](_0x589739){const _0x4bae45=a0_0x425ea5,_0x49595e=[];if(_0x589739['maxDepth']!==undefined){if(typeof _0x589739[_0x4bae45(0x19d)]!==_0x4bae45(0x18f)||_0x589739[_0x4bae45(0x19d)]<0x1)_0x49595e[_0x4bae45(0x13c)]('max-depth\x20must\x20be\x20a\x20positive\x20number');else _0x589739[_0x4bae45(0x19d)]>this['treeConfig'][_0x4bae45(0x16d)]&&_0x49595e['push']('max-depth\x20cannot\x20exceed\x20'+this['treeConfig'][_0x4bae45(0x16d)]);}_0x589739['directory']&&_0x589739[_0x4bae45(0x184)]['includes']('..')&&_0x49595e['push']('Path\x20traversal\x20(..)\x20not\x20allowed\x20for\x20security');if(_0x589739[_0x4bae45(0x168)]!==undefined&&_0x589739[_0x4bae45(0x168)]!==null){if(!Array['isArray'](_0x589739[_0x4bae45(0x168)]))_0x49595e['push'](_0x4bae45(0x14a));else for(const _0x1f1a7a of _0x589739[_0x4bae45(0x168)]){!_0x1f1a7a[_0x4bae45(0x192)]('.')&&_0x49595e['push']('Extension\x20\x22'+_0x1f1a7a+_0x4bae45(0x123));}}if(_0x589739[_0x4bae45(0x13e)]!==undefined&&_0x589739['excludeExtensions']!==null){if(!Array['isArray'](_0x589739[_0x4bae45(0x13e)]))_0x49595e['push'](_0x4bae45(0x18d));else for(const _0x2ba391 of _0x589739[_0x4bae45(0x13e)]){!_0x2ba391[_0x4bae45(0x192)]('.')&&_0x49595e[_0x4bae45(0x13c)]('Extension\x20\x22'+_0x2ba391+'\x22\x20must\x20start\x20with\x20a\x20dot\x20(e.g.,\x20\x22.js\x22)');}}_0x589739['excludeDirectories']!==undefined&&_0x589739['excludeDirectories']!==null&&(!Array['isArray'](_0x589739['excludeDirectories'])&&_0x49595e['push'](_0x4bae45(0x13b)));if(_0x49595e[_0x4bae45(0x133)]>0x0)throw new Error(_0x4bae45(0x15a)+_0x49595e[_0x4bae45(0x132)](',\x20'));return{'valid':!![],'errors':[]};}async[a0_0x425ea5(0x14d)](_0x351b2a,_0x19589b){const _0x597d05=a0_0x425ea5,{directory:directory='.',maxDepth:maxDepth=TREE_CONFIG[_0x597d05(0x185)],includeExtensions:includeExtensions=[],excludeExtensions:excludeExtensions=[],excludeDirectories:excludeDirectories=[],showFiles:showFiles=!![],showHidden:showHidden=![],showSizes:showSizes=![],ignoreBinaryFiles:ignoreBinaryFiles=![]}=_0x351b2a,{projectDir:_0xd3acb,agentId:_0x3c4899,directoryAccess:_0x39ce05}=_0x19589b;let _0x477d5c=_0xd3acb||process['cwd']();_0x39ce05&&_0x39ce05['workingDirectory']&&(_0x477d5c=_0x39ce05[_0x597d05(0x156)],this['logger']?.['info'](_0x597d05(0x182),{'workingDirectory':_0x39ce05['workingDirectory'],'agentId':_0x3c4899}));const _0x1dd971=a0_0x50cfc0['isAbsolute'](directory)?directory:a0_0x50cfc0[_0x597d05(0x173)](_0x477d5c,directory);try{const _0xa2fca=await a0_0xf730f6['stat'](_0x1dd971);if(!_0xa2fca[_0x597d05(0x127)]())throw new Error('Path\x20is\x20not\x20a\x20directory');}catch(_0x25de71){throw new Error(_0x597d05(0x183)+directory);}this[_0x597d05(0x129)]?.[_0x597d05(0x143)]('Generating\x20file\x20tree',{'directory':directory,'targetDir':_0x1dd971,'maxDepth':maxDepth,'includeExtensions':includeExtensions?.[_0x597d05(0x133)]||0x0,'excludeExtensions':excludeExtensions?.[_0x597d05(0x133)]||0x0,'agentId':_0x3c4899}),this[_0x597d05(0x142)]={'filesCount':0x0,'directoriesCount':0x0,'skippedCount':0x0};const _0x288139=[...DEFAULT_IGNORE_DIRECTORIES,...excludeDirectories||[]],_0x533bbb=[...DEFAULT_IGNORE_EXTENSIONS];ignoreBinaryFiles&&_0x533bbb['push'](...BINARY_EXTENSIONS);const _0xe1baab=await this['buildTree'](_0x1dd971,_0x1dd971,0x0,maxDepth,_0x288139,includeExtensions||[],[...excludeExtensions||[],..._0x533bbb],showFiles,showHidden,showSizes),_0x399b58=this[_0x597d05(0x196)](_0xe1baab),_0x3c69a7=this['generateSummary'](directory,this['stats'],maxDepth);return{'success':!![],'directory':_0x1dd971,'tree':_0x399b58,'summary':_0x3c69a7,'maxDepth':maxDepth,'totalFiles':this[_0x597d05(0x142)]['filesCount'],'totalDirectories':this['stats'][_0x597d05(0x190)],'skippedCount':this['stats'][_0x597d05(0x12e)],'statistics':{...this[_0x597d05(0x142)]},'toolUsed':_0x597d05(0x16b)};}async[a0_0x425ea5(0x128)](_0x58be78,_0x336911,_0xd58fd,_0x329cc7,_0x3baa08,_0x296af3,_0x694397,_0x206308,_0xaf9a18,_0x5a2631){const _0x3753b3=a0_0x425ea5;if(_0xd58fd>_0x329cc7)return null;if(this['stats']['directoriesCount']>=this[_0x3753b3(0x12f)]['MAX_DIRECTORIES'])return this[_0x3753b3(0x129)]?.['warn']('Maximum\x20directory\x20count\x20reached',{'maxDirectories':this['treeConfig']['MAX_DIRECTORIES']}),null;try{const _0x19f720=await a0_0xf730f6[_0x3753b3(0x11f)](_0x336911,{'withFileTypes':!![]}),_0x4373ca={'name':_0xd58fd===0x0?a0_0x50cfc0['basename'](_0x336911)+'/':a0_0x50cfc0['basename'](_0x336911),'path':a0_0x50cfc0[_0x3753b3(0x131)](_0x58be78,_0x336911),'type':'directory','children':[]};this[_0x3753b3(0x142)][_0x3753b3(0x190)]++;for(const _0x3cdd6c of _0x19f720){if(this[_0x3753b3(0x142)]['filesCount']>=this['treeConfig'][_0x3753b3(0x18b)]){this[_0x3753b3(0x129)]?.[_0x3753b3(0x13d)](_0x3753b3(0x157),{'maxFiles':this[_0x3753b3(0x12f)]['MAX_FILES_IN_TREE']});break;}if(!_0xaf9a18&&_0x3cdd6c['name']['startsWith']('.')){this[_0x3753b3(0x142)][_0x3753b3(0x12e)]++;continue;}const _0x4dad13=a0_0x50cfc0[_0x3753b3(0x132)](_0x336911,_0x3cdd6c[_0x3753b3(0x181)]);if(_0x3cdd6c['isDirectory']()){if(_0x3baa08[_0x3753b3(0x18c)](_0x3cdd6c[_0x3753b3(0x181)])){this['stats']['skippedCount']++;continue;}const _0x1a9473=await this['buildTree'](_0x58be78,_0x4dad13,_0xd58fd+0x1,_0x329cc7,_0x3baa08,_0x296af3,_0x694397,_0x206308,_0xaf9a18,_0x5a2631);_0x1a9473&&(_0x1a9473['children']['length']>0x0||_0xd58fd===0x0)&&_0x4373ca[_0x3753b3(0x11c)]['push'](_0x1a9473);}else{if(_0x3cdd6c[_0x3753b3(0x15b)]()&&_0x206308){if(_0xd58fd+0x1>_0x329cc7)continue;const _0x31dc10=a0_0x50cfc0['extname'](_0x3cdd6c[_0x3753b3(0x181)]);if(_0x296af3['length']>0x0){if(!_0x296af3[_0x3753b3(0x18c)](_0x31dc10)){this[_0x3753b3(0x142)][_0x3753b3(0x12e)]++;continue;}}else{if(_0x694397[_0x3753b3(0x18c)](_0x31dc10)){this['stats']['skippedCount']++;continue;}}let _0x4427f7='';if(_0x5a2631)try{const _0x3136a1=await a0_0xf730f6[_0x3753b3(0x172)](_0x4dad13);_0x4427f7='\x20('+this[_0x3753b3(0x138)](_0x3136a1['size'])+')';}catch(_0x1ecb2b){}_0x4373ca['children'][_0x3753b3(0x13c)]({'name':_0x3cdd6c['name']+_0x4427f7,'path':a0_0x50cfc0['relative'](_0x58be78,_0x4dad13),'type':_0x3753b3(0x11d),'ext':_0x31dc10}),this[_0x3753b3(0x142)][_0x3753b3(0x147)]++;}}}return _0x4373ca['children']['sort']((_0x219501,_0xc6e32a)=>{const _0x52d835=_0x3753b3;if(_0x219501['type']===_0xc6e32a['type'])return _0x219501['name'][_0x52d835(0x19e)](_0xc6e32a[_0x52d835(0x181)]);return _0x219501['type']===_0x52d835(0x184)?-0x1:0x1;}),_0x4373ca;}catch(_0xc348a1){return this[_0x3753b3(0x129)]?.['error'](_0x3753b3(0x187),{'currentPath':_0x336911,'error':_0xc348a1['message']}),{'name':a0_0x50cfc0['basename'](_0x336911),'path':a0_0x50cfc0[_0x3753b3(0x131)](_0x58be78,_0x336911),'type':'directory','error':_0xc348a1['message'],'children':[]};}}['formatTree'](_0x400059,_0x25ccd1='',_0x414c0b=!![],_0xc29eaf=!![]){const _0x3aaf18=a0_0x425ea5;if(!_0x400059)return'';const _0x2568a1=this[_0x3aaf18(0x12f)]['SYMBOLS'];let _0x2249f7='';_0xc29eaf?_0x2249f7=_0x400059['name']+'\x0a':_0x2249f7=''+_0x25ccd1+(_0x414c0b?_0x2568a1['LAST_BRANCH']:_0x2568a1[_0x3aaf18(0x15e)])+_0x400059['name']+'\x0a';if(_0x400059['children']&&_0x400059[_0x3aaf18(0x11c)]['length']>0x0){const _0xa1126d=_0xc29eaf?'':_0x25ccd1+(_0x414c0b?_0x2568a1['INDENT']:_0x2568a1['VERTICAL']);_0x400059['children'][_0x3aaf18(0x17d)]((_0x456f16,_0x4aad95)=>{const _0x1820fb=_0x3aaf18,_0x5dc699=_0x4aad95===_0x400059[_0x1820fb(0x11c)][_0x1820fb(0x133)]-0x1;_0x2249f7+=this[_0x1820fb(0x196)](_0x456f16,_0xa1126d,_0x5dc699,![]);});}return _0x2249f7;}[a0_0x425ea5(0x138)](_0x238508){const _0x384d56=a0_0x425ea5,_0x769cc3=0x400,_0x15b91f=_0x769cc3*0x400,_0x3d4b9c=_0x15b91f*0x400;if(_0x238508>=_0x3d4b9c)return(_0x238508/_0x3d4b9c)['toFixed'](0x2)+'\x20GB';else{if(_0x238508>=_0x15b91f)return(_0x238508/_0x15b91f)['toFixed'](0x2)+'\x20MB';else return _0x238508>=_0x769cc3?(_0x238508/_0x769cc3)[_0x384d56(0x137)](0x2)+_0x384d56(0x162):_0x238508+'\x20B';}}['generateSummary'](_0x5c45de,_0x54ae45,_0x18cff2){const _0x359a21=a0_0x425ea5;return(_0x359a21(0x180)+_0x5c45de+'\x0aMax\x20Depth:\x20'+_0x18cff2+_0x359a21(0x16f)+_0x54ae45[_0x359a21(0x147)]+_0x359a21(0x151)+_0x54ae45[_0x359a21(0x190)]+'\x0aSkipped:\x20'+_0x54ae45[_0x359a21(0x12e)]+'\x0a\x20\x20\x20\x20')[_0x359a21(0x134)]();}async['cleanup'](_0xb157d4){const _0x460948=a0_0x425ea5;this[_0x460948(0x129)]?.[_0x460948(0x143)](_0x460948(0x158),{'operationId':_0xb157d4});}}export default FileTreeTool;
|