@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,956 +1 @@
1
- /**
2
- * SeekTool - Search for content within project files
3
- *
4
- * Purpose:
5
- * - Search for specific content/patterns within files
6
- * - Support glob patterns for file paths
7
- * - Verify imports, function usage, and variable references
8
- * - Provide detailed match information with line numbers
9
- */
10
-
11
- import { BaseTool } from './baseTool.js';
12
- import TagParser from '../utilities/tagParser.js';
13
- import { promises as fs } from 'fs';
14
- import path from 'path';
15
-
16
- // Configuration constants
17
- const SEEK_CONFIG = {
18
- // File size limits
19
- MAX_FILE_SIZE: 10 * 1024 * 1024, // 10MB - don't search files larger than this
20
-
21
- // Search limits
22
- MAX_FILES_PER_SEARCH: 1000, // Maximum files to search in one operation
23
- MAX_MATCHES_PER_FILE: 100, // Maximum matches to return per file
24
- MAX_TOTAL_MATCHES: 500, // Maximum total matches to return
25
-
26
- // Performance limits
27
- MAX_SEARCH_TERMS: 50, // Maximum number of search terms
28
- MAX_FILE_PATHS: 100, // Maximum number of file path patterns
29
-
30
- // Recursion limits
31
- MAX_DIRECTORY_DEPTH: 20, // Maximum directory recursion depth
32
-
33
- // Result formatting
34
- MAX_LINE_CONTENT_LENGTH: 200, // Maximum line content to show in results
35
- CONTEXT_LINES_BEFORE: 0, // Lines of context before match
36
- CONTEXT_LINES_AFTER: 0, // Lines of context after match
37
- };
38
-
39
- // File encoding
40
- const FILE_ENCODING = 'utf-8';
41
-
42
- // Common binary file extensions to skip
43
- const BINARY_EXTENSIONS = new Set([
44
- '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.ico', '.svg',
45
- '.pdf', '.zip', '.tar', '.gz', '.rar', '.7z',
46
- '.exe', '.dll', '.so', '.dylib',
47
- '.mp3', '.mp4', '.avi', '.mov', '.wmv',
48
- '.woff', '.woff2', '.ttf', '.eot',
49
- '.bin', '.dat', '.db', '.sqlite'
50
- ]);
51
-
52
- class SeekTool extends BaseTool {
53
- constructor(config = {}, logger = null) {
54
- super(config, logger);
55
-
56
- // Tool metadata
57
- this.requiresProject = true; // Requires project directory
58
- this.isAsync = true; // File operations are async
59
- this.timeout = config.timeout || 120000; // 2 minutes default
60
-
61
- // Merge config with defaults
62
- this.seekConfig = {
63
- ...SEEK_CONFIG,
64
- ...config.seekConfig
65
- };
66
- }
67
-
68
- /**
69
- * Get tool description for LLM consumption
70
- * @returns {string} Tool description
71
- */
72
- getDescription() {
73
- return `
74
- Seek Tool: Search for specific content within project files. Highly recommended for verifying imports, function usage, and variable references.
75
-
76
- XML USAGE:
77
- <seek>
78
- <in-files>
79
- file/path/one.js
80
- file/path/two.js
81
- src/**/*.js
82
- </in-files>
83
- <search-terms>
84
- <term>search phrase one</term>
85
- <term>search phrase two</term>
86
- <term>search phrase three</term>
87
- </search-terms>
88
- </seek>
89
-
90
- JSON USAGE:
91
- \`\`\`json
92
- {
93
- "toolId": "seek",
94
- "filePaths": [
95
- "src/components/Header.js",
96
- "src/utils/*.js",
97
- "src/**/*.jsx"
98
- ],
99
- "searchTerms": [
100
- "import React",
101
- "useState",
102
- "function handleSubmit"
103
- ]
104
- }
105
- \`\`\`
106
-
107
- SUPPORTED GLOB PATTERNS:
108
- - *.js - All .js files in a directory
109
- - **/*.js - All .js files recursively
110
- - src/**/*.jsx - All .jsx files under src/ recursively
111
- - components/*.* - All files in components/
112
-
113
- EXAMPLES:
114
-
115
- Example 1 - Find function usage:
116
- <seek>
117
- <in-files>
118
- src/components/*.js
119
- src/utils/helpers.js
120
- </in-files>
121
- <search-terms>
122
- <term>function handleSubmit</term>
123
- <term>useState(</term>
124
- </search-terms>
125
- </seek>
126
-
127
- Example 2 - Verify imports:
128
- <seek>
129
- <in-files>
130
- src/components/Header.js
131
- src/components/Footer.js
132
- </in-files>
133
- <search-terms>
134
- <term>import React</term>
135
- <term>import { useState }</term>
136
- <term>from 'react'</term>
137
- </search-terms>
138
- </seek>
139
-
140
- Example 3 - Find variable references:
141
- <seek>
142
- <in-files>
143
- src/**/*.js
144
- </in-files>
145
- <search-terms>
146
- <term>apiClient</term>
147
- <term>config.apiUrl</term>
148
- </search-terms>
149
- </seek>
150
-
151
- Example 4 - Search specific files only:
152
- <seek>
153
- <in-files>
154
- package.json
155
- tsconfig.json
156
- .gitignore
157
- </in-files>
158
- <search-terms>
159
- <term>react</term>
160
- <term>typescript</term>
161
- </search-terms>
162
- </seek>
163
-
164
- FEATURES:
165
- - Searches for exact string matches (case-sensitive)
166
- - Returns file path, line number, and line content for each match
167
- - Supports glob patterns for flexible file selection
168
- - Skips binary files automatically
169
- - Reports files not found and files with errors
170
- - Limited to ${SEEK_CONFIG.MAX_FILE_SIZE / (1024 * 1024)}MB per file
171
- - Returns up to ${SEEK_CONFIG.MAX_TOTAL_MATCHES} matches total
172
-
173
- RESULT FORMAT:
174
- The tool returns:
175
- - List of files that were not found
176
- - List of files that had errors during search
177
- - For each search term:
178
- - File path where found
179
- - Line number
180
- - Line content (trimmed)
181
-
182
- MULTI-DIRECTORY SUPPORT:
183
- When an agent has multiple directories configured, the SeekTool can search across all of them:
184
- - Relative paths are resolved from the working directory
185
- - Absolute paths can reference any accessible directory
186
- - Automatic validation ensures paths are within allowed directories
187
-
188
- Example with multiple directories:
189
- If agent has access to:
190
- - /home/user/project1 (working directory)
191
- - /home/user/project2 (read-only)
192
- - /home/user/shared (read-only)
193
-
194
- You can search:
195
- src/**/*.js → Searches in /home/user/project1/src/**/*.js
196
- /home/user/project2/config.json → Searches in project2 (absolute path)
197
- /home/user/shared/docs/*.md → Searches in shared directory
198
-
199
- LIMITATIONS:
200
- - Maximum ${SEEK_CONFIG.MAX_FILES_PER_SEARCH} files per search
201
- - Maximum ${SEEK_CONFIG.MAX_SEARCH_TERMS} search terms
202
- - Maximum ${SEEK_CONFIG.MAX_FILE_SIZE / (1024 * 1024)}MB per file
203
- - Case-sensitive search only
204
- - Exact string matching (not regex)
205
- - Paths outside accessible directories will be reported as "not found"
206
- `;
207
- }
208
-
209
- /**
210
- * Parse parameters from tool command content
211
- * @param {string} content - Raw tool command content
212
- * @returns {Object} Parsed parameters
213
- */
214
- parseParameters(content) {
215
- try {
216
- // Try JSON first
217
- if (content.trim().startsWith('{')) {
218
- const parsed = JSON.parse(content);
219
-
220
- return {
221
- filePaths: parsed.filePaths || [],
222
- searchTerms: parsed.searchTerms || []
223
- };
224
- }
225
-
226
- // XML parsing
227
- const params = {
228
- filePaths: [],
229
- searchTerms: []
230
- };
231
-
232
- // Extract in-files content
233
- const inFilesPattern = /<in-files>([\s\S]*?)<\/in-files>/i;
234
- const inFilesMatch = inFilesPattern.exec(content);
235
-
236
- if (inFilesMatch) {
237
- const filesContent = inFilesMatch[1];
238
- params.filePaths = filesContent
239
- .split('\n')
240
- .map(line => line.trim())
241
- .filter(line => line.length > 0);
242
- }
243
-
244
- // Extract search-terms content
245
- const searchTermsPattern = /<search-terms>([\s\S]*?)<\/search-terms>/i;
246
- const searchTermsMatch = searchTermsPattern.exec(content);
247
-
248
- if (searchTermsMatch) {
249
- const termsContent = searchTermsMatch[1];
250
-
251
- // Extract individual <term> tags
252
- const termPattern = /<term>(.*?)<\/term>/gi;
253
- let termMatch;
254
-
255
- while ((termMatch = termPattern.exec(termsContent)) !== null) {
256
- const term = termMatch[1].trim();
257
- if (term.length > 0) {
258
- params.searchTerms.push(term);
259
- }
260
- }
261
- }
262
-
263
- return params;
264
-
265
- } catch (error) {
266
- this.logger?.error('Failed to parse seek parameters', { error: error.message });
267
- return {
268
- filePaths: [],
269
- searchTerms: [],
270
- parseError: error.message
271
- };
272
- }
273
- }
274
-
275
- /**
276
- * Get required parameters
277
- * @returns {Array<string>} Array of required parameter names
278
- */
279
- getRequiredParameters() {
280
- return ['filePaths', 'searchTerms'];
281
- }
282
-
283
- /**
284
- * Custom parameter validation
285
- * @param {Object} params - Parameters to validate
286
- * @returns {Object} Validation result
287
- */
288
- customValidateParameters(params) {
289
- const errors = [];
290
-
291
- // Validate filePaths
292
- if (!params.filePaths || !Array.isArray(params.filePaths) || params.filePaths.length === 0) {
293
- errors.push('At least one file path is required');
294
- } else if (params.filePaths.length > this.seekConfig.MAX_FILE_PATHS) {
295
- errors.push(`Too many file paths (max ${this.seekConfig.MAX_FILE_PATHS})`);
296
- }
297
-
298
- // Validate searchTerms
299
- if (!params.searchTerms || !Array.isArray(params.searchTerms) || params.searchTerms.length === 0) {
300
- errors.push('At least one search term is required');
301
- } else if (params.searchTerms.length > this.seekConfig.MAX_SEARCH_TERMS) {
302
- errors.push(`Too many search terms (max ${this.seekConfig.MAX_SEARCH_TERMS})`);
303
- }
304
-
305
- // Validate search terms are non-empty strings
306
- if (params.searchTerms && Array.isArray(params.searchTerms)) {
307
- for (const [index, term] of params.searchTerms.entries()) {
308
- if (typeof term !== 'string' || term.trim().length === 0) {
309
- errors.push(`Search term ${index + 1}: must be a non-empty string`);
310
- }
311
- }
312
- }
313
-
314
- // Validate file paths are non-empty strings
315
- if (params.filePaths && Array.isArray(params.filePaths)) {
316
- for (const [index, filePath] of params.filePaths.entries()) {
317
- if (typeof filePath !== 'string' || filePath.trim().length === 0) {
318
- errors.push(`File path ${index + 1}: must be a non-empty string`);
319
- }
320
-
321
- // Check for path traversal attempts
322
- if (filePath.includes('..')) {
323
- errors.push(`File path ${index + 1}: path traversal (..) not allowed for security`);
324
- }
325
- }
326
- }
327
-
328
- return {
329
- valid: errors.length === 0,
330
- errors
331
- };
332
- }
333
-
334
- /**
335
- * Execute tool with parsed parameters
336
- * @param {Object} params - Parsed parameters
337
- * @param {Object} context - Execution context
338
- * @returns {Promise<Object>} Execution result
339
- */
340
- async execute(params, context) {
341
- const { filePaths, searchTerms } = params;
342
- const { projectDir, agentId, directoryAccess } = context;
343
-
344
- // IMPORTANT: Get all accessible directories for the agent
345
- // This includes workingDirectory, readOnlyDirectories, and writeEnabledDirectories
346
- let workingDirectory = projectDir || process.cwd();
347
- let accessibleDirectories = [workingDirectory];
348
-
349
- if (directoryAccess && directoryAccess.workingDirectory) {
350
- workingDirectory = directoryAccess.workingDirectory;
351
-
352
- // Collect all accessible directories (for read operations)
353
- accessibleDirectories = this.getAllAccessibleDirectories(directoryAccess);
354
-
355
- this.logger?.info('Using agent configured directory access', {
356
- workingDirectory: directoryAccess.workingDirectory,
357
- totalAccessibleDirs: accessibleDirectories.length,
358
- readOnlyDirs: directoryAccess.readOnlyDirectories?.length || 0,
359
- writeEnabledDirs: directoryAccess.writeEnabledDirectories?.length || 0,
360
- agentId
361
- });
362
- }
363
-
364
- if (!workingDirectory) {
365
- throw new Error('Project directory is required for seek tool');
366
- }
367
-
368
- this.logger?.info('Executing seek tool', {
369
- filePathCount: filePaths.length,
370
- searchTermCount: searchTerms.length,
371
- workingDirectory,
372
- accessibleDirectories: accessibleDirectories.length,
373
- agentId
374
- });
375
-
376
- try {
377
- // Resolve file paths (expand globs)
378
- // Pass accessible directories for validation (if agent has directoryAccess configured)
379
- const resolveResult = await this.resolveFilePaths(
380
- filePaths,
381
- workingDirectory,
382
- directoryAccess ? accessibleDirectories : null
383
- );
384
-
385
- const resolvedFiles = resolveResult.found;
386
- const notFoundFiles = resolveResult.notFound;
387
-
388
- // Check file count limit
389
- if (resolvedFiles.length > this.seekConfig.MAX_FILES_PER_SEARCH) {
390
- return {
391
- success: false,
392
- error: `Too many files to search (${resolvedFiles.length}). Maximum is ${this.seekConfig.MAX_FILES_PER_SEARCH}. Use more specific file patterns.`,
393
- filesResolved: resolvedFiles.length,
394
- filesNotFound: notFoundFiles.length
395
- };
396
- }
397
-
398
- // Search in files
399
- const searchResult = await this.searchFiles(resolvedFiles, searchTerms, workingDirectory);
400
-
401
- // Format results
402
- const formattedResults = this.formatResults(
403
- searchResult.matches,
404
- searchResult.errorFiles,
405
- notFoundFiles,
406
- resolvedFiles.length
407
- );
408
-
409
- return {
410
- success: true,
411
- filesSearched: resolvedFiles.length,
412
- filesNotFound: notFoundFiles.length,
413
- filesWithErrors: searchResult.errorFiles.length,
414
- totalMatches: searchResult.matches.length,
415
- matchesByTerm: searchResult.matchesByTerm,
416
- formattedResults,
417
- toolUsed: 'seek'
418
- };
419
-
420
- } catch (error) {
421
- this.logger?.error('Seek tool execution failed', { error: error.message });
422
- throw error;
423
- }
424
- }
425
-
426
- /**
427
- * Get all accessible directories for read operations
428
- * @param {Object} directoryAccess - Directory access configuration
429
- * @returns {Array<string>} Array of accessible directory paths
430
- * @private
431
- */
432
- getAllAccessibleDirectories(directoryAccess) {
433
- const directories = new Set();
434
-
435
- // Add working directory
436
- if (directoryAccess.workingDirectory) {
437
- directories.add(directoryAccess.workingDirectory);
438
- }
439
-
440
- // Add read-only directories
441
- if (directoryAccess.readOnlyDirectories && Array.isArray(directoryAccess.readOnlyDirectories)) {
442
- for (const dir of directoryAccess.readOnlyDirectories) {
443
- directories.add(dir);
444
- }
445
- }
446
-
447
- // Add write-enabled directories (if you can write, you can read)
448
- if (directoryAccess.writeEnabledDirectories && Array.isArray(directoryAccess.writeEnabledDirectories)) {
449
- for (const dir of directoryAccess.writeEnabledDirectories) {
450
- directories.add(dir);
451
- }
452
- }
453
-
454
- return Array.from(directories);
455
- }
456
-
457
- /**
458
- * Check if a path is within any accessible directory
459
- * @param {string} targetPath - Path to check
460
- * @param {Array<string>} accessibleDirs - Array of accessible directories
461
- * @returns {boolean} True if path is accessible
462
- * @private
463
- */
464
- isPathAccessible(targetPath, accessibleDirs) {
465
- for (const dir of accessibleDirs) {
466
- const relative = path.relative(dir, targetPath);
467
- const isWithin = !relative.startsWith('..') && !path.isAbsolute(relative);
468
- if (isWithin) {
469
- return true;
470
- }
471
- }
472
- return false;
473
- }
474
-
475
- /**
476
- * Resolve file paths, expanding glob patterns
477
- * @param {Array<string>} filePaths - File paths with possible glob patterns
478
- * @param {string} projectDir - Project directory
479
- * @param {Array<string>} accessibleDirs - Optional array of accessible directories
480
- * @returns {Promise<Object>} Object with found and notFound arrays
481
- * @private
482
- */
483
- async resolveFilePaths(filePaths, projectDir, accessibleDirs = null) {
484
- const result = {
485
- found: [],
486
- notFound: []
487
- };
488
-
489
- for (const filePath of filePaths) {
490
- const normalizedPath = filePath.trim();
491
-
492
- if (normalizedPath.includes('*')) {
493
- // Handle glob patterns
494
- const globResult = await this.expandGlobPattern(normalizedPath, projectDir);
495
-
496
- if (globResult.found.length > 0) {
497
- result.found.push(...globResult.found);
498
- } else {
499
- result.notFound.push(`${normalizedPath} (no matching files)`);
500
- }
501
- } else {
502
- // Handle direct file reference
503
- const absolutePath = path.isAbsolute(normalizedPath)
504
- ? normalizedPath
505
- : path.resolve(projectDir, normalizedPath);
506
-
507
- // Check if path is within accessible directories (if configured)
508
- if (accessibleDirs && accessibleDirs.length > 0) {
509
- if (!this.isPathAccessible(absolutePath, accessibleDirs)) {
510
- result.notFound.push(`${normalizedPath} (not in accessible directories)`);
511
- continue;
512
- }
513
- }
514
-
515
- try {
516
- const stats = await fs.stat(absolutePath);
517
-
518
- if (stats.isFile()) {
519
- result.found.push(absolutePath);
520
- } else if (stats.isDirectory()) {
521
- result.notFound.push(`${normalizedPath} (is a directory, not a file)`);
522
- } else {
523
- result.notFound.push(`${normalizedPath} (not a regular file)`);
524
- }
525
- } catch (error) {
526
- result.notFound.push(`${normalizedPath} (${error.code || error.message})`);
527
- }
528
- }
529
- }
530
-
531
- return result;
532
- }
533
-
534
- /**
535
- * Expand glob pattern to matching file paths
536
- * @param {string} pattern - Glob pattern
537
- * @param {string} projectDir - Project directory
538
- * @returns {Promise<Object>} Object with found files
539
- * @private
540
- */
541
- async expandGlobPattern(pattern, projectDir) {
542
- const result = { found: [] };
543
-
544
- // Handle recursive pattern: src/**/*.js
545
- if (pattern.includes('**/')) {
546
- const [baseDir, filePattern] = pattern.split('**/');
547
- const basePath = path.resolve(projectDir, baseDir);
548
-
549
- try {
550
- const stats = await fs.stat(basePath);
551
-
552
- if (stats.isDirectory()) {
553
- await this.findFilesRecursively(
554
- basePath,
555
- filePattern,
556
- result.found,
557
- 0,
558
- this.seekConfig.MAX_DIRECTORY_DEPTH
559
- );
560
- }
561
- } catch (error) {
562
- // Directory doesn't exist
563
- this.logger?.warn('Base directory not found for glob pattern', { basePath, error: error.message });
564
- }
565
- }
566
- // Handle simple pattern: src/*.js
567
- else if (pattern.includes('*')) {
568
- const dirPath = path.dirname(path.resolve(projectDir, pattern));
569
- const filePattern = path.basename(pattern);
570
-
571
- try {
572
- const stats = await fs.stat(dirPath);
573
-
574
- if (stats.isDirectory()) {
575
- const files = await fs.readdir(dirPath);
576
-
577
- for (const file of files) {
578
- const filePath = path.join(dirPath, file);
579
-
580
- try {
581
- const fileStats = await fs.stat(filePath);
582
-
583
- if (fileStats.isFile() && this.matchesPattern(file, filePattern)) {
584
- result.found.push(filePath);
585
- }
586
- } catch (error) {
587
- // Skip files we can't stat
588
- continue;
589
- }
590
- }
591
- }
592
- } catch (error) {
593
- // Directory doesn't exist
594
- this.logger?.warn('Directory not found for glob pattern', { dirPath, error: error.message });
595
- }
596
- }
597
-
598
- return result;
599
- }
600
-
601
- /**
602
- * Find files recursively matching a pattern
603
- * @param {string} dir - Directory to search
604
- * @param {string} filePattern - File pattern to match
605
- * @param {Array<string>} results - Results array
606
- * @param {number} currentDepth - Current recursion depth
607
- * @param {number} maxDepth - Maximum recursion depth
608
- * @returns {Promise<void>}
609
- * @private
610
- */
611
- async findFilesRecursively(dir, filePattern, results, currentDepth, maxDepth) {
612
- // Prevent infinite recursion
613
- if (currentDepth >= maxDepth) {
614
- this.logger?.warn('Maximum directory depth reached', { dir, currentDepth });
615
- return;
616
- }
617
-
618
- try {
619
- const entries = await fs.readdir(dir, { withFileTypes: true });
620
-
621
- for (const entry of entries) {
622
- // Skip hidden files and directories
623
- if (entry.name.startsWith('.')) {
624
- continue;
625
- }
626
-
627
- const fullPath = path.join(dir, entry.name);
628
-
629
- try {
630
- if (entry.isDirectory()) {
631
- // Skip common large directories
632
- if (this.shouldSkipDirectory(entry.name)) {
633
- continue;
634
- }
635
-
636
- await this.findFilesRecursively(
637
- fullPath,
638
- filePattern,
639
- results,
640
- currentDepth + 1,
641
- maxDepth
642
- );
643
- } else if (entry.isFile()) {
644
- if (this.matchesPattern(entry.name, filePattern)) {
645
- results.push(fullPath);
646
-
647
- // Stop if we've found too many files
648
- if (results.length >= this.seekConfig.MAX_FILES_PER_SEARCH) {
649
- return;
650
- }
651
- }
652
- }
653
- } catch (error) {
654
- // Skip entries we can't access
655
- continue;
656
- }
657
- }
658
- } catch (error) {
659
- this.logger?.warn('Error reading directory', { dir, error: error.message });
660
- }
661
- }
662
-
663
- /**
664
- * Check if filename matches a wildcard pattern
665
- * @param {string} filename - Filename to check
666
- * @param {string} pattern - Wildcard pattern
667
- * @returns {boolean} True if matches
668
- * @private
669
- */
670
- matchesPattern(filename, pattern) {
671
- // Simple wildcard matching
672
- const regexPattern = pattern
673
- .split('*')
674
- .map(part => this.escapeRegExp(part))
675
- .join('.*');
676
-
677
- const regex = new RegExp(`^${regexPattern}$`, 'i');
678
- return regex.test(filename);
679
- }
680
-
681
- /**
682
- * Escape special regex characters
683
- * @param {string} string - String to escape
684
- * @returns {string} Escaped string
685
- * @private
686
- */
687
- escapeRegExp(string) {
688
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
689
- }
690
-
691
- /**
692
- * Check if directory should be skipped during recursive search
693
- * @param {string} dirName - Directory name
694
- * @returns {boolean} True if should skip
695
- * @private
696
- */
697
- shouldSkipDirectory(dirName) {
698
- const skipDirs = new Set([
699
- 'node_modules',
700
- '.git',
701
- 'dist',
702
- 'build',
703
- 'coverage',
704
- '.next',
705
- '.nuxt',
706
- 'out',
707
- 'target',
708
- 'vendor',
709
- '__pycache__',
710
- '.cache',
711
- 'tmp',
712
- 'temp'
713
- ]);
714
-
715
- return skipDirs.has(dirName.toLowerCase());
716
- }
717
-
718
- /**
719
- * Check if file should be skipped (binary files)
720
- * @param {string} filePath - File path
721
- * @returns {boolean} True if should skip
722
- * @private
723
- */
724
- shouldSkipFile(filePath) {
725
- const ext = path.extname(filePath).toLowerCase();
726
- return BINARY_EXTENSIONS.has(ext);
727
- }
728
-
729
- /**
730
- * Search for terms in multiple files
731
- * @param {Array<string>} filePaths - File paths to search
732
- * @param {Array<string>} searchTerms - Search terms
733
- * @param {string} projectDir - Project directory for relative paths
734
- * @returns {Promise<Object>} Search results
735
- * @private
736
- */
737
- async searchFiles(filePaths, searchTerms, projectDir) {
738
- const allMatches = [];
739
- const errorFiles = [];
740
- let totalMatches = 0;
741
-
742
- for (const filePath of filePaths) {
743
- // Skip binary files
744
- if (this.shouldSkipFile(filePath)) {
745
- continue;
746
- }
747
-
748
- try {
749
- // Check file size
750
- const stats = await fs.stat(filePath);
751
-
752
- if (stats.size > this.seekConfig.MAX_FILE_SIZE) {
753
- errorFiles.push({
754
- filePath: path.relative(projectDir, filePath),
755
- error: `File too large (${Math.round(stats.size / (1024 * 1024))}MB, max ${Math.round(this.seekConfig.MAX_FILE_SIZE / (1024 * 1024))}MB)`
756
- });
757
- continue;
758
- }
759
-
760
- // Search in file
761
- const matches = await this.searchInFile(filePath, searchTerms, projectDir);
762
-
763
- allMatches.push(...matches);
764
- totalMatches += matches.length;
765
-
766
- // Stop if we've exceeded max total matches
767
- if (totalMatches >= this.seekConfig.MAX_TOTAL_MATCHES) {
768
- this.logger?.warn('Maximum total matches reached', { totalMatches });
769
- break;
770
- }
771
-
772
- } catch (error) {
773
- errorFiles.push({
774
- filePath: path.relative(projectDir, filePath),
775
- error: error.message
776
- });
777
- }
778
- }
779
-
780
- // Group matches by search term
781
- const matchesByTerm = {};
782
-
783
- for (const match of allMatches) {
784
- if (!matchesByTerm[match.term]) {
785
- matchesByTerm[match.term] = [];
786
- }
787
-
788
- matchesByTerm[match.term].push({
789
- filePath: match.filePath,
790
- lineNumber: match.lineNumber,
791
- lineContent: match.lineContent
792
- });
793
- }
794
-
795
- return {
796
- matches: allMatches,
797
- matchesByTerm,
798
- errorFiles
799
- };
800
- }
801
-
802
- /**
803
- * Search for terms in a single file
804
- * @param {string} filePath - File path
805
- * @param {Array<string>} searchTerms - Search terms
806
- * @param {string} projectDir - Project directory for relative paths
807
- * @returns {Promise<Array<Object>>} Matches found
808
- * @private
809
- */
810
- async searchInFile(filePath, searchTerms, projectDir) {
811
- const matches = [];
812
- let matchesInFile = 0;
813
-
814
- try {
815
- // Read file content
816
- const content = await fs.readFile(filePath, FILE_ENCODING);
817
-
818
- // Split into lines
819
- const lines = content.split('\n');
820
- const relativePath = path.relative(projectDir, filePath);
821
-
822
- // Search each line
823
- for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
824
- const line = lines[lineIndex];
825
- const lineNumber = lineIndex + 1; // 1-based line numbers
826
-
827
- // Check each search term
828
- for (const term of searchTerms) {
829
- if (line.includes(term)) {
830
- // Truncate line content if too long
831
- let lineContent = line;
832
- if (lineContent.length > this.seekConfig.MAX_LINE_CONTENT_LENGTH) {
833
- const termIndex = lineContent.indexOf(term);
834
- const start = Math.max(0, termIndex - 50);
835
- const end = Math.min(lineContent.length, termIndex + term.length + 50);
836
- lineContent = (start > 0 ? '...' : '') +
837
- lineContent.substring(start, end) +
838
- (end < lineContent.length ? '...' : '');
839
- }
840
-
841
- matches.push({
842
- term,
843
- filePath: relativePath,
844
- lineNumber,
845
- lineContent: lineContent.trim()
846
- });
847
-
848
- matchesInFile++;
849
-
850
- // Limit matches per file
851
- if (matchesInFile >= this.seekConfig.MAX_MATCHES_PER_FILE) {
852
- this.logger?.warn('Maximum matches per file reached', { filePath: relativePath });
853
- return matches;
854
- }
855
- }
856
- }
857
- }
858
-
859
- } catch (error) {
860
- throw new Error(`Failed to read file: ${error.message}`);
861
- }
862
-
863
- return matches;
864
- }
865
-
866
- /**
867
- * Format search results for display
868
- * @param {Array<Object>} matches - Search matches
869
- * @param {Array<Object>} errorFiles - Files with errors
870
- * @param {Array<string>} notFoundFiles - Files not found
871
- * @param {number} filesSearched - Number of files searched
872
- * @returns {string} Formatted results
873
- * @private
874
- */
875
- formatResults(matches, errorFiles, notFoundFiles, filesSearched) {
876
- let output = '';
877
-
878
- // Report files not found
879
- if (notFoundFiles.length > 0) {
880
- output += 'FILES NOT FOUND:\n';
881
- for (const file of notFoundFiles) {
882
- output += ` - ${file}\n`;
883
- }
884
- output += '\n';
885
- }
886
-
887
- // Report files with errors
888
- if (errorFiles.length > 0) {
889
- output += 'FILES WITH ERRORS:\n';
890
- for (const file of errorFiles) {
891
- output += ` - ${file.filePath}: ${file.error}\n`;
892
- }
893
- output += '\n';
894
- }
895
-
896
- // Report search results
897
- if (matches.length === 0) {
898
- output += `No matches found for the specified search terms in ${filesSearched} file(s).\n`;
899
- } else {
900
- // Group by term
901
- const matchesByTerm = {};
902
- for (const match of matches) {
903
- if (!matchesByTerm[match.term]) {
904
- matchesByTerm[match.term] = [];
905
- }
906
- matchesByTerm[match.term].push(match);
907
- }
908
-
909
- output += `SEARCH RESULTS (${matches.length} total matches in ${filesSearched} file(s)):\n\n`;
910
-
911
- for (const [term, termMatches] of Object.entries(matchesByTerm)) {
912
- output += `Search term: "${term}" (${termMatches.length} matches)\n`;
913
-
914
- for (const match of termMatches) {
915
- output += ` ${match.filePath}:${match.lineNumber} - ${match.lineContent}\n`;
916
- }
917
-
918
- output += '\n';
919
- }
920
-
921
- // Add warning if max matches reached
922
- if (matches.length >= this.seekConfig.MAX_TOTAL_MATCHES) {
923
- output += `⚠️ Maximum matches limit reached (${this.seekConfig.MAX_TOTAL_MATCHES}). Some matches may not be shown.\n`;
924
- }
925
- }
926
-
927
- return output.trim();
928
- }
929
-
930
- /**
931
- * Get supported file extensions
932
- * @returns {Array<string>} Array of supported extensions
933
- */
934
- getSupportedExtensions() {
935
- return [
936
- '.js', '.jsx', '.ts', '.tsx',
937
- '.json', '.xml', '.html', '.css', '.scss', '.sass', '.less',
938
- '.md', '.txt', '.log',
939
- '.py', '.rb', '.java', '.go', '.rs',
940
- '.c', '.cpp', '.h', '.hpp',
941
- '.sh', '.bash', '.zsh',
942
- '.yml', '.yaml', '.toml', '.ini', '.conf'
943
- ];
944
- }
945
-
946
- /**
947
- * Resource cleanup
948
- * @param {string} operationId - Operation identifier
949
- */
950
- async cleanup(operationId) {
951
- // No persistent resources to clean up
952
- this.logger?.info('Seek tool cleanup completed', { operationId });
953
- }
954
- }
955
-
956
- export default SeekTool;
1
+ const a0_0x5ead5f=a0_0x22d4;(function(_0x8448b5,_0x470bf0){const _0x1328b1=a0_0x22d4,_0x4e5c72=_0x8448b5();while(!![]){try{const _0x41f2f2=parseInt(_0x1328b1(0xbb))/0x1*(-parseInt(_0x1328b1(0xc5))/0x2)+-parseInt(_0x1328b1(0x100))/0x3+parseInt(_0x1328b1(0xf9))/0x4+-parseInt(_0x1328b1(0xd2))/0x5*(-parseInt(_0x1328b1(0x11b))/0x6)+parseInt(_0x1328b1(0xbe))/0x7+-parseInt(_0x1328b1(0xba))/0x8+parseInt(_0x1328b1(0xaf))/0x9;if(_0x41f2f2===_0x470bf0)break;else _0x4e5c72['push'](_0x4e5c72['shift']());}catch(_0x4f979b){_0x4e5c72['push'](_0x4e5c72['shift']());}}}(a0_0x33e8,0xefab1));import{BaseTool}from'./baseTool.js';function a0_0x22d4(_0xa78133,_0x56259c){_0xa78133=_0xa78133-0x9d;const _0x33e8a5=a0_0x33e8();let _0x22d40e=_0x33e8a5[_0xa78133];if(a0_0x22d4['mLsVYN']===undefined){var _0x591650=function(_0x9acd27){const _0x543a8d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x255fed='',_0x313b56='';for(let _0x37e18d=0x0,_0x5ed48b,_0x95246a,_0x2eb0ba=0x0;_0x95246a=_0x9acd27['charAt'](_0x2eb0ba++);~_0x95246a&&(_0x5ed48b=_0x37e18d%0x4?_0x5ed48b*0x40+_0x95246a:_0x95246a,_0x37e18d++%0x4)?_0x255fed+=String['fromCharCode'](0xff&_0x5ed48b>>(-0x2*_0x37e18d&0x6)):0x0){_0x95246a=_0x543a8d['indexOf'](_0x95246a);}for(let _0x3b4229=0x0,_0x41489f=_0x255fed['length'];_0x3b4229<_0x41489f;_0x3b4229++){_0x313b56+='%'+('00'+_0x255fed['charCodeAt'](_0x3b4229)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x313b56);};a0_0x22d4['jfJHTZ']=_0x591650,a0_0x22d4['PCgpic']={},a0_0x22d4['mLsVYN']=!![];}const _0x39a939=_0x33e8a5[0x0],_0x3b27e8=_0xa78133+_0x39a939,_0x2e7e66=a0_0x22d4['PCgpic'][_0x3b27e8];return!_0x2e7e66?(_0x22d40e=a0_0x22d4['jfJHTZ'](_0x22d40e),a0_0x22d4['PCgpic'][_0x3b27e8]=_0x22d40e):_0x22d40e=_0x2e7e66,_0x22d40e;}function a0_0x33e8(){const _0x1b61dc=['yNvPBgq','zM9YBwf0uMvZDwX0CW','lMXLC3m','lNjZ','lMPZB24','rxjYB3iGCMvHzgLUzYbKAxjLy3rVCNK','BwvZC2fNzq','qxqGBgvHC3qGB25LigzPBguGCgf0AcbPCYbYzxf1AxjLza','C2L6zq','4PQG77IpicbnyxHPBxvTig1HDgnOzxmGBgLTAxqGCMvHy2HLzcaO','mJCYntKYoeHODenRDG','lM1WmW','yMfZzw5HBwu','CMvSyxrPDMu','zxHLyW','lNrHCG','rxHLy3v0Aw5NihnLzwSGDg9VBa','ndaZnZiZmLnMqwfPuG','C2vHCMnOrMLSzxm','lNnV','tufyx0zjtevFu0LArq','rMfPBgvKihrVihbHCNnLihnLzwSGCgfYyw1LDgvYCW','C3bSAxq','AxngAwXL','ihnLyxjJAcb0zxjTCWOTie1HEgLTDw0G','lMrHDa','vg9Vig1HBNKGzMLSzsbWyxrOCYaOBwf4ia','lM5LEhq','DgvZDa','C3vIC3rYAw5N','C2HVDwXKu2TPCezPBgu','tM8GBwf0y2HLCYbMB3vUzcbMB3iGDgHLihnWzwnPzMLLzcbZzwfYy2GGDgvYBxmGAw4G','CgfYC2vqyxjHBwv0zxjZ','CMvHzgrPCG','Bwf0y2HLC1bHDhrLCM4','u2vHCMnOihrLCM0G','oIbWyxrOihrYyxzLCNnHBcaOlI4Pig5VDcbHBgXVD2vKigzVCIbZzwn1CML0Eq','C2vLA0nVBMzPzW','DhjPBq','zM91BMq','icHUB3qGAw4GywnJzxnZAwjSzsbKAxjLy3rVCMLLCYK','lMjTCa','iIaO','lMPZEa','mtiWwxLQzK1K','Aw5JBhvKzxm','Dg1W','AgfZ','CM91BMq','CMvHze9UBhLeAxjLy3rVCMLLCW','twf4Aw11Bsb0B3rHBcbTyxrJAgvZihjLywnOzwq','C3rHCNrZv2L0Aa','lI4U','z2v0rgvZy3jPChrPB24','zNjVBq','lM51Ehq','lNnXBgL0zq','DMvUzg9Y','lNrZEa','CMvZB2X2zuzPBgvqyxrOCW','D3jPDgvfBMfIBgvKrgLYzwn0B3jPzxm','D29YA2LUz0rPCMvJDg9YEq','Bg9Nz2vY','zMLSDgvY','igzPBgvZihbLCIbZzwfYy2GklsbnyxHPBxvTia','ig1HDgnOzxmPcG','nty3odeXogX5A3vlyW','lNjHCG','lMPWzW','AxnbCNjHEq','u2vLAYb0B29SignSzwfUDxaGy29TCgXLDgvK','lNnJC3m','AxneAxjLy3rVCNK','tufyx0zjtevtx1bfuL9trufsq0G','z2v0uMvXDwLYzwrqyxjHBwv0zxjZ','lJD6','C2vHCMnOsw5gAwXL','mZi2oduYme90D3PRAa','mJy1mJaXEgXyC1HP','zxjYB3i','zxjYB3jgAwXLCW','mta1nJm0odn1C2HmqwO','DgLTzw91Da','ywrK','zgLZDa','DgvYBq','tufyx1rpvefmx01bvenirvm','u2vLAYb0B29Sigv4zwn1DgLVBIbMywLSzwq','nNHUDu9Iwq','lMrSBa','ig1HDgnOzxmGDg90ywWkcLjfu1vmvcbgt1jnqvq6cLrOzsb0B29SihjLDhvYBNm6cI0GtgLZDcbVzIbMAwXLCYb0Agf0ihDLCMuGBM90igzVDw5KcI0GtgLZDcbVzIbMAwXLCYb0Agf0igHHzcbLCNjVCNmGzhvYAw5NihnLyxjJAaOTiezVCIbLywnOihnLyxjJAcb0zxjToGOGic0GrMLSzsbWyxrOihDOzxjLigzVDw5KcIaGlsbmAw5Lig51BwjLCGOGic0GtgLUzsbJB250zw50icH0CMLTBwvKkqOktvvmveKTreLsrunut1jzifnvufbpuLq6cLDOzw4Gyw4GywDLBNqGAgfZig11BhrPCgXLigrPCMvJDg9YAwvZignVBMzPz3vYzwqSihrOzsbtzwvRvg9VBcbJyw4GC2vHCMnOigfJCM9ZCYbHBgWGB2yGDgHLBtOklsbszwXHDgL2zsbWyxrOCYbHCMuGCMvZB2X2zwqGzNjVBsb0AguGD29YA2LUzYbKAxjLy3rVCNKklsbbyNnVBhv0zsbWyxrOCYbJyw4GCMvMzxjLBMnLigfUEsbHy2nLC3nPyMXLigrPCMvJDg9YEqOTief1Dg9TyxrPyYb2ywXPzgf0Aw9UigvUC3vYzxmGCgf0AhmGyxjLihDPDgHPBIbHBgXVD2vKigrPCMvJDg9YAwvZcGPfEgfTCgXLihDPDgGGBxvSDgLWBguGzgLYzwn0B3jPzxm6cKLMigfNzw50igHHCYbHy2nLC3mGDg86cIaGlsaVAg9Tzs91C2vYl3bYB2PLy3qXicH3B3jRAw5NigrPCMvJDg9YEsKkicaTic9OB21Ll3vZzxiVChjVAMvJDdiGkhjLywqTB25SEsKkicaTic9OB21Ll3vZzxiVC2HHCMvKicHYzwfKlw9UBhKPcGPzB3uGy2fUihnLyxjJAdOkicbZCMmVkIOVkI5QCYaGicaGicaGicaGicaGicaGicaGicaGicaGiokgKIbtzwfYy2HLCYbPBIaVAg9Tzs91C2vYl3bYB2PLy3qXl3nYyY8QkI8QlMPZcIaGl2HVBwuVDxnLCI9WCM9Qzwn0mI9JB25MAwCUANnVBIaGicaGicdIHPiGu2vHCMnOzxmGAw4GChjVAMvJDdiGkgfIC29SDxrLihbHDgGPcIaGl2HVBwuVDxnLCI9ZAgfYzwqVzg9JCY8QlM1KicaGicaGicaGicdIHPiGu2vHCMnOzxmGAw4GC2HHCMvKigrPCMvJDg9YEqOkteLnsvrbveLptLm6cI0Gtwf4Aw11Bsa','oIbTDxn0igjLigeGBM9UlwvTChr5ihn0CMLUzW','qMfZzsbKAxjLy3rVCNKGBM90igzVDw5KigzVCIbNBg9IihbHDhrLCM4','C3rHDa','tuiSig1HEca','twf4Aw11BsbKAxjLy3rVCNKGzgvWDgGGCMvHy2HLza','BgvUz3rO','AxnbC3LUyW','lMXVzW','zxnJyxbLuMvNrxHW','C2HVDwXKu2TPCerPCMvJDg9YEq','mtC3ntm1u0L0y0nP','Bwf0y2HLC0j5vgvYBq','C2vHCMnOvgvYBxm','ChvZAa','tufyx0rjuKvdve9swv9ervbusa','ihrVDgfSig1HDgnOzxmGAw4G','lNrZ','Aw5KzxHpzG','zMLUzezPBgvZuMvJDxjZAxzLBhK','B3v0','lMv4zq','lMPZ','BM90rM91BMq','zxH0BMfTzq','BwLU','lNnO','D2fYBG','AxnqyxrOqwnJzxnZAwjSzq','icHUBYbTyxrJAgLUzYbMAwXLCYK','zw50CMLLCW','Aw5MBW','rKLmrvmGv0LuscbfuLjpuLm6cG','lNjI','lMDV','zMLSzvbHDgHZ','u2vHCMnOihrLCM06ici','lNLTBa','AM9PBG','BMfTzq'];a0_0x33e8=function(){return _0x1b61dc;};return a0_0x33e8();}import a0_0x255fed from'../utilities/tagParser.js';import{promises as a0_0x313b56}from'fs';import a0_0x37e18d from'path';const SEEK_CONFIG={'MAX_FILE_SIZE':0xa*0x400*0x400,'MAX_FILES_PER_SEARCH':0x3e8,'MAX_MATCHES_PER_FILE':0x64,'MAX_TOTAL_MATCHES':0x1f4,'MAX_SEARCH_TERMS':0x32,'MAX_FILE_PATHS':0x64,'MAX_DIRECTORY_DEPTH':0x14,'MAX_LINE_CONTENT_LENGTH':0xc8,'CONTEXT_LINES_BEFORE':0x0,'CONTEXT_LINES_AFTER':0x0},FILE_ENCODING='utf-8',BINARY_EXTENSIONS=new Set(['.png',a0_0x5ead5f(0xb1),'.jpeg','.gif',a0_0x5ead5f(0x118),'.ico','.svg','.pdf','.zip',a0_0x5ead5f(0xfe),'.gz',a0_0x5ead5f(0xb0),a0_0x5ead5f(0xb8),a0_0x5ead5f(0xdc),a0_0x5ead5f(0xc6),a0_0x5ead5f(0x102),'.dylib',a0_0x5ead5f(0xfa),'.mp4','.avi','.mov','.wmv','.woff','.woff2','.ttf','.eot','.bin',a0_0x5ead5f(0x108),'.db',a0_0x5ead5f(0xa5)]);class SeekTool extends BaseTool{constructor(_0x5ed48b={},_0x95246a=null){const _0x15993b=a0_0x5ead5f;super(_0x5ed48b,_0x95246a),this['requiresProject']=!![],this[_0x15993b(0xce)]=!![],this['timeout']=_0x5ed48b[_0x15993b(0xbf)]||0x1d4c0,this['seekConfig']={...SEEK_CONFIG,..._0x5ed48b[_0x15993b(0x114)]};}[a0_0x5ead5f(0xa2)](){const _0x26afe9=a0_0x5ead5f;return'\x0aSeek\x20Tool:\x20Search\x20for\x20specific\x20content\x20within\x20project\x20files.\x20Highly\x20recommended\x20for\x20verifying\x20imports,\x20function\x20usage,\x20and\x20variable\x20references.\x0a\x0aXML\x20USAGE:\x0a<seek>\x0a\x20\x20<in-files>\x0a\x20\x20\x20\x20file/path/one.js\x0a\x20\x20\x20\x20file/path/two.js\x0a\x20\x20\x20\x20src/**/*.js\x0a\x20\x20</in-files>\x0a\x20\x20<search-terms>\x0a\x20\x20\x20\x20<term>search\x20phrase\x20one</term>\x0a\x20\x20\x20\x20<term>search\x20phrase\x20two</term>\x0a\x20\x20\x20\x20<term>search\x20phrase\x20three</term>\x0a\x20\x20</search-terms>\x0a</seek>\x0a\x0aJSON\x20USAGE:\x0a```json\x0a{\x0a\x20\x20\x22toolId\x22:\x20\x22seek\x22,\x0a\x20\x20\x22filePaths\x22:\x20[\x0a\x20\x20\x20\x20\x22src/components/Header.js\x22,\x0a\x20\x20\x20\x20\x22src/utils/*.js\x22,\x0a\x20\x20\x20\x20\x22src/**/*.jsx\x22\x0a\x20\x20],\x0a\x20\x20\x22searchTerms\x22:\x20[\x0a\x20\x20\x20\x20\x22import\x20React\x22,\x0a\x20\x20\x20\x20\x22useState\x22,\x0a\x20\x20\x20\x20\x22function\x20handleSubmit\x22\x0a\x20\x20]\x0a}\x0a```\x0a\x0aSUPPORTED\x20GLOB\x20PATTERNS:\x0a-\x20*.js\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20-\x20All\x20.js\x20files\x20in\x20a\x20directory\x0a-\x20**/*.js\x20\x20\x20\x20\x20\x20\x20\x20-\x20All\x20.js\x20files\x20recursively\x0a-\x20src/**/*.jsx\x20\x20\x20-\x20All\x20.jsx\x20files\x20under\x20src/\x20recursively\x0a-\x20components/*.*\x20-\x20All\x20files\x20in\x20components/\x0a\x0aEXAMPLES:\x0a\x0aExample\x201\x20-\x20Find\x20function\x20usage:\x0a<seek>\x0a\x20\x20<in-files>\x0a\x20\x20\x20\x20src/components/*.js\x0a\x20\x20\x20\x20src/utils/helpers.js\x0a\x20\x20</in-files>\x0a\x20\x20<search-terms>\x0a\x20\x20\x20\x20<term>function\x20handleSubmit</term>\x0a\x20\x20\x20\x20<term>useState(</term>\x0a\x20\x20</search-terms>\x0a</seek>\x0a\x0aExample\x202\x20-\x20Verify\x20imports:\x0a<seek>\x0a\x20\x20<in-files>\x0a\x20\x20\x20\x20src/components/Header.js\x0a\x20\x20\x20\x20src/components/Footer.js\x0a\x20\x20</in-files>\x0a\x20\x20<search-terms>\x0a\x20\x20\x20\x20<term>import\x20React</term>\x0a\x20\x20\x20\x20<term>import\x20{\x20useState\x20}</term>\x0a\x20\x20\x20\x20<term>from\x20\x27react\x27</term>\x0a\x20\x20</search-terms>\x0a</seek>\x0a\x0aExample\x203\x20-\x20Find\x20variable\x20references:\x0a<seek>\x0a\x20\x20<in-files>\x0a\x20\x20\x20\x20src/**/*.js\x0a\x20\x20</in-files>\x0a\x20\x20<search-terms>\x0a\x20\x20\x20\x20<term>apiClient</term>\x0a\x20\x20\x20\x20<term>config.apiUrl</term>\x0a\x20\x20</search-terms>\x0a</seek>\x0a\x0aExample\x204\x20-\x20Search\x20specific\x20files\x20only:\x0a<seek>\x0a\x20\x20<in-files>\x0a\x20\x20\x20\x20package.json\x0a\x20\x20\x20\x20tsconfig.json\x0a\x20\x20\x20\x20.gitignore\x0a\x20\x20</in-files>\x0a\x20\x20<search-terms>\x0a\x20\x20\x20\x20<term>react</term>\x0a\x20\x20\x20\x20<term>typescript</term>\x0a\x20\x20</search-terms>\x0a</seek>\x0a\x0aFEATURES:\x0a-\x20Searches\x20for\x20exact\x20string\x20matches\x20(case-sensitive)\x0a-\x20Returns\x20file\x20path,\x20line\x20number,\x20and\x20line\x20content\x20for\x20each\x20match\x0a-\x20Supports\x20glob\x20patterns\x20for\x20flexible\x20file\x20selection\x0a-\x20Skips\x20binary\x20files\x20automatically\x0a-\x20Reports\x20files\x20not\x20found\x20and\x20files\x20with\x20errors\x0a-\x20Limited\x20to\x20'+SEEK_CONFIG['MAX_FILE_SIZE']/(0x400*0x400)+'MB\x20per\x20file\x0a-\x20Returns\x20up\x20to\x20'+SEEK_CONFIG[_0x26afe9(0xc3)]+_0x26afe9(0xc7)+SEEK_CONFIG[_0x26afe9(0xb6)]+_0x26afe9(0xad)+SEEK_CONFIG['MAX_SEARCH_TERMS']+_0x26afe9(0x107)+SEEK_CONFIG[_0x26afe9(0x103)]/(0x400*0x400)+'MB\x20per\x20file\x0a-\x20Case-sensitive\x20search\x20only\x0a-\x20Exact\x20string\x20matching\x20(not\x20regex)\x0a-\x20Paths\x20outside\x20accessible\x20directories\x20will\x20be\x20reported\x20as\x20\x22not\x20found\x22\x0a\x20\x20\x20\x20';}[a0_0x5ead5f(0x10f)](_0x2eb0ba){const _0x47fac6=a0_0x5ead5f;try{if(_0x2eb0ba['trim']()[_0x47fac6(0xa0)]('{')){const _0x3f87fe=JSON['parse'](_0x2eb0ba);return{'filePaths':_0x3f87fe[_0x47fac6(0xea)]||[],'searchTerms':_0x3f87fe[_0x47fac6(0xd4)]||[]};}const _0x3b4229={'filePaths':[],'searchTerms':[]},_0x41489f=/<in-files>([\s\S]*?)<\/in-files>/i,_0x2b2071=_0x41489f[_0x47fac6(0xfd)](_0x2eb0ba);if(_0x2b2071){const _0x298e8c=_0x2b2071[0x1];_0x3b4229[_0x47fac6(0xea)]=_0x298e8c[_0x47fac6(0x105)]('\x0a')['map'](_0xa3c541=>_0xa3c541[_0x47fac6(0x115)]())[_0x47fac6(0xac)](_0x3e9a95=>_0x3e9a95['length']>0x0);}const _0x42498c=/<search-terms>([\s\S]*?)<\/search-terms>/i,_0x2e19bb=_0x42498c['exec'](_0x2eb0ba);if(_0x2e19bb){const _0x451dc5=_0x2e19bb[0x1],_0x4e13a5=/<term>(.*?)<\/term>/gi;let _0x225f68;while((_0x225f68=_0x4e13a5['exec'](_0x451dc5))!==null){const _0x5543f8=_0x225f68[0x1]['trim']();_0x5543f8[_0x47fac6(0xcd)]>0x0&&_0x3b4229[_0x47fac6(0xd4)][_0x47fac6(0xd5)](_0x5543f8);}}return _0x3b4229;}catch(_0x4289c9){return this[_0x47fac6(0xab)]?.[_0x47fac6(0xbc)](_0x47fac6(0x104),{'error':_0x4289c9[_0x47fac6(0xf5)]}),{'filePaths':[],'searchTerms':[],'parseError':_0x4289c9[_0x47fac6(0xf5)]};}}[a0_0x5ead5f(0xb7)](){const _0x29c3bd=a0_0x5ead5f;return[_0x29c3bd(0xea),_0x29c3bd(0xd4)];}['customValidateParameters'](_0x33f187){const _0x3cb798=a0_0x5ead5f,_0x423ce6=[];if(!_0x33f187[_0x3cb798(0xea)]||!Array[_0x3cb798(0xb2)](_0x33f187[_0x3cb798(0xea)])||_0x33f187[_0x3cb798(0xea)]['length']===0x0)_0x423ce6['push'](_0x3cb798(0xf6));else _0x33f187['filePaths']['length']>this['seekConfig']['MAX_FILE_PATHS']&&_0x423ce6[_0x3cb798(0xd5)](_0x3cb798(0x109)+this['seekConfig']['MAX_FILE_PATHS']+')');if(!_0x33f187['searchTerms']||!Array[_0x3cb798(0xb2)](_0x33f187[_0x3cb798(0xd4)])||_0x33f187['searchTerms'][_0x3cb798(0xcd)]===0x0)_0x423ce6[_0x3cb798(0xd5)]('At\x20least\x20one\x20search\x20term\x20is\x20required');else _0x33f187['searchTerms']['length']>this[_0x3cb798(0x114)]['MAX_SEARCH_TERMS']&&_0x423ce6['push']('Too\x20many\x20search\x20terms\x20(max\x20'+this[_0x3cb798(0x114)]['MAX_SEARCH_TERMS']+')');if(_0x33f187['searchTerms']&&Array[_0x3cb798(0xb2)](_0x33f187['searchTerms']))for(const [_0x208acf,_0x20143e]of _0x33f187[_0x3cb798(0xd4)][_0x3cb798(0xe5)]()){(typeof _0x20143e!=='string'||_0x20143e['trim']()[_0x3cb798(0xcd)]===0x0)&&_0x423ce6[_0x3cb798(0xd5)](_0x3cb798(0x112)+(_0x208acf+0x1)+':\x20must\x20be\x20a\x20non-empty\x20string');}if(_0x33f187['filePaths']&&Array[_0x3cb798(0xb2)](_0x33f187[_0x3cb798(0xea)]))for(const [_0x49fab3,_0x232168]of _0x33f187['filePaths'][_0x3cb798(0xe5)]()){(typeof _0x232168!=='string'||_0x232168['trim']()['length']===0x0)&&_0x423ce6[_0x3cb798(0xd5)]('File\x20path\x20'+(_0x49fab3+0x1)+_0x3cb798(0xc8)),_0x232168['includes']('..')&&_0x423ce6['push']('File\x20path\x20'+(_0x49fab3+0x1)+_0x3cb798(0x113));}return{'valid':_0x423ce6['length']===0x0,'errors':_0x423ce6};}async['execute'](_0x50b73a,_0xadcb1f){const _0xf35c84=a0_0x5ead5f,{filePaths:_0x9ba6ee,searchTerms:_0xbb30d1}=_0x50b73a,{projectDir:_0x48496e,agentId:_0x32bef0,directoryAccess:_0x4bf1ee}=_0xadcb1f;let _0x1cc415=_0x48496e||process['cwd'](),_0x4765e7=[_0x1cc415];_0x4bf1ee&&_0x4bf1ee[_0xf35c84(0xaa)]&&(_0x1cc415=_0x4bf1ee['workingDirectory'],_0x4765e7=this['getAllAccessibleDirectories'](_0x4bf1ee),this[_0xf35c84(0xab)]?.[_0xf35c84(0xe6)]('Using\x20agent\x20configured\x20directory\x20access',{'workingDirectory':_0x4bf1ee[_0xf35c84(0xaa)],'totalAccessibleDirs':_0x4765e7['length'],'readOnlyDirs':_0x4bf1ee['readOnlyDirectories']?.[_0xf35c84(0xcd)]||0x0,'writeEnabledDirs':_0x4bf1ee[_0xf35c84(0xa9)]?.[_0xf35c84(0xcd)]||0x0,'agentId':_0x32bef0}));if(!_0x1cc415)throw new Error('Project\x20directory\x20is\x20required\x20for\x20seek\x20tool');this[_0xf35c84(0xab)]?.['info'](_0xf35c84(0xff),{'filePathCount':_0x9ba6ee['length'],'searchTermCount':_0xbb30d1[_0xf35c84(0xcd)],'workingDirectory':_0x1cc415,'accessibleDirectories':_0x4765e7['length'],'agentId':_0x32bef0});try{const _0xc397ff=await this[_0xf35c84(0xa8)](_0x9ba6ee,_0x1cc415,_0x4bf1ee?_0x4765e7:null),_0x260bc8=_0xc397ff['found'],_0x3918b4=_0xc397ff[_0xf35c84(0xde)];if(_0x260bc8[_0xf35c84(0xcd)]>this['seekConfig']['MAX_FILES_PER_SEARCH'])return{'success':![],'error':'Too\x20many\x20files\x20to\x20search\x20('+_0x260bc8['length']+').\x20Maximum\x20is\x20'+this['seekConfig'][_0xf35c84(0xb6)]+'.\x20Use\x20more\x20specific\x20file\x20patterns.','filesResolved':_0x260bc8['length'],'filesNotFound':_0x3918b4['length']};const _0xc72ffc=await this['searchFiles'](_0x260bc8,_0xbb30d1,_0x1cc415),_0x26bc24=this[_0xf35c84(0xf0)](_0xc72ffc['matches'],_0xc72ffc[_0xf35c84(0xbd)],_0x3918b4,_0x260bc8[_0xf35c84(0xcd)]);return{'success':!![],'filesSearched':_0x260bc8['length'],'filesNotFound':_0x3918b4['length'],'filesWithErrors':_0xc72ffc['errorFiles'][_0xf35c84(0xcd)],'totalMatches':_0xc72ffc['matches']['length'],'matchesByTerm':_0xc72ffc[_0xf35c84(0xd3)],'formattedResults':_0x26bc24,'toolUsed':'seek'};}catch(_0xc08f97){this[_0xf35c84(0xab)]?.['error'](_0xf35c84(0xc4),{'error':_0xc08f97['message']});throw _0xc08f97;}}['getAllAccessibleDirectories'](_0x10826f){const _0x49a5f0=a0_0x5ead5f,_0x36865e=new Set();_0x10826f[_0x49a5f0(0xaa)]&&_0x36865e['add'](_0x10826f['workingDirectory']);if(_0x10826f[_0x49a5f0(0x9e)]&&Array[_0x49a5f0(0xb2)](_0x10826f['readOnlyDirectories']))for(const _0x46cc95 of _0x10826f['readOnlyDirectories']){_0x36865e['add'](_0x46cc95);}if(_0x10826f['writeEnabledDirectories']&&Array[_0x49a5f0(0xb2)](_0x10826f['writeEnabledDirectories']))for(const _0x106ecc of _0x10826f['writeEnabledDirectories']){_0x36865e[_0x49a5f0(0xc0)](_0x106ecc);}return Array[_0x49a5f0(0xa3)](_0x36865e);}[a0_0x5ead5f(0xe3)](_0x49805a,_0x52b75d){const _0x187327=a0_0x5ead5f;for(const _0x58ee8d of _0x52b75d){const _0x5741a0=a0_0x37e18d[_0x187327(0xfc)](_0x58ee8d,_0x49805a),_0x307e27=!_0x5741a0['startsWith']('..')&&!a0_0x37e18d['isAbsolute'](_0x5741a0);if(_0x307e27)return!![];}return![];}async[a0_0x5ead5f(0xa8)](_0xd1e338,_0x396e14,_0x40a507=null){const _0x4bd069=a0_0x5ead5f,_0x5aa279={'found':[],'notFound':[]};for(const _0x489e1a of _0xd1e338){const _0x22e560=_0x489e1a['trim']();if(_0x22e560[_0x4bd069(0x11c)]('*')){const _0x46cbed=await this['expandGlobPattern'](_0x22e560,_0x396e14);_0x46cbed['found']['length']>0x0?_0x5aa279['found']['push'](..._0x46cbed[_0x4bd069(0x116)]):_0x5aa279[_0x4bd069(0xde)][_0x4bd069(0xd5)](_0x22e560+_0x4bd069(0xe4));}else{const _0x5b70d2=a0_0x37e18d['isAbsolute'](_0x22e560)?_0x22e560:a0_0x37e18d['resolve'](_0x396e14,_0x22e560);if(_0x40a507&&_0x40a507[_0x4bd069(0xcd)]>0x0){if(!this['isPathAccessible'](_0x5b70d2,_0x40a507)){_0x5aa279[_0x4bd069(0xde)]['push'](_0x22e560+_0x4bd069(0x117));continue;}}try{const _0x2ece79=await a0_0x313b56[_0x4bd069(0xca)](_0x5b70d2);if(_0x2ece79[_0x4bd069(0x106)]())_0x5aa279[_0x4bd069(0x116)][_0x4bd069(0xd5)](_0x5b70d2);else _0x2ece79['isDirectory']()?_0x5aa279['notFound'][_0x4bd069(0xd5)](_0x22e560+'\x20(is\x20a\x20directory,\x20not\x20a\x20file)'):_0x5aa279['notFound'][_0x4bd069(0xd5)](_0x22e560+'\x20(not\x20a\x20regular\x20file)');}catch(_0x2a7ada){_0x5aa279['notFound'][_0x4bd069(0xd5)](_0x22e560+'\x20('+(_0x2a7ada['code']||_0x2a7ada['message'])+')');}}}return _0x5aa279;}async['expandGlobPattern'](_0xbc09d4,_0x431ec5){const _0x396aab=a0_0x5ead5f,_0x173976={'found':[]};if(_0xbc09d4[_0x396aab(0x11c)]('**/')){const [_0x30d640,_0x2ab81f]=_0xbc09d4[_0x396aab(0x105)]('**/'),_0x4abf1c=a0_0x37e18d['resolve'](_0x431ec5,_0x30d640);try{const _0x3e3057=await a0_0x313b56[_0x396aab(0xca)](_0x4abf1c);_0x3e3057['isDirectory']()&&await this[_0x396aab(0xda)](_0x4abf1c,_0x2ab81f,_0x173976['found'],0x0,this['seekConfig'][_0x396aab(0xd6)]);}catch(_0x3821f7){this[_0x396aab(0xab)]?.['warn'](_0x396aab(0xc9),{'basePath':_0x4abf1c,'error':_0x3821f7[_0x396aab(0xf5)]});}}else{if(_0xbc09d4['includes']('*')){const _0x35939f=a0_0x37e18d['dirname'](a0_0x37e18d['resolve'](_0x431ec5,_0xbc09d4)),_0x1bb583=a0_0x37e18d[_0x396aab(0xfb)](_0xbc09d4);try{const _0x4ba7f8=await a0_0x313b56[_0x396aab(0xca)](_0x35939f);if(_0x4ba7f8[_0x396aab(0xb5)]()){const _0x1fe6e3=await a0_0x313b56[_0x396aab(0x110)](_0x35939f);for(const _0x192d9b of _0x1fe6e3){const _0x3aef0c=a0_0x37e18d[_0x396aab(0xed)](_0x35939f,_0x192d9b);try{const _0x2d3d9e=await a0_0x313b56['stat'](_0x3aef0c);_0x2d3d9e['isFile']()&&this['matchesPattern'](_0x192d9b,_0x1bb583)&&_0x173976[_0x396aab(0x116)]['push'](_0x3aef0c);}catch(_0x410140){continue;}}}}catch(_0x4d8301){this[_0x396aab(0xab)]?.[_0x396aab(0xe2)]('Directory\x20not\x20found\x20for\x20glob\x20pattern',{'dirPath':_0x35939f,'error':_0x4d8301['message']});}}}return _0x173976;}async['findFilesRecursively'](_0x344d2c,_0x2e6212,_0x567a61,_0x104cba,_0x181962){const _0x9f94c=a0_0x5ead5f;if(_0x104cba>=_0x181962){this[_0x9f94c(0xab)]?.['warn'](_0x9f94c(0xcc),{'dir':_0x344d2c,'currentDepth':_0x104cba});return;}try{const _0x6d6721=await a0_0x313b56[_0x9f94c(0x110)](_0x344d2c,{'withFileTypes':!![]});for(const _0x3f6ba9 of _0x6d6721){if(_0x3f6ba9[_0x9f94c(0xee)][_0x9f94c(0xa0)]('.'))continue;const _0x2629a3=a0_0x37e18d['join'](_0x344d2c,_0x3f6ba9['name']);try{if(_0x3f6ba9[_0x9f94c(0xb5)]()){if(this['shouldSkipDirectory'](_0x3f6ba9[_0x9f94c(0xee)]))continue;await this['findFilesRecursively'](_0x2629a3,_0x2e6212,_0x567a61,_0x104cba+0x1,_0x181962);}else{if(_0x3f6ba9[_0x9f94c(0x106)]()){if(this[_0x9f94c(0x111)](_0x3f6ba9[_0x9f94c(0xee)],_0x2e6212)){_0x567a61['push'](_0x2629a3);if(_0x567a61['length']>=this['seekConfig'][_0x9f94c(0xb6)])return;}}}}catch(_0xe6c433){continue;}}}catch(_0x41a286){this['logger']?.[_0x9f94c(0xe2)](_0x9f94c(0xf4),{'dir':_0x344d2c,'error':_0x41a286['message']});}}[a0_0x5ead5f(0x111)](_0x58ca62,_0x39651a){const _0x25b97d=a0_0x5ead5f,_0x7f86e1=_0x39651a[_0x25b97d(0x105)]('*')['map'](_0x2a43a0=>this[_0x25b97d(0xd0)](_0x2a43a0))['join']('.*'),_0x3e3962=new RegExp('^'+_0x7f86e1+'$','i');return _0x3e3962[_0x25b97d(0x10b)](_0x58ca62);}['escapeRegExp'](_0x6c3191){return _0x6c3191['replace'](/[.*+?^${}()|[\]\\]/g,'\x5c$&');}[a0_0x5ead5f(0xd1)](_0x274819){const _0xda1d7a=a0_0x5ead5f,_0x12c0be=new Set(['node_modules','.git',_0xda1d7a(0xc1),_0xda1d7a(0xef),'coverage',_0xda1d7a(0x10a),_0xda1d7a(0xa4),_0xda1d7a(0xdb),'target',_0xda1d7a(0xa6),'__pycache__','.cache',_0xda1d7a(0x11d),'temp']);return _0x12c0be[_0xda1d7a(0x11e)](_0x274819['toLowerCase']());}['shouldSkipFile'](_0x31f520){const _0x3b0712=a0_0x5ead5f,_0x4bd121=a0_0x37e18d[_0x3b0712(0xdf)](_0x31f520)['toLowerCase']();return BINARY_EXTENSIONS['has'](_0x4bd121);}async[a0_0x5ead5f(0x101)](_0x21c073,_0x29752f,_0x4b3309){const _0x4120ca=a0_0x5ead5f,_0x5e0ccb=[],_0x429b9c=[];let _0xf0b257=0x0;for(const _0x405ee1 of _0x21c073){if(this[_0x4120ca(0x10d)](_0x405ee1))continue;try{const _0x4f7df8=await a0_0x313b56[_0x4120ca(0xca)](_0x405ee1);if(_0x4f7df8[_0x4120ca(0xf7)]>this[_0x4120ca(0x114)][_0x4120ca(0x103)]){_0x429b9c[_0x4120ca(0xd5)]({'filePath':a0_0x37e18d['relative'](_0x4b3309,_0x405ee1),'error':'File\x20too\x20large\x20('+Math[_0x4120ca(0x9d)](_0x4f7df8['size']/(0x400*0x400))+_0x4120ca(0xcb)+Math[_0x4120ca(0x9d)](this[_0x4120ca(0x114)]['MAX_FILE_SIZE']/(0x400*0x400))+'MB)'});continue;}const _0x10b8e8=await this[_0x4120ca(0xb9)](_0x405ee1,_0x29752f,_0x4b3309);_0x5e0ccb[_0x4120ca(0xd5)](..._0x10b8e8),_0xf0b257+=_0x10b8e8['length'];if(_0xf0b257>=this['seekConfig']['MAX_TOTAL_MATCHES']){this['logger']?.['warn'](_0x4120ca(0x9f),{'totalMatches':_0xf0b257});break;}}catch(_0x5605d3){_0x429b9c['push']({'filePath':a0_0x37e18d['relative'](_0x4b3309,_0x405ee1),'error':_0x5605d3[_0x4120ca(0xf5)]});}}const _0x8a18d6={};for(const _0x27bc4e of _0x5e0ccb){!_0x8a18d6[_0x27bc4e[_0x4120ca(0xc2)]]&&(_0x8a18d6[_0x27bc4e['term']]=[]),_0x8a18d6[_0x27bc4e['term']][_0x4120ca(0xd5)]({'filePath':_0x27bc4e['filePath'],'lineNumber':_0x27bc4e['lineNumber'],'lineContent':_0x27bc4e['lineContent']});}return{'matches':_0x5e0ccb,'matchesByTerm':_0x8a18d6,'errorFiles':_0x429b9c};}async['searchInFile'](_0x535d07,_0x1d7150,_0x142eaa){const _0x33e8db=a0_0x5ead5f,_0x3e37a3=[];let _0x2ffa57=0x0;try{const _0x1ac3d1=await a0_0x313b56['readFile'](_0x535d07,FILE_ENCODING),_0x3eaf28=_0x1ac3d1[_0x33e8db(0x105)]('\x0a'),_0x1b5d28=a0_0x37e18d[_0x33e8db(0xfc)](_0x142eaa,_0x535d07);for(let _0x1bd6fa=0x0;_0x1bd6fa<_0x3eaf28['length'];_0x1bd6fa++){const _0x5aa02c=_0x3eaf28[_0x1bd6fa],_0x33d873=_0x1bd6fa+0x1;for(const _0x1abb0b of _0x1d7150){if(_0x5aa02c[_0x33e8db(0x11c)](_0x1abb0b)){let _0x10bc44=_0x5aa02c;if(_0x10bc44['length']>this[_0x33e8db(0x114)]['MAX_LINE_CONTENT_LENGTH']){const _0x523504=_0x10bc44[_0x33e8db(0xd9)](_0x1abb0b),_0x2106e8=Math['max'](0x0,_0x523504-0x32),_0x550fed=Math[_0x33e8db(0xe0)](_0x10bc44[_0x33e8db(0xcd)],_0x523504+_0x1abb0b[_0x33e8db(0xcd)]+0x32);_0x10bc44=(_0x2106e8>0x0?_0x33e8db(0xa1):'')+_0x10bc44[_0x33e8db(0x10c)](_0x2106e8,_0x550fed)+(_0x550fed<_0x10bc44['length']?_0x33e8db(0xa1):'');}_0x3e37a3[_0x33e8db(0xd5)]({'term':_0x1abb0b,'filePath':_0x1b5d28,'lineNumber':_0x33d873,'lineContent':_0x10bc44[_0x33e8db(0x115)]()}),_0x2ffa57++;if(_0x2ffa57>=this[_0x33e8db(0x114)]['MAX_MATCHES_PER_FILE'])return this['logger']?.['warn']('Maximum\x20matches\x20per\x20file\x20reached',{'filePath':_0x1b5d28}),_0x3e37a3;}}}}catch(_0x298c62){throw new Error('Failed\x20to\x20read\x20file:\x20'+_0x298c62[_0x33e8db(0xf5)]);}return _0x3e37a3;}[a0_0x5ead5f(0xf0)](_0x9d70d9,_0x8a4d7f,_0x24e587,_0x4512d7){const _0x3a724c=a0_0x5ead5f;let _0x33cf52='';if(_0x24e587['length']>0x0){_0x33cf52+='FILES\x20NOT\x20FOUND:\x0a';for(const _0x5ad5ab of _0x24e587){_0x33cf52+='\x20\x20-\x20'+_0x5ad5ab+'\x0a';}_0x33cf52+='\x0a';}if(_0x8a4d7f['length']>0x0){_0x33cf52+=_0x3a724c(0xe7);for(const _0x5276f7 of _0x8a4d7f){_0x33cf52+='\x20\x20-\x20'+_0x5276f7['filePath']+':\x20'+_0x5276f7[_0x3a724c(0xbc)]+'\x0a';}_0x33cf52+='\x0a';}if(_0x9d70d9['length']===0x0)_0x33cf52+=_0x3a724c(0x10e)+_0x4512d7+'\x20file(s).\x0a';else{const _0x29e7dc={};for(const _0x2f104a of _0x9d70d9){!_0x29e7dc[_0x2f104a[_0x3a724c(0xc2)]]&&(_0x29e7dc[_0x2f104a['term']]=[]),_0x29e7dc[_0x2f104a['term']][_0x3a724c(0xd5)](_0x2f104a);}_0x33cf52+='SEARCH\x20RESULTS\x20('+_0x9d70d9['length']+_0x3a724c(0xd7)+_0x4512d7+'\x20file(s)):\x0a\x0a';for(const [_0x2f65aa,_0xf4b394]of Object[_0x3a724c(0xe5)](_0x29e7dc)){_0x33cf52+=_0x3a724c(0xeb)+_0x2f65aa+_0x3a724c(0x119)+_0xf4b394[_0x3a724c(0xcd)]+_0x3a724c(0xae);for(const _0x52f1e6 of _0xf4b394){_0x33cf52+='\x20\x20'+_0x52f1e6['filePath']+':'+_0x52f1e6['lineNumber']+'\x20-\x20'+_0x52f1e6['lineContent']+'\x0a';}_0x33cf52+='\x0a';}_0x9d70d9[_0x3a724c(0xcd)]>=this[_0x3a724c(0x114)][_0x3a724c(0xc3)]&&(_0x33cf52+=_0x3a724c(0xf8)+this[_0x3a724c(0x114)][_0x3a724c(0xc3)]+').\x20Some\x20matches\x20may\x20not\x20be\x20shown.\x0a');}return _0x33cf52[_0x3a724c(0x115)]();}['getSupportedExtensions'](){const _0x333e50=a0_0x5ead5f;return[_0x333e50(0xdd),_0x333e50(0x11a),_0x333e50(0xd8),_0x333e50(0xa7),_0x333e50(0xf3),'.xml','.html','.css',_0x333e50(0xb4),'.sass',_0x333e50(0xf1),'.md','.txt',_0x333e50(0xcf),'.py',_0x333e50(0xe8),'.java',_0x333e50(0xe9),_0x333e50(0xf2),'.c','.cpp','.h','.hpp',_0x333e50(0xe1),'.bash','.zsh',_0x333e50(0xec),'.yaml','.toml','.ini','.conf'];}async['cleanup'](_0x2fcd35){const _0x3f1980=a0_0x5ead5f;this[_0x3f1980(0xab)]?.[_0x3f1980(0xe6)](_0x3f1980(0xb3),{'operationId':_0x2fcd35});}}export default SeekTool;