@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,1215 +1 @@
1
- /**
2
- * @file tools/dependencyResolverTool.js
3
- * @description Modern tool for resolving Node.js dependency conflicts by checking and updating to latest compatible versions
4
- */
5
-
6
- import { promises as fs } from 'fs';
7
- import path from 'path';
8
- import { exec as execCb } from 'child_process';
9
- import { promisify } from 'util';
10
- import { BaseTool } from './baseTool.js';
11
- import TagParser from '../utilities/tagParser.js';
12
-
13
- const exec = promisify(execCb);
14
-
15
- /**
16
- * Configuration constants for the dependency resolver
17
- */
18
- const RESOLVER_CONFIG = {
19
- DEFAULT_MODE: 'check',
20
- VALID_MODES: ['check', 'fix', 'auto'],
21
- NPM_COMMAND_TIMEOUT: 300000, // 5 minutes for npm commands
22
- REGISTRY_TIMEOUT: 10000, // 10 seconds for registry requests
23
- MAX_CONCURRENT_CHECKS: 5, // Max parallel registry checks
24
- BACKUP_EXTENSION: '.backup.json', // Backup file extension
25
- CREATE_BACKUPS: true, // Always create backups
26
- RETRY_ATTEMPTS: 3, // Registry request retry attempts
27
- RETRY_DELAY: 1000, // Delay between retries (ms)
28
- MAX_DEPENDENCIES: 500, // Safety limit
29
- NPM_REGISTRY_URL: 'https://registry.npmjs.org'
30
- };
31
-
32
- /**
33
- * DependencyResolverTool - Modern implementation
34
- * Resolves Node.js package dependency conflicts with improved security and reliability
35
- */
36
- export class DependencyResolverTool extends BaseTool {
37
- /**
38
- * Get tool description for agent system prompt
39
- * @returns {string} Formatted tool description
40
- */
41
- getDescription() {
42
- return `Tool: Dependency Resolver - Resolve Node.js package dependency conflicts
43
-
44
- **Purpose:** Checks npm dependencies for updates and optionally updates package.json to latest compatible versions automatically.
45
-
46
- **Invocation Syntax:**
47
-
48
- XML Format:
49
- \`\`\`xml
50
- <dependency-resolve>
51
- <path>./my-project</path>
52
- <mode>check</mode>
53
- <include-dev>true</include-dev>
54
- </dependency-resolve>
55
- \`\`\`
56
-
57
- JSON Format:
58
- \`\`\`json
59
- {
60
- "toolId": "dependency-resolver",
61
- "parameters": {
62
- "path": "./my-project",
63
- "mode": "check",
64
- "includeDev": true
65
- }
66
- }
67
- \`\`\`
68
-
69
- **Parameters:**
70
- - **path** (string, optional): Path to project directory with package.json. Default: "."
71
- - **mode** (string, optional): Operation mode. Options:
72
- - "check" - Only check for updates (default)
73
- - "fix" - Update package.json and run npm install
74
- - "auto" - Automatically fix all conflicts
75
- - **includeDev** (boolean, optional): Include devDependencies. Default: true
76
-
77
- **What It Does:**
78
- - Checks npm registry for latest compatible versions
79
- - Respects semver ranges (^, ~, >=, etc.)
80
- - Creates automatic backups before modifications
81
- - Runs npm install after updates (in fix/auto mode)
82
- - Provides detailed update report
83
-
84
- **Examples:**
85
-
86
- 1. Check for updates:
87
- \`\`\`xml
88
- <dependency-resolver>
89
- <mode>check</mode>
90
- </dependency-resolver>
91
- \`\`\`
92
-
93
- 2. Fix outdated dependencies:
94
- \`\`\`xml
95
- <dependency-resolver>
96
- <path>./my-project</path>
97
- <mode>fix</mode>
98
- </dependency-resolver>
99
- \`\`\`
100
-
101
- 3. Auto-fix with devDependencies:
102
- \`\`\`json
103
- {
104
- "toolId": "dependency-resolver",
105
- "parameters": { "mode": "auto", "includeDev": true }
106
- }
107
- \`\`\`
108
-
109
- **Notes:**
110
- - Always creates backup (.backup.json) before modifications
111
- - Network requests have timeout and retry logic
112
- - npm install runs with timeout protection (5 minutes max)
113
- - Supports complex semver ranges (||, &&, etc.)`;
114
- }
115
-
116
- /**
117
- * Parse tool parameters from raw content (XML or JSON)
118
- * @param {string|Object} content - Raw tool content or parsed object
119
- * @returns {Object} Parsed parameters
120
- */
121
- parseParameters(content) {
122
- // If already an object, validate and return
123
- if (typeof content === 'object' && content !== null) {
124
- return {
125
- path: content.path || '.',
126
- mode: content.mode || RESOLVER_CONFIG.DEFAULT_MODE,
127
- includeDev: content.includeDev !== undefined ? content.includeDev : true
128
- };
129
- }
130
-
131
- // Parse XML content
132
- if (typeof content === 'string') {
133
- // Try modern XML format first: <dependency-resolve>...</dependency-resolve>
134
- const modernPattern = /<dependency-resolve([^>]*)>([\s\S]*?)<\/dependency-resolve>/i;
135
- const modernMatch = modernPattern.exec(content);
136
-
137
- if (modernMatch) {
138
- const attributesStr = modernMatch[1];
139
- const innerContent = modernMatch[2];
140
-
141
- // Parse attributes from opening tag
142
- const pathAttr = /path=["']([^"']*)["']/i.exec(attributesStr);
143
- const modeAttr = /mode=["']([^"']*)["']/i.exec(attributesStr);
144
- const includeDevAttr = /include-dev=["']([^"']*)["']/i.exec(attributesStr);
145
-
146
- // Extract from inner content
147
- const pathPattern = /<path>(.*?)<\/path>/i;
148
- const pathMatch = pathPattern.exec(innerContent);
149
-
150
- const modePattern = /<mode>(.*?)<\/mode>/i;
151
- const modeMatch = modePattern.exec(innerContent);
152
-
153
- const includeDevPattern = /<include-dev>(.*?)<\/include-dev>/i;
154
- const includeDevMatch = includeDevPattern.exec(innerContent);
155
-
156
- // Content takes precedence over attributes
157
- const extractedPath = (pathMatch ? pathMatch[1].trim() : null) || (pathAttr ? pathAttr[1] : '.');
158
- const extractedMode = (modeMatch ? modeMatch[1].trim() : null) || (modeAttr ? modeAttr[1] : RESOLVER_CONFIG.DEFAULT_MODE);
159
- const extractedIncludeDev = (includeDevMatch ? includeDevMatch[1].trim() : null) || (includeDevAttr ? includeDevAttr[1] : 'true');
160
-
161
- return {
162
- path: extractedPath,
163
- mode: extractedMode,
164
- includeDev: this._parseBoolean(extractedIncludeDev, true)
165
- };
166
- }
167
-
168
- // Try legacy format: [resolve path="..." mode="..."]
169
- const legacyPattern = /\[resolve\s+([^\]]*)\]/i;
170
- const legacyMatch = legacyPattern.exec(content);
171
-
172
- if (legacyMatch) {
173
- const attrString = legacyMatch[1];
174
-
175
- // Parse attributes manually
176
- const pathAttr = /path=["']([^"']*)["']/i.exec(attrString);
177
- const modeAttr = /mode=["']([^"']*)["']/i.exec(attrString);
178
- const includeDevAttr = /include-dev=["']([^"']*)["']/i.exec(attrString);
179
-
180
- return {
181
- path: pathAttr ? pathAttr[1] : '.',
182
- mode: modeAttr ? modeAttr[1] : RESOLVER_CONFIG.DEFAULT_MODE,
183
- includeDev: this._parseBoolean(includeDevAttr ? includeDevAttr[1] : 'true', true)
184
- };
185
- }
186
-
187
- throw new Error('Invalid dependency-resolve format. Use <dependency-resolve> tags or JSON format.');
188
- }
189
-
190
- throw new Error('Invalid parameter format. Expected string (XML) or object (JSON).');
191
- }
192
-
193
- /**
194
- * Parse boolean from string or boolean
195
- * @param {any} value - Value to parse
196
- * @param {boolean} defaultValue - Default if undefined
197
- * @returns {boolean}
198
- * @private
199
- */
200
- _parseBoolean(value, defaultValue = false) {
201
- if (value === undefined || value === null) return defaultValue;
202
- if (typeof value === 'boolean') return value;
203
- if (typeof value === 'string') {
204
- return value.toLowerCase() === 'true' || value === '1';
205
- }
206
- return defaultValue;
207
- }
208
-
209
- /**
210
- * Validate parameters
211
- * @param {Object} params - Parameters to validate
212
- * @throws {Error} If validation fails
213
- * @private
214
- */
215
- _validateParameters(params) {
216
- if (!params || typeof params !== 'object') {
217
- throw new Error('Parameters must be an object');
218
- }
219
-
220
- if (params.path && typeof params.path !== 'string') {
221
- throw new Error('path must be a string');
222
- }
223
-
224
- if (params.mode && !RESOLVER_CONFIG.VALID_MODES.includes(params.mode)) {
225
- throw new Error(`Invalid mode: ${params.mode}. Must be one of: ${RESOLVER_CONFIG.VALID_MODES.join(', ')}`);
226
- }
227
-
228
- if (params.includeDev !== undefined && typeof params.includeDev !== 'boolean') {
229
- throw new Error('includeDev must be a boolean');
230
- }
231
- }
232
-
233
- /**
234
- * Validate and resolve file path
235
- * @param {string} targetPath - Target path from parameters
236
- * @param {Object} context - Execution context
237
- * @returns {string} Resolved absolute path
238
- * @throws {Error} If path is invalid or inaccessible
239
- * @private
240
- */
241
- _resolveAndValidatePath(targetPath, context) {
242
- const { projectDir, directoryAccess } = context;
243
-
244
- // Determine working directory
245
- let workingDirectory = projectDir || process.cwd();
246
-
247
- if (directoryAccess && directoryAccess.workingDirectory) {
248
- workingDirectory = directoryAccess.workingDirectory;
249
- }
250
-
251
- // Resolve the target path
252
- const resolvedPath = path.isAbsolute(targetPath)
253
- ? path.normalize(targetPath)
254
- : path.normalize(path.join(workingDirectory, targetPath));
255
-
256
- // Security: Check for path traversal
257
- const realWorkingDir = path.normalize(workingDirectory);
258
- if (!resolvedPath.startsWith(realWorkingDir)) {
259
- throw new Error(`Path traversal detected: ${targetPath} resolves outside working directory`);
260
- }
261
-
262
- return resolvedPath;
263
- }
264
-
265
- /**
266
- * Create backup of package.json
267
- * @param {string} pkgPath - Path to package.json
268
- * @returns {Promise<string|null>} Backup file path or null if failed
269
- * @private
270
- */
271
- async _createBackup(pkgPath) {
272
- if (!RESOLVER_CONFIG.CREATE_BACKUPS) {
273
- return null;
274
- }
275
-
276
- try {
277
- const backupPath = pkgPath + RESOLVER_CONFIG.BACKUP_EXTENSION;
278
- await fs.copyFile(pkgPath, backupPath);
279
- this.logger?.info('Created backup', { backupPath });
280
- return backupPath;
281
- } catch (error) {
282
- this.logger?.warn('Failed to create backup', { error: error.message });
283
- return null;
284
- }
285
- }
286
-
287
- /**
288
- * Fetch package info from npm registry with retries
289
- * @param {string} packageName - Package name
290
- * @returns {Promise<Object|null>} Package data or null if failed
291
- * @private
292
- */
293
- async _fetchPackageInfo(packageName) {
294
- const url = `${RESOLVER_CONFIG.NPM_REGISTRY_URL}/${encodeURIComponent(packageName)}`;
295
-
296
- for (let attempt = 1; attempt <= RESOLVER_CONFIG.RETRY_ATTEMPTS; attempt++) {
297
- try {
298
- const controller = new AbortController();
299
- const timeout = setTimeout(() => controller.abort(), RESOLVER_CONFIG.REGISTRY_TIMEOUT);
300
-
301
- const response = await fetch(url, { signal: controller.signal });
302
- clearTimeout(timeout);
303
-
304
- if (!response.ok) {
305
- if (response.status === 404) {
306
- this.logger?.warn(`Package not found: ${packageName}`);
307
- return null;
308
- }
309
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
310
- }
311
-
312
- const data = await response.json();
313
-
314
- // Validate response structure
315
- if (!data || typeof data !== 'object' || !data['dist-tags']) {
316
- throw new Error('Invalid registry response format');
317
- }
318
-
319
- return data;
320
-
321
- } catch (error) {
322
- if (attempt < RESOLVER_CONFIG.RETRY_ATTEMPTS) {
323
- this.logger?.debug(`Retry ${attempt}/${RESOLVER_CONFIG.RETRY_ATTEMPTS} for ${packageName}`);
324
- await new Promise(resolve => setTimeout(resolve, RESOLVER_CONFIG.RETRY_DELAY * attempt));
325
- } else {
326
- this.logger?.error(`Failed to fetch ${packageName}:`, error.message);
327
- return null;
328
- }
329
- }
330
- }
331
-
332
- return null;
333
- }
334
-
335
- /**
336
- * Get latest compatible version for a package
337
- * Enhanced self-contained semver logic supporting:
338
- * - Caret ranges (^) with 0.x.y and 0.0.x special cases
339
- * - Tilde ranges (~)
340
- * - Comparison operators (>, >=, <, <=)
341
- * - X-ranges (4.x, 4.*, etc.)
342
- * - Pre-release versions
343
- * - Complex range expressions (AND/OR)
344
- * - Exact versions
345
- *
346
- * @param {string} packageName - Package name
347
- * @param {string} currentRange - Current version range
348
- * @returns {Promise<string|null>} Latest version or null if no update needed
349
- * @private
350
- */
351
- async _getLatestCompatibleVersion(packageName, currentRange) {
352
- const data = await this._fetchPackageInfo(packageName);
353
-
354
- if (!data) {
355
- return null;
356
- }
357
-
358
- const latest = data['dist-tags']?.latest;
359
-
360
- if (!latest) {
361
- return null;
362
- }
363
-
364
- // Parse latest version
365
- const latestParsed = this._parseVersion(latest);
366
-
367
- if (!latestParsed) {
368
- return null; // Can't parse latest
369
- }
370
-
371
- // Check if it's a complex range (AND/OR)
372
- if (this._isComplexRange(currentRange)) {
373
- const complexRange = this._parseComplexRange(currentRange);
374
- const isUpdateAvailable = this._satisfiesComplexRange(complexRange, latestParsed);
375
-
376
- if (isUpdateAvailable) {
377
- // For complex ranges, preserve the original format
378
- return latest;
379
- }
380
- return null;
381
- }
382
-
383
- // Simple range - parse normally
384
- const rangeInfo = this._parseVersionRange(currentRange);
385
-
386
- if (!rangeInfo) {
387
- return null; // Can't parse, skip
388
- }
389
-
390
- // Check if update is available and compatible
391
- const isUpdateAvailable = this._isUpdateAvailable(rangeInfo, latestParsed);
392
-
393
- if (isUpdateAvailable) {
394
- // Preserve the original prefix
395
- return rangeInfo.prefix + latest;
396
- }
397
-
398
- return null;
399
- }
400
-
401
- /**
402
- * Parse a version string into components including pre-release and build metadata
403
- * @param {string} version - Version string (e.g., "4.17.1", "1.0.0-alpha.1", "1.0.0+build.123")
404
- * @returns {Object|null} Parsed version or null
405
- * @private
406
- */
407
- _parseVersion(version) {
408
- // Match: major.minor.patch[-prerelease][+build]
409
- // Pre-release and build are optional
410
- const pattern = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
411
- const match = pattern.exec(version);
412
-
413
- if (!match) {
414
- // Fallback: try simple X.Y.Z pattern without pre-release/build
415
- const simpleMatch = version.match(/^(\d+)\.(\d+)\.(\d+)/);
416
- if (simpleMatch) {
417
- return {
418
- major: parseInt(simpleMatch[1], 10),
419
- minor: parseInt(simpleMatch[2], 10),
420
- patch: parseInt(simpleMatch[3], 10),
421
- prerelease: null,
422
- build: null
423
- };
424
- }
425
- return null;
426
- }
427
-
428
- return {
429
- major: parseInt(match[1], 10),
430
- minor: parseInt(match[2], 10),
431
- patch: parseInt(match[3], 10),
432
- prerelease: match[4] ? match[4].split('.') : null,
433
- build: match[5] || null
434
- };
435
- }
436
-
437
- /**
438
- * Compare two versions according to semver rules
439
- * Returns: < 0 if v1 < v2, 0 if v1 === v2, > 0 if v1 > v2
440
- * Handles pre-release versions correctly:
441
- * - 1.0.0 > 1.0.0-alpha (release > pre-release)
442
- * - 1.0.0-alpha < 1.0.0-beta (lexical comparison)
443
- * - 1.0.0-1 < 1.0.0-2 (numeric comparison)
444
- * @param {Object} v1 - First version
445
- * @param {Object} v2 - Second version
446
- * @returns {number} Comparison result
447
- * @private
448
- */
449
- _compareVersions(v1, v2) {
450
- // Compare major.minor.patch first
451
- if (v1.major !== v2.major) return v1.major - v2.major;
452
- if (v1.minor !== v2.minor) return v1.minor - v2.minor;
453
- if (v1.patch !== v2.patch) return v1.patch - v2.patch;
454
-
455
- // When major.minor.patch are equal, check pre-release
456
- // According to semver spec:
457
- // 1. Release version (no prerelease) > prerelease version
458
- // 2. If both have prerelease, compare identifiers
459
-
460
- if (!v1.prerelease && !v2.prerelease) {
461
- // Both are release versions, equal
462
- return 0;
463
- }
464
-
465
- if (!v1.prerelease && v2.prerelease) {
466
- // v1 is release, v2 is pre-release → v1 > v2
467
- return 1;
468
- }
469
-
470
- if (v1.prerelease && !v2.prerelease) {
471
- // v1 is pre-release, v2 is release → v1 < v2
472
- return -1;
473
- }
474
-
475
- // Both have pre-release, compare them
476
- return this._comparePrerelease(v1.prerelease, v2.prerelease);
477
- }
478
-
479
- /**
480
- * Compare pre-release version identifiers according to semver spec
481
- * Identifiers are compared as:
482
- * 1. Numeric identifiers are compared numerically
483
- * 2. Alphanumeric identifiers are compared lexically (ASCII sort)
484
- * 3. Numeric identifiers have lower precedence than alphanumeric
485
- * 4. Larger set of identifiers has higher precedence if all preceding are equal
486
- * @param {Array<string>} pre1 - First pre-release identifiers
487
- * @param {Array<string>} pre2 - Second pre-release identifiers
488
- * @returns {number} Comparison result
489
- * @private
490
- */
491
- _comparePrerelease(pre1, pre2) {
492
- const len = Math.max(pre1.length, pre2.length);
493
-
494
- for (let i = 0; i < len; i++) {
495
- // If one pre-release has fewer identifiers, it has lower precedence
496
- if (i >= pre1.length) return -1; // pre1 is shorter, pre1 < pre2
497
- if (i >= pre2.length) return 1; // pre2 is shorter, pre1 > pre2
498
-
499
- const part1 = pre1[i];
500
- const part2 = pre2[i];
501
-
502
- // Check if parts are numeric
503
- const num1 = /^\d+$/.test(part1) ? parseInt(part1, 10) : null;
504
- const num2 = /^\d+$/.test(part2) ? parseInt(part2, 10) : null;
505
-
506
- // Both numeric: compare numerically
507
- if (num1 !== null && num2 !== null) {
508
- if (num1 !== num2) return num1 - num2;
509
- continue;
510
- }
511
-
512
- // One numeric, one alphanumeric: numeric has lower precedence
513
- if (num1 !== null && num2 === null) return -1;
514
- if (num1 === null && num2 !== null) return 1;
515
-
516
- // Both alphanumeric: compare lexically
517
- if (part1 < part2) return -1;
518
- if (part1 > part2) return 1;
519
- }
520
-
521
- // All identifiers equal
522
- return 0;
523
- }
524
-
525
- /**
526
- * Parse version range into components
527
- * @param {string} range - Version range (e.g., "^4.17.1", "~4.17.1", "<5.0.0", "4.x", "4.*")
528
- * @returns {Object|null} Parsed range or null
529
- * @private
530
- */
531
- _parseVersionRange(range) {
532
- const trimmed = range.trim();
533
-
534
- // Check for X-ranges first: 4.x, 4.*, 4.17.x, 4.17.*, or just 4
535
- // X-ranges use 'x', '*', or missing parts as wildcards
536
- const xRangePattern = /^(\d+|\*|x)(\.(\d+|\*|x))?(\.(\d+|\*|x))?$/i;
537
- const xMatch = xRangePattern.exec(trimmed);
538
-
539
- if (xMatch) {
540
- const majorStr = xMatch[1];
541
- const minorStr = xMatch[3];
542
- const patchStr = xMatch[5];
543
-
544
- // Check if any part is wildcard or missing (making it an X-range)
545
- const isXRange =
546
- majorStr === '*' || majorStr.toLowerCase() === 'x' ||
547
- minorStr === undefined || minorStr === '*' || minorStr.toLowerCase() === 'x' ||
548
- patchStr === undefined || patchStr === '*' || patchStr.toLowerCase() === 'x';
549
-
550
- if (isXRange) {
551
- return {
552
- prefix: '',
553
- operator: 'x-range',
554
- major: (majorStr === '*' || majorStr.toLowerCase() === 'x') ? null : parseInt(majorStr, 10),
555
- minor: (!minorStr || minorStr === '*' || minorStr.toLowerCase() === 'x') ? null : parseInt(minorStr, 10),
556
- patch: (!patchStr || patchStr === '*' || patchStr.toLowerCase() === 'x') ? null : parseInt(patchStr, 10),
557
- original: range
558
- };
559
- }
560
- }
561
-
562
- // Extract prefix and version for other operators
563
- let prefix = '';
564
- let version = trimmed;
565
- let operator = '=';
566
-
567
- if (trimmed.startsWith('^')) {
568
- prefix = '^';
569
- version = trimmed.slice(1);
570
- operator = '^';
571
- } else if (trimmed.startsWith('~')) {
572
- prefix = '~';
573
- version = trimmed.slice(1);
574
- operator = '~';
575
- } else if (trimmed.startsWith('>=')) {
576
- prefix = '>=';
577
- version = trimmed.slice(2).trim();
578
- operator = '>=';
579
- } else if (trimmed.startsWith('>')) {
580
- prefix = '>';
581
- version = trimmed.slice(1).trim();
582
- operator = '>';
583
- } else if (trimmed.startsWith('<=')) {
584
- prefix = '<=';
585
- version = trimmed.slice(2).trim();
586
- operator = '<=';
587
- } else if (trimmed.startsWith('<')) {
588
- prefix = '<';
589
- version = trimmed.slice(1).trim();
590
- operator = '<';
591
- }
592
-
593
- // Parse version X.Y.Z (including pre-release and build)
594
- const parsed = this._parseVersion(version);
595
-
596
- if (!parsed) {
597
- return null;
598
- }
599
-
600
- return {
601
- prefix,
602
- operator,
603
- major: parsed.major,
604
- minor: parsed.minor,
605
- patch: parsed.patch,
606
- prerelease: parsed.prerelease,
607
- build: parsed.build,
608
- original: range
609
- };
610
- }
611
-
612
- /**
613
- * Check if update is available and compatible with range
614
- * @param {Object} rangeInfo - Parsed range information
615
- * @param {Object} latest - Parsed latest version
616
- * @returns {boolean} True if update available
617
- * @private
618
- */
619
- _isUpdateAvailable(rangeInfo, latest) {
620
- const current = {
621
- major: rangeInfo.major,
622
- minor: rangeInfo.minor,
623
- patch: rangeInfo.patch,
624
- prerelease: rangeInfo.prerelease || null,
625
- build: rangeInfo.build || null
626
- };
627
-
628
- // Check based on operator
629
- switch (rangeInfo.operator) {
630
- case '^':
631
- return this._isCaretUpdateAvailable(current, latest);
632
-
633
- case '~':
634
- return this._isTildeUpdateAvailable(current, latest);
635
-
636
- case '>=':
637
- case '>':
638
- return this._isSimpleUpdateAvailable(current, latest);
639
-
640
- case '<':
641
- case '<=':
642
- return this._isLessThanUpdateAvailable(rangeInfo, latest);
643
-
644
- case 'x-range':
645
- return this._isXRangeUpdateAvailable(rangeInfo, latest);
646
-
647
- case '=':
648
- default:
649
- return this._isExactUpdateAvailable(current, latest);
650
- }
651
- }
652
-
653
- /**
654
- * Check if update is available for caret range (^)
655
- * Handles special cases:
656
- * - ^0.0.X → Only patch updates in 0.0.*
657
- * - ^0.X.Y → Only patch updates in 0.X.*
658
- * - ^X.Y.Z → Minor and patch updates in X.*.*
659
- * Also handles pre-release versions correctly
660
- * @private
661
- */
662
- _isCaretUpdateAvailable(current, latest) {
663
- // First check if latest is actually greater than current
664
- const cmp = this._compareVersions(latest, current);
665
- if (cmp <= 0) {
666
- // latest is not greater than current
667
- return false;
668
- }
669
-
670
- // ^0.0.X → Only patch updates in 0.0.*
671
- if (current.major === 0 && current.minor === 0) {
672
- return latest.major === 0 && latest.minor === 0;
673
- }
674
-
675
- // ^0.X.Y → Only patch updates in 0.X.*
676
- if (current.major === 0) {
677
- return latest.major === 0 && latest.minor === current.minor;
678
- }
679
-
680
- // ^X.Y.Z → Any minor/patch update in X.*.*
681
- return latest.major === current.major;
682
- }
683
-
684
- /**
685
- * Check if update is available for tilde range (~)
686
- * ~X.Y.Z → Only patch updates in X.Y.*
687
- * Also handles pre-release versions correctly
688
- * @private
689
- */
690
- _isTildeUpdateAvailable(current, latest) {
691
- // First check if latest is actually greater than current
692
- const cmp = this._compareVersions(latest, current);
693
- if (cmp <= 0) {
694
- return false;
695
- }
696
-
697
- // Must be same major and minor
698
- return latest.major === current.major && latest.minor === current.minor;
699
- }
700
-
701
- /**
702
- * Check if update is available for simple comparison (>, >=)
703
- * Also handles pre-release versions correctly
704
- * @private
705
- */
706
- _isSimpleUpdateAvailable(current, latest) {
707
- // Use proper version comparison that handles pre-release
708
- const cmp = this._compareVersions(latest, current);
709
- return cmp > 0;
710
- }
711
-
712
- /**
713
- * Check if update is available for exact version
714
- * Suggests update if latest is newer
715
- * @private
716
- */
717
- _isExactUpdateAvailable(current, latest) {
718
- return this._isSimpleUpdateAvailable(current, latest);
719
- }
720
-
721
- /**
722
- * Check if update is available for less than operators (<, <=)
723
- * <X.Y.Z → latest must be < range
724
- * <=X.Y.Z → latest must be <= range
725
- * Also handles pre-release versions correctly
726
- * @param {Object} rangeInfo - Parsed range information
727
- * @param {Object} latest - Parsed latest version
728
- * @returns {boolean} True if update satisfies constraint
729
- * @private
730
- */
731
- _isLessThanUpdateAvailable(rangeInfo, latest) {
732
- // Use proper version comparison that handles pre-release
733
- const cmp = this._compareVersions(latest, rangeInfo);
734
-
735
- if (rangeInfo.operator === '<') {
736
- // latest must be < range
737
- return cmp < 0;
738
- } else if (rangeInfo.operator === '<=') {
739
- // latest must be <= range
740
- return cmp <= 0;
741
- }
742
- return false;
743
- }
744
-
745
- /**
746
- * Check if update is available for X-ranges (4.x, 4.*, 4.17.x, etc.)
747
- * X-ranges match any version within the specified parts
748
- * 4.x or 4.* → any version 4.Y.Z
749
- * 4.17.x or 4.17.* → any version 4.17.Z
750
- * *.*.* → any version
751
- * @param {Object} rangeInfo - Parsed range information
752
- * @param {Object} latest - Parsed latest version
753
- * @returns {boolean} True if update is within range
754
- * @private
755
- */
756
- _isXRangeUpdateAvailable(rangeInfo, latest) {
757
- // Check major version if specified
758
- if (rangeInfo.major !== null && latest.major !== rangeInfo.major) {
759
- return false;
760
- }
761
-
762
- // Check minor version if specified
763
- if (rangeInfo.minor !== null && latest.minor !== rangeInfo.minor) {
764
- return false;
765
- }
766
-
767
- // Check patch version if specified
768
- if (rangeInfo.patch !== null && latest.patch !== rangeInfo.patch) {
769
- return false;
770
- }
771
-
772
- // All specified parts match, update is within range
773
- return true;
774
- }
775
-
776
- /**
777
- * Check if a range string is a complex range (contains AND/OR operators)
778
- * Complex ranges include:
779
- * - OR ranges: "^4.0.0 || ^5.0.0"
780
- * - AND ranges: ">=4.0.0 <5.0.0" (space-separated, multiple constraints)
781
- * @param {string} range - Version range string
782
- * @returns {boolean} True if complex range
783
- * @private
784
- */
785
- _isComplexRange(range) {
786
- // Check for OR operator
787
- if (range.includes('||')) {
788
- return true;
789
- }
790
-
791
- // Check for AND (multiple space-separated ranges)
792
- // Need to detect patterns like ">=4.0.0 <5.0.0"
793
- // But NOT "^4.0.0" or "~4.0.0" (single ranges with spaces after)
794
- const trimmed = range.trim();
795
-
796
- // Remove single operator prefixes to see what's left
797
- if (trimmed.startsWith('^') || trimmed.startsWith('~')) {
798
- return false; // Single caret or tilde range
799
- }
800
-
801
- // Split by whitespace and check if there are multiple parts
802
- const parts = trimmed.split(/\s+/).filter(p => p.length > 0);
803
-
804
- // If we have multiple parts, it might be a complex AND range
805
- // Examples: [">=4.0.0", "<5.0.0"], [">1.0.0", "<2.0.0"]
806
- if (parts.length > 1) {
807
- // Check if each part looks like a range operator
808
- const rangeOperators = /^(>=?|<=?|\^|~|[0-9])/;
809
- return parts.every(part => rangeOperators.test(part));
810
- }
811
-
812
- return false;
813
- }
814
-
815
- /**
816
- * Parse a complex range expression into a structured format
817
- * Handles:
818
- * - OR: "^4.0.0 || ^5.0.0" → {type: 'or', ranges: [...]}
819
- * - AND: ">=4.0.0 <5.0.0" → {type: 'and', ranges: [...]}
820
- * - Simple: "^4.0.0" → {type: 'simple', range: {...}}
821
- * @param {string} range - Complex range string
822
- * @returns {Object} Parsed complex range structure
823
- * @private
824
- */
825
- _parseComplexRange(range) {
826
- // Split by OR first (|| has precedence)
827
- if (range.includes('||')) {
828
- const orParts = range.split('||').map(p => p.trim());
829
- return {
830
- type: 'or',
831
- ranges: orParts.map(part => this._parseComplexRange(part))
832
- };
833
- }
834
-
835
- // Split by AND (space-separated, no || present)
836
- const andParts = range.trim().split(/\s+/).filter(p => p.length > 0);
837
-
838
- if (andParts.length > 1) {
839
- return {
840
- type: 'and',
841
- ranges: andParts.map(part => this._parseVersionRange(part))
842
- };
843
- }
844
-
845
- // Simple range
846
- return {
847
- type: 'simple',
848
- range: this._parseVersionRange(range)
849
- };
850
- }
851
-
852
- /**
853
- * Check if a version satisfies a single range
854
- * @param {Object} rangeInfo - Parsed range information
855
- * @param {Object} version - Parsed version to check
856
- * @returns {boolean} True if version satisfies range
857
- * @private
858
- */
859
- _satisfiesRange(rangeInfo, version) {
860
- if (!rangeInfo || !version) {
861
- return false;
862
- }
863
-
864
- // Use the existing _isUpdateAvailable logic which handles all operators
865
- return this._isUpdateAvailable(rangeInfo, version);
866
- }
867
-
868
- /**
869
- * Check if a version satisfies a complex range expression
870
- * Handles AND/OR logic recursively
871
- * @param {Object} complexRange - Parsed complex range structure
872
- * @param {Object} version - Parsed version to check
873
- * @returns {boolean} True if version satisfies the complex range
874
- * @private
875
- */
876
- _satisfiesComplexRange(complexRange, version) {
877
- if (!complexRange || !version) {
878
- return false;
879
- }
880
-
881
- switch (complexRange.type) {
882
- case 'simple':
883
- return this._satisfiesRange(complexRange.range, version);
884
-
885
- case 'and':
886
- // ALL ranges must be satisfied
887
- return complexRange.ranges.every(range => this._satisfiesRange(range, version));
888
-
889
- case 'or':
890
- // AT LEAST ONE range must be satisfied
891
- return complexRange.ranges.some(range => this._satisfiesComplexRange(range, version));
892
-
893
- default:
894
- return false;
895
- }
896
- }
897
-
898
- /**
899
- * Check dependencies in batches to avoid overwhelming the registry
900
- * @param {Object} dependencies - Map of package names to versions
901
- * @returns {Promise<Object>} Map of packages with available updates
902
- * @private
903
- */
904
- async _checkDependencies(dependencies) {
905
- const updates = {};
906
- const entries = Object.entries(dependencies);
907
-
908
- // Process in batches
909
- for (let i = 0; i < entries.length; i += RESOLVER_CONFIG.MAX_CONCURRENT_CHECKS) {
910
- const batch = entries.slice(i, i + RESOLVER_CONFIG.MAX_CONCURRENT_CHECKS);
911
-
912
- const promises = batch.map(async ([pkg, range]) => {
913
- try {
914
- const latest = await this._getLatestCompatibleVersion(pkg, range);
915
-
916
- if (latest) {
917
- // Preserve the range prefix (^, ~, etc.)
918
- const prefix = range.match(/^[\^~]/)?.[0] || '^';
919
- return { pkg, newVersion: `${prefix}${latest}`, oldVersion: range };
920
- }
921
-
922
- return null;
923
- } catch (error) {
924
- this.logger?.error(`Error checking ${pkg}:`, error.message);
925
- return null;
926
- }
927
- });
928
-
929
- const results = await Promise.all(promises);
930
-
931
- results.forEach(result => {
932
- if (result) {
933
- updates[result.pkg] = result.newVersion;
934
- }
935
- });
936
- }
937
-
938
- return updates;
939
- }
940
-
941
- /**
942
- * Execute tool with parsed parameters
943
- * @param {Object} params - Parsed parameters
944
- * @param {Object} context - Execution context
945
- * @returns {Promise<Object>} Execution result
946
- */
947
- async execute(params, context = {}) {
948
- try {
949
- // Validate parameters
950
- this._validateParameters(params);
951
-
952
- const { path: targetPath, mode, includeDev } = params;
953
- const { projectDir, agentId, directoryAccess } = context;
954
-
955
- // Resolve and validate path
956
- const resolvedPath = this._resolveAndValidatePath(targetPath, context);
957
- const pkgPath = path.join(resolvedPath, 'package.json');
958
-
959
- this.logger?.info('Dependency resolver executing', {
960
- mode,
961
- resolvedPath,
962
- includeDev,
963
- agentId
964
- });
965
-
966
- const output = [];
967
- output.push(`🔍 Checking dependencies in: ${resolvedPath}`);
968
- output.push(`Mode: ${mode}`);
969
-
970
- // Check if package.json exists
971
- try {
972
- await fs.access(pkgPath);
973
- } catch {
974
- return {
975
- success: false,
976
- error: `No package.json found at: ${pkgPath}`,
977
- output: output.join('\n')
978
- };
979
- }
980
-
981
- // Read package.json
982
- output.push('\n📦 Reading package.json...');
983
- const pkgContent = await fs.readFile(pkgPath, 'utf-8');
984
- const pkgData = JSON.parse(pkgContent);
985
-
986
- // Collect dependencies
987
- const allDeps = { ...pkgData.dependencies };
988
-
989
- if (includeDev && pkgData.devDependencies) {
990
- Object.assign(allDeps, pkgData.devDependencies);
991
- }
992
-
993
- if (Object.keys(allDeps).length === 0) {
994
- return {
995
- success: true,
996
- mode,
997
- message: 'No dependencies found in package.json',
998
- statistics: {
999
- totalDependencies: 0,
1000
- updatesAvailable: 0,
1001
- updatesApplied: 0,
1002
- errors: 0
1003
- },
1004
- output: output.join('\n')
1005
- };
1006
- }
1007
-
1008
- // Safety check
1009
- if (Object.keys(allDeps).length > RESOLVER_CONFIG.MAX_DEPENDENCIES) {
1010
- return {
1011
- success: false,
1012
- error: `Too many dependencies (${Object.keys(allDeps).length}), max allowed: ${RESOLVER_CONFIG.MAX_DEPENDENCIES}`,
1013
- output: output.join('\n')
1014
- };
1015
- }
1016
-
1017
- output.push(`📊 Found ${Object.keys(allDeps).length} dependencies to check`);
1018
- output.push('🌐 Querying npm registry for updates...');
1019
-
1020
- // Check for updates
1021
- const updates = await this._checkDependencies(allDeps);
1022
-
1023
- output.push(`\n✅ Registry check complete`);
1024
- output.push(`📈 Updates available: ${Object.keys(updates).length}`);
1025
-
1026
- if (Object.keys(updates).length > 0) {
1027
- output.push('\n📋 Available updates:');
1028
- for (const [pkg, newVersion] of Object.entries(updates)) {
1029
- const oldVersion = allDeps[pkg];
1030
- output.push(` • ${pkg}: ${oldVersion} → ${newVersion}`);
1031
- }
1032
- } else {
1033
- output.push('\n🎉 All dependencies are up-to-date!');
1034
- }
1035
-
1036
- // Handle modes
1037
- if (mode === 'check') {
1038
- // Check mode - just report
1039
- if (Object.keys(updates).length > 0) {
1040
- output.push('\n💡 Run with mode="fix" or mode="auto" to apply updates');
1041
- }
1042
-
1043
- return {
1044
- success: true,
1045
- mode: 'check',
1046
- message: `Found ${Object.keys(updates).length} package(s) with available updates`,
1047
- statistics: {
1048
- totalDependencies: Object.keys(allDeps).length,
1049
- updatesAvailable: Object.keys(updates).length,
1050
- updatesApplied: 0,
1051
- errors: 0
1052
- },
1053
- updates,
1054
- output: output.join('\n')
1055
- };
1056
- }
1057
-
1058
- // Fix or auto mode - apply updates
1059
- if ((mode === 'fix' || mode === 'auto') && Object.keys(updates).length > 0) {
1060
- // Create backup
1061
- output.push('\n💾 Creating backup of package.json...');
1062
- const backupPath = await this._createBackup(pkgPath);
1063
-
1064
- if (backupPath) {
1065
- output.push(`✅ Backup created: ${path.basename(backupPath)}`);
1066
- } else {
1067
- output.push('⚠️ Backup creation failed, continuing anyway...');
1068
- }
1069
-
1070
- // Update package.json
1071
- output.push('\n🛠 Updating package.json...');
1072
-
1073
- for (const [pkg, newVersion] of Object.entries(updates)) {
1074
- if (pkgData.dependencies?.[pkg]) {
1075
- pkgData.dependencies[pkg] = newVersion;
1076
- }
1077
- if (pkgData.devDependencies?.[pkg]) {
1078
- pkgData.devDependencies[pkg] = newVersion;
1079
- }
1080
- }
1081
-
1082
- // Write updated package.json
1083
- await fs.writeFile(pkgPath, JSON.stringify(pkgData, null, 2) + '\n');
1084
- output.push('✅ package.json updated');
1085
-
1086
- // Run npm install
1087
- output.push('\n📥 Installing dependencies (this may take a while)...');
1088
-
1089
- try {
1090
- const { stdout, stderr } = await exec('npm install', {
1091
- cwd: resolvedPath,
1092
- timeout: RESOLVER_CONFIG.NPM_COMMAND_TIMEOUT,
1093
- maxBuffer: 1024 * 1024 * 10 // 10MB buffer
1094
- });
1095
-
1096
- if (stdout) {
1097
- // Only show summary, not full output
1098
- const lines = stdout.trim().split('\n');
1099
- if (lines.length > 10) {
1100
- output.push(' ' + lines.slice(-5).join('\n '));
1101
- } else {
1102
- output.push(' ' + stdout.trim());
1103
- }
1104
- }
1105
-
1106
- if (stderr && !stderr.includes('npm WARN')) {
1107
- output.push(`⚠️ ${stderr.trim()}`);
1108
- }
1109
-
1110
- output.push('✅ Installation complete');
1111
-
1112
- // Show installed versions
1113
- try {
1114
- const { stdout: lsOutput } = await exec('npm ls --depth=0 --json', {
1115
- cwd: resolvedPath,
1116
- timeout: 30000
1117
- });
1118
-
1119
- const lsData = JSON.parse(lsOutput);
1120
-
1121
- if (lsData.dependencies) {
1122
- output.push('\n📦 Installed versions:');
1123
- for (const pkg of Object.keys(updates)) {
1124
- if (lsData.dependencies[pkg]) {
1125
- output.push(` • ${pkg}@${lsData.dependencies[pkg].version}`);
1126
- }
1127
- }
1128
- }
1129
- } catch (lsError) {
1130
- // npm ls might fail with peer dependency warnings - that's okay
1131
- this.logger?.debug('npm ls failed:', lsError.message);
1132
- }
1133
-
1134
- return {
1135
- success: true,
1136
- mode,
1137
- message: `Successfully updated ${Object.keys(updates).length} package(s)`,
1138
- statistics: {
1139
- totalDependencies: Object.keys(allDeps).length,
1140
- updatesAvailable: Object.keys(updates).length,
1141
- updatesApplied: Object.keys(updates).length,
1142
- errors: 0
1143
- },
1144
- updates,
1145
- backupCreated: backupPath !== null,
1146
- backupPath,
1147
- output: output.join('\n')
1148
- };
1149
-
1150
- } catch (installError) {
1151
- output.push(`\n❌ npm install failed: ${installError.message}`);
1152
-
1153
- // Try to restore from backup
1154
- if (backupPath) {
1155
- try {
1156
- await fs.copyFile(backupPath, pkgPath);
1157
- output.push('🔄 Restored package.json from backup');
1158
- } catch (restoreError) {
1159
- output.push('⚠️ Failed to restore backup');
1160
- }
1161
- }
1162
-
1163
- return {
1164
- success: false,
1165
- mode,
1166
- error: `npm install failed: ${installError.message}`,
1167
- statistics: {
1168
- totalDependencies: Object.keys(allDeps).length,
1169
- updatesAvailable: Object.keys(updates).length,
1170
- updatesApplied: 0,
1171
- errors: 1
1172
- },
1173
- updates,
1174
- backupCreated: backupPath !== null,
1175
- output: output.join('\n')
1176
- };
1177
- }
1178
- } else if (mode === 'fix' || mode === 'auto') {
1179
- // No updates needed
1180
- output.push('\n✨ No updates needed');
1181
-
1182
- return {
1183
- success: true,
1184
- mode,
1185
- message: 'All dependencies are up-to-date',
1186
- statistics: {
1187
- totalDependencies: Object.keys(allDeps).length,
1188
- updatesAvailable: 0,
1189
- updatesApplied: 0,
1190
- errors: 0
1191
- },
1192
- updates: {},
1193
- output: output.join('\n')
1194
- };
1195
- }
1196
-
1197
- } catch (error) {
1198
- this.logger?.error('Dependency resolver error:', error);
1199
-
1200
- return {
1201
- success: false,
1202
- error: error.message,
1203
- statistics: {
1204
- totalDependencies: 0,
1205
- updatesAvailable: 0,
1206
- updatesApplied: 0,
1207
- errors: 1
1208
- },
1209
- output: error.message
1210
- };
1211
- }
1212
- }
1213
- }
1214
-
1215
- export default DependencyResolverTool;
1
+ const a0_0xbda7d4=a0_0x45fa;(function(_0x242d86,_0x14d1a1){const _0x307555=a0_0x45fa,_0x3d8c89=_0x242d86();while(!![]){try{const _0x526017=parseInt(_0x307555(0x11c))/0x1+parseInt(_0x307555(0xca))/0x2+parseInt(_0x307555(0xa9))/0x3*(parseInt(_0x307555(0xe4))/0x4)+parseInt(_0x307555(0x119))/0x5+parseInt(_0x307555(0x102))/0x6+-parseInt(_0x307555(0xe5))/0x7+-parseInt(_0x307555(0x111))/0x8;if(_0x526017===_0x14d1a1)break;else _0x3d8c89['push'](_0x3d8c89['shift']());}catch(_0x5925e5){_0x3d8c89['push'](_0x3d8c89['shift']());}}}(a0_0x15e1,0x7f976));import{promises as a0_0x4ffdd1}from'fs';function a0_0x15e1(){const _0x5d0850=['x2LZrxHHy3rvCgrHDgvbDMfPBgfIBgu','ChjLCMvSzwfZzq','Bg9Nz2vY','Cgf0Aa','Bwf4','tLbnx1jfr0Ltvfjzx1vsta','yw5K','zxHLyW','mtq5ntuZmM9bCLznta','cVcFK6yGsw5ZDgfSBgvKihzLCNnPB25ZoG','A2v5CW','sw52ywXPzcbYzwDPC3rYEsbYzxnWB25ZzsbMB3jTyxq','uKvuuLLFqvruru1qvfm','BwfW','cVcFK4SGqxzHAwXHyMXLihvWzgf0zxm6','Dg9mB3DLCKnHC2u','Ec1Yyw5Nzq','x2LZq2fYzxrvCgrHDgvbDMfPBgfIBgu','uKvuuLLFrevmqvK','AM9PBG','x3nHDgLZzMLLC1jHBMDL','ywjVCNq','tufyx0nptKnvuLjftLrFq0Hfq0Tt','B2jQzwn0','x3jLC29SDMvbBMrwywXPzgf0zvbHDgG','qKfds1vqx0vyvevou0LptG','Aw5JBhvKzxm','cUkCQcboBYb1CgrHDgvZig5LzwrLza','Aw5JBhvKzurLDG','C29Tzq','yxv0BW','BwvZC2fNzq','zxzLCNK','ugfYyw1LDgvYCYbTDxn0igjLigfUig9IAMvJDa','mJH1zMXnAKK','otGXmZm3sePswwfN','qwXSigrLCgvUzgvUy2LLCYbHCMuGDxaTDg8Tzgf0zq','ANnVBG','x2DLDeXHDgvZDenVBxbHDgLIBgvwzxjZAw9U','z2v0rgvZy3jPChrPB24','Aw5MBW','BNbTigLUC3rHBgW','zgv2rgvWzw5Kzw5JAwvZ','4PQG77Ipica','DgvZDa','yNvPBgq','cVcFK6uGsw5ZDgfSBgLUzYbKzxbLBMrLBMnPzxmGkhrOAxmGBwf5ihrHA2uGysb3AgLSzsKUlI4','uKvhsvnuuLLFveLnru9vva','D29YA2LUz0rPCMvJDg9YEq','Cgf0y2G','rMfPBgvKihrVignYzwf0zsbIywnRDxa','rgvWzw5Kzw5JEsbYzxnVBhzLCIbLCNjVCJO','x2LZvgLSzgvvCgrHDgvbDMfPBgfIBgu','8j+uJsbdAgvJA2LUzYbKzxbLBMrLBMnPzxmGAw46ia','ihjLC29SDMvZig91DhnPzguGD29YA2LUzYbKAxjLy3rVCNK','tM8GzgvWzw5Kzw5JAwvZigzVDw5KigLUihbHy2THz2uUANnVBG','C3rHCNrZv2L0Aa','C3bSAxq','ChvZAa','x2LZwfjHBMDLvxbKyxrLqxzHAwXHyMXL','q1jfqvrfx0jbq0Tvufm','x3bHCNnLvMvYC2LVBG','C3rHDhvZ','Bwf0y2G','mZuWmtK0ofDszK5uEa','x2LZtgvZC1rOyw5vCgrHDgvbDMfPBgfIBgu','zM9YrwfJAa','CgfYC2u','ywnJzxnZ','Bw9Kzq','cUkCHsbszwDPC3rYEsbJAgvJAYbJB21WBgv0zq','x3zHBgLKyxrLugfYyw1LDgvYCW','iokgKIa','zw50CMLLCW','D2fYBG','x2nOzwnRrgvWzw5Kzw5JAwvZ','Cgf0AcbTDxn0igjLigeGC3rYAw5N','8j+mKcbrDwvYEwLUzYbUCg0GCMvNAxn0CNKGzM9YihvWzgf0zxmUlI4','y3DK','mtC1nJK0ntzkt05xqNG','yM9VBgvHBG','x3bHCNnLq29TCgXLEfjHBMDL','AxnbyNnVBhv0zq','x3nHDgLZzMLLC0nVBxbSzxHsyw5Nzq','x3bHCNnLvMvYC2LVBLjHBMDL','x2LZvxbKyxrLqxzHAwXHyMXL','C3rYAw5NAwz5','mZe0mJKZmhzuzMXtuq','x3bHCNnLqM9VBgvHBG','C2XPy2u','ndG2mhrzsLzZAG','cVcFM6aGifvWzgf0Aw5NihbHy2THz2uUANnVBI4UlG','q3jLyxrLzcbIywnRDxa','C3rYAw5N','x2nVBxbHCMvwzxjZAw9UCW','BwLUB3i','ChjLzML4','B3bLCMf0B3i','DhLWzq','zgvIDwC','cUkDJcbUCg0GAw5ZDgfSBcbMywLSzwq6ia','yxnZAwDU','x2nVBxbHCMvqCMvYzwXLyxnL','Ahr0Chm6lY9YzwDPC3rYEs5UCg1QCY5VCMC','CMfUz2vZ','mZGZmtKZz3ntBLns','vg9VBdOGrgvWzw5Kzw5JEsbszxnVBhzLCIaTifjLC29SDMuGtM9Kzs5QCYbWywnRywDLigrLCgvUzgvUy3KGy29UzMXPy3rZcGOQkLb1CNbVC2u6kIOGq2HLy2TZig5WBsbKzxbLBMrLBMnPzxmGzM9YihvWzgf0zxmGyw5Kig9WDgLVBMfSBhKGDxbKyxrLCYbWywnRywDLlMPZB24GDg8GBgf0zxn0ignVBxbHDgLIBguGDMvYC2LVBNmGyxv0B21HDgLJywXSEs4kcIOQsw52B2nHDgLVBIbtEw50yxG6kIOkcLHntcbgB3jTyxq6cMbGyhHTBaO8zgvWzw5Kzw5JEs1YzxnVBhzLpGOGidXWyxrOpI4VBxKTChjVAMvJDdWVCgf0Ad4kica8Bw9Kzt5JAgvJAZWVBw9Kzt4kica8Aw5JBhvKzs1Kzxy+Dhj1ztWVAw5JBhvKzs1Kzxy+cJWVzgvWzw5Kzw5JEs1YzxnVBhzLpGPGygakcKPtt04GrM9YBwf0oGPGygbQC29UcNSkicaIDg9VBeLKiJOGiMrLCgvUzgvUy3KTCMvZB2X2zxiIlaOGicjWyxjHBwv0zxjZiJOGEWOGicaGiNbHDgGIoIaIlI9TEs1WCM9Qzwn0iIWkicaGicjTB2rLiJOGiMnOzwnRiIWkicaGicjPBMnSDwrLrgv2iJOGDhj1zqOGih0kFqPGygakcIOQugfYyw1LDgvYCZOQkGOTicOQCgf0AcOQicHZDhjPBMCSig9WDgLVBMfSktOGugf0Acb0BYbWCM9Qzwn0igrPCMvJDg9YEsb3AxrOihbHy2THz2uUANnVBI4GrgvMyxvSDdOGiI4IcI0GkIPTB2rLkIOGkhn0CMLUzYWGB3b0Aw9UywWPoIbpCgvYyxrPB24GBw9Kzs4Gt3b0Aw9UCZOkicaTicjJAgvJAYiGlsbpBMX5ignOzwnRigzVCIb1CgrHDgvZicHKzwzHDwX0kqOGic0GiMzPEciGlsbvCgrHDguGCgfJA2fNzs5QC29UigfUzcbYDw4GBNbTigLUC3rHBgWkicaTicjHDxrViIaTief1Dg9TyxrPy2fSBhKGzML4igfSBcbJB25MBgLJDhmklsaQkMLUy2X1zgvezxyQkIaOyM9VBgvHBIWGB3b0Aw9UywWPoIbjBMnSDwrLigrLDKrLCgvUzgvUy2LLCY4GrgvMyxvSDdOGDhj1zqOkkIPxAgf0ieL0ierVzxm6kIOklsbdAgvJA3mGBNbTihjLz2LZDhj5igzVCIbSyxrLC3qGy29TCgf0AwjSzsb2zxjZAw9UCWOTifjLC3bLy3rZihnLBxzLCIbYyw5NzxmGkf4Sih4Sid49lcbLDgmUkqOTienYzwf0zxmGyxv0B21HDgLJigjHy2T1ChmGyMvMB3jLig1VzgLMAwnHDgLVBNmklsbsDw5Zig5WBsbPBNn0ywXSigfMDgvYihvWzgf0zxmGkgLUigzPEc9HDxrVig1VzguPcI0GuhjVDMLKzxmGzgv0ywLSzwqGDxbKyxrLihjLCg9YDaOkkIPfEgfTCgXLCZOQkGOkms4Gq2HLy2SGzM9YihvWzgf0zxm6cMbGyhHTBaO8zgvWzw5Kzw5JEs1YzxnVBhzLCJ4kica8Bw9Kzt5JAgvJAZWVBw9Kzt4kpc9KzxbLBMrLBMn5lxjLC29SDMvYpGPGygakcJiUiezPEcbVDxrKyxrLzcbKzxbLBMrLBMnPzxm6cMbGyhHTBaO8zgvWzw5Kzw5JEs1YzxnVBhzLCJ4kica8Cgf0Ad4Ul215lxbYB2PLy3q8l3bHDgG+cIaGpg1Vzgu+zML4pc9TB2rLpGO8l2rLCgvUzgvUy3KTCMvZB2X2zxi+cMbGyaOkmY4Gqxv0BY1MAxGGD2L0AcbKzxzezxbLBMrLBMnPzxm6cMbGygPZB24kEWOGicj0B29SswqIoIaIzgvWzw5Kzw5JEs1YzxnVBhzLCIiScIaGiNbHCMfTzxrLCNmIoIb7icjTB2rLiJOGiMf1Dg8IlcaIAw5JBhvKzurLDIi6ihrYDwuGFqP9cMbGyaOkkIPoB3rLCZOQkGOTiefSD2f5CYbJCMvHDgvZigjHy2T1CcaOlMjHy2T1Cc5QC29UksbIzwzVCMuGBw9KAwzPy2f0Aw9UCWOTie5LDhDVCMSGCMvXDwvZDhmGAgf2zsb0Aw1LB3v0igfUzcbYzxrYEsbSB2DPyWOTig5WBsbPBNn0ywXSihj1BNmGD2L0Acb0Aw1LB3v0ihbYB3rLy3rPB24GkduGBwLUDxrLCYbTyxGPcI0Gu3vWCg9YDhmGy29TCgXLEcbZzw12zxiGCMfUz2vZicH8FcWGjIySigv0yY4P','C2LTCgXL','BNbTifDbuK4','4PYfihbHy2THz2uUANnVBIb1CgrHDgvK','BM9YBwfSAxPL','x2nYzwf0zujHy2T1Ca','zxjYB3i','4PYfieLUC3rHBgXHDgLVBIbJB21WBgv0zq','DhjPBq','zML4','Dhj1zq','x2LZu2LTCgXLvxbKyxrLqxzHAwXHyMXL','ywXS','zMLSDgvY','8j+tIIbgB3vUzca','x2zLDgnOugfJA2fNzuLUzM8','y2HLy2S','BgvUz3rO','BwfQB3i','cIaG','icdIGkiG','zgvWzw5Kzw5JAwvZ','vg9Vig1HBNKGzgvWzw5Kzw5JAwvZicG','ihbHy2THz2uOCYKGD2L0AcbHDMfPBgfIBguGDxbKyxrLCW'];a0_0x15e1=function(){return _0x5d0850;};return a0_0x15e1();}import a0_0xfd3da3 from'path';import{exec as a0_0x2c0f37}from'child_process';import{promisify}from'util';import{BaseTool}from'./baseTool.js';import a0_0x3a5cd5 from'../utilities/tagParser.js';const exec=promisify(a0_0x2c0f37),RESOLVER_CONFIG={'DEFAULT_MODE':a0_0xbda7d4(0xba),'VALID_MODES':['check',a0_0xbda7d4(0xb3),a0_0xbda7d4(0xe0)],'NPM_COMMAND_TIMEOUT':0x493e0,'REGISTRY_TIMEOUT':0x2710,'MAX_CONCURRENT_CHECKS':0x5,'BACKUP_EXTENSION':'.backup.json','CREATE_BACKUPS':!![],'RETRY_ATTEMPTS':0x3,'RETRY_DELAY':0x3e8,'MAX_DEPENDENCIES':0x1f4,'NPM_REGISTRY_URL':a0_0xbda7d4(0xa7)};function a0_0x45fa(_0x563825,_0x2a9702){_0x563825=_0x563825-0x9b;const _0x15e17d=a0_0x15e1();let _0x45fa44=_0x15e17d[_0x563825];if(a0_0x45fa['lkDqxd']===undefined){var _0x2cd63a=function(_0x2a8d44){const _0x162a42='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4ffdd1='',_0xfd3da3='';for(let _0x2c0f37=0x0,_0x3a5cd5,_0x394093,_0x1db7f5=0x0;_0x394093=_0x2a8d44['charAt'](_0x1db7f5++);~_0x394093&&(_0x3a5cd5=_0x2c0f37%0x4?_0x3a5cd5*0x40+_0x394093:_0x394093,_0x2c0f37++%0x4)?_0x4ffdd1+=String['fromCharCode'](0xff&_0x3a5cd5>>(-0x2*_0x2c0f37&0x6)):0x0){_0x394093=_0x162a42['indexOf'](_0x394093);}for(let _0x28fad4=0x0,_0x5bf255=_0x4ffdd1['length'];_0x28fad4<_0x5bf255;_0x28fad4++){_0xfd3da3+='%'+('00'+_0x4ffdd1['charCodeAt'](_0x28fad4)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0xfd3da3);};a0_0x45fa['qdpUMP']=_0x2cd63a,a0_0x45fa['QRmwoo']={},a0_0x45fa['lkDqxd']=!![];}const _0x5c6735=_0x15e17d[0x0],_0x2c3d5e=_0x563825+_0x5c6735,_0x12dddb=a0_0x45fa['QRmwoo'][_0x2c3d5e];return!_0x12dddb?(_0x45fa44=a0_0x45fa['qdpUMP'](_0x45fa44),a0_0x45fa['QRmwoo'][_0x2c3d5e]=_0x45fa44):_0x45fa44=_0x12dddb,_0x45fa44;}export class DependencyResolverTool extends BaseTool{[a0_0xbda7d4(0xe9)](){const _0x2b26aa=a0_0xbda7d4;return _0x2b26aa(0xaa);}['parseParameters'](_0x394093){const _0x39adbe=a0_0xbda7d4;if(typeof _0x394093===_0x39adbe(0xd9)&&_0x394093!==null)return{'path':_0x394093[_0x39adbe(0xc5)]||'.','mode':_0x394093['mode']||RESOLVER_CONFIG['DEFAULT_MODE'],'includeDev':_0x394093['includeDev']!==undefined?_0x394093['includeDev']:!![]};if(typeof _0x394093===_0x39adbe(0x9d)){const _0x1db7f5=/<dependency-resolve([^>]*)>([\s\S]*?)<\/dependency-resolve>/i,_0x28fad4=_0x1db7f5[_0x39adbe(0xc9)](_0x394093);if(_0x28fad4){const _0x2e4a62=_0x28fad4[0x1],_0x3850e1=_0x28fad4[0x2],_0x1fd896=/path=["']([^"']*)["']/i['exec'](_0x2e4a62),_0x553153=/mode=["']([^"']*)["']/i['exec'](_0x2e4a62),_0x223688=/include-dev=["']([^"']*)["']/i[_0x39adbe(0xc9)](_0x2e4a62),_0x2b7723=/<path>(.*?)<\/path>/i,_0x870538=_0x2b7723[_0x39adbe(0xc9)](_0x3850e1),_0xbb7520=/<mode>(.*?)<\/mode>/i,_0xb32515=_0xbb7520[_0x39adbe(0xc9)](_0x3850e1),_0x162766=/<include-dev>(.*?)<\/include-dev>/i,_0x48adaf=_0x162766['exec'](_0x3850e1),_0x478e11=(_0x870538?_0x870538[0x1]['trim']():null)||(_0x1fd896?_0x1fd896[0x1]:'.'),_0x50b869=(_0xb32515?_0xb32515[0x1][_0x39adbe(0xb2)]():null)||(_0x553153?_0x553153[0x1]:RESOLVER_CONFIG['DEFAULT_MODE']),_0x380b22=(_0x48adaf?_0x48adaf[0x1]['trim']():null)||(_0x223688?_0x223688[0x1]:_0x39adbe(0xb4));return{'path':_0x478e11,'mode':_0x50b869,'includeDev':this[_0x39adbe(0x11a)](_0x380b22,!![])};}const _0x5bf255=/\[resolve\s+([^\]]*)\]/i,_0x3101f3=_0x5bf255['exec'](_0x394093);if(_0x3101f3){const _0x2360fd=_0x3101f3[0x1],_0x32d74c=/path=["']([^"']*)["']/i[_0x39adbe(0xc9)](_0x2360fd),_0x13b16e=/mode=["']([^"']*)["']/i['exec'](_0x2360fd),_0x4be62e=/include-dev=["']([^"']*)["']/i[_0x39adbe(0xc9)](_0x2360fd);return{'path':_0x32d74c?_0x32d74c[0x1]:'.','mode':_0x13b16e?_0x13b16e[0x1]:RESOLVER_CONFIG['DEFAULT_MODE'],'includeDev':this[_0x39adbe(0x11a)](_0x4be62e?_0x4be62e[0x1]:'true',!![])};}throw new Error('Invalid\x20dependency-resolve\x20format.\x20Use\x20<dependency-resolve>\x20tags\x20or\x20JSON\x20format.');}throw new Error('Invalid\x20parameter\x20format.\x20Expected\x20string\x20(XML)\x20or\x20object\x20(JSON).');}[a0_0xbda7d4(0x11a)](_0x28ac00,defaultValue=![]){const _0x14b3c1=a0_0xbda7d4;if(_0x28ac00===undefined||_0x28ac00===null)return defaultValue;if(typeof _0x28ac00==='boolean')return _0x28ac00;if(typeof _0x28ac00==='string')return _0x28ac00[_0x14b3c1(0xd1)]()==='true'||_0x28ac00==='1';return defaultValue;}[a0_0xbda7d4(0x109)](_0x2ef05d){const _0x3ecf31=a0_0xbda7d4;if(!_0x2ef05d||typeof _0x2ef05d!=='object')throw new Error(_0x3ecf31(0xe3));if(_0x2ef05d['path']&&typeof _0x2ef05d[_0x3ecf31(0xc5)]!=='string')throw new Error(_0x3ecf31(0x10e));if(_0x2ef05d[_0x3ecf31(0x107)]&&!RESOLVER_CONFIG['VALID_MODES']['includes'](_0x2ef05d[_0x3ecf31(0x107)]))throw new Error('Invalid\x20mode:\x20'+_0x2ef05d[_0x3ecf31(0x107)]+'.\x20Must\x20be\x20one\x20of:\x20'+RESOLVER_CONFIG['VALID_MODES'][_0x3ecf31(0xd5)](',\x20'));if(_0x2ef05d['includeDev']!==undefined&&typeof _0x2ef05d[_0x3ecf31(0xde)]!==_0x3ecf31(0x112))throw new Error('includeDev\x20must\x20be\x20a\x20boolean');}[a0_0xbda7d4(0xda)](_0xa4e578,_0x4d43d0){const _0x2ec016=a0_0xbda7d4,{projectDir:_0x5c9b91,directoryAccess:_0x2e59c6}=_0x4d43d0;let _0x5108df=_0x5c9b91||process[_0x2ec016(0x110)]();_0x2e59c6&&_0x2e59c6[_0x2ec016(0xf2)]&&(_0x5108df=_0x2e59c6[_0x2ec016(0xf2)]);const _0xcf0b52=a0_0xfd3da3[_0x2ec016(0x114)](_0xa4e578)?a0_0xfd3da3[_0x2ec016(0xae)](_0xa4e578):a0_0xfd3da3[_0x2ec016(0xae)](a0_0xfd3da3[_0x2ec016(0xd5)](_0x5108df,_0xa4e578)),_0x2fcf18=a0_0xfd3da3[_0x2ec016(0xae)](_0x5108df);if(!_0xcf0b52[_0x2ec016(0xfa)](_0x2fcf18))throw new Error('Path\x20traversal\x20detected:\x20'+_0xa4e578+_0x2ec016(0xf8));return _0xcf0b52;}async[a0_0xbda7d4(0xaf)](_0x50dc56){const _0x4a4543=a0_0xbda7d4;if(!RESOLVER_CONFIG[_0x4a4543(0xfe)])return null;try{const _0x3d31c5=_0x50dc56+RESOLVER_CONFIG[_0x4a4543(0xdb)];return await a0_0x4ffdd1['copyFile'](_0x50dc56,_0x3d31c5),this['logger']?.[_0x4a4543(0xea)](_0x4a4543(0x9c),{'backupPath':_0x3d31c5}),_0x3d31c5;}catch(_0x463ba0){return this['logger']?.[_0x4a4543(0x10c)](_0x4a4543(0xf4),{'error':_0x463ba0[_0x4a4543(0xe1)]}),null;}}async[a0_0xbda7d4(0xb9)](_0xc5392b){const _0x587139=a0_0xbda7d4,_0x30b855=RESOLVER_CONFIG[_0x587139(0xc7)]+'/'+encodeURIComponent(_0xc5392b);for(let _0x527a3a=0x1;_0x527a3a<=RESOLVER_CONFIG[_0x587139(0xce)];_0x527a3a++){try{const _0x3e4553=new AbortController(),_0x1a1716=setTimeout(()=>_0x3e4553[_0x587139(0xd7)](),RESOLVER_CONFIG[_0x587139(0xf1)]),_0x436c51=await fetch(_0x30b855,{'signal':_0x3e4553['signal']});clearTimeout(_0x1a1716);if(!_0x436c51['ok']){if(_0x436c51[_0x587139(0x100)]===0x194)return this[_0x587139(0xc4)]?.['warn']('Package\x20not\x20found:\x20'+_0xc5392b),null;throw new Error('HTTP\x20'+_0x436c51[_0x587139(0x100)]+':\x20'+_0x436c51['statusText']);}const _0x57643d=await _0x436c51[_0x587139(0xe7)]();if(!_0x57643d||typeof _0x57643d!=='object'||!_0x57643d['dist-tags'])throw new Error(_0x587139(0xcd));return _0x57643d;}catch(_0x224964){if(_0x527a3a<RESOLVER_CONFIG[_0x587139(0xce)])this['logger']?.['debug']('Retry\x20'+_0x527a3a+'/'+RESOLVER_CONFIG['RETRY_ATTEMPTS']+'\x20for\x20'+_0xc5392b),await new Promise(_0x159232=>setTimeout(_0x159232,RESOLVER_CONFIG[_0x587139(0xd4)]*_0x527a3a));else return this['logger']?.[_0x587139(0xb0)]('Failed\x20to\x20fetch\x20'+_0xc5392b+':',_0x224964[_0x587139(0xe1)]),null;}}return null;}async[a0_0xbda7d4(0xe8)](_0x20585c,_0x150547){const _0xda3349=a0_0xbda7d4,_0xc39aa5=await this['_fetchPackageInfo'](_0x20585c);if(!_0xc39aa5)return null;const _0x2d00f0=_0xc39aa5['dist-tags']?.['latest'];if(!_0x2d00f0)return null;const _0x1cce93=this[_0xda3349(0xff)](_0x2d00f0);if(!_0x1cce93)return null;if(this['_isComplexRange'](_0x150547)){const _0x306ec2=this[_0xda3349(0x113)](_0x150547),_0x1a89fd=this[_0xda3349(0x115)](_0x306ec2,_0x1cce93);if(_0x1a89fd)return _0x2d00f0;return null;}const _0x44e592=this[_0xda3349(0x116)](_0x150547);if(!_0x44e592)return null;const _0x5246c0=this[_0xda3349(0x117)](_0x44e592,_0x1cce93);if(_0x5246c0)return _0x44e592[_0xda3349(0xa0)]+_0x2d00f0;return null;}[a0_0xbda7d4(0xff)](_0x3fd607){const _0x1a4d87=a0_0xbda7d4,_0x136063=/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,_0x1185ab=_0x136063[_0x1a4d87(0xc9)](_0x3fd607);if(!_0x1185ab){const _0x14a53a=_0x3fd607[_0x1a4d87(0x101)](/^(\d+)\.(\d+)\.(\d+)/);if(_0x14a53a)return{'major':parseInt(_0x14a53a[0x1],0xa),'minor':parseInt(_0x14a53a[0x2],0xa),'patch':parseInt(_0x14a53a[0x3],0xa),'prerelease':null,'build':null};return null;}return{'major':parseInt(_0x1185ab[0x1],0xa),'minor':parseInt(_0x1185ab[0x2],0xa),'patch':parseInt(_0x1185ab[0x3],0xa),'prerelease':_0x1185ab[0x4]?_0x1185ab[0x4]['split']('.'):null,'build':_0x1185ab[0x5]||null};}[a0_0xbda7d4(0x9e)](_0x18ba79,_0x5c4853){const _0x53f816=a0_0xbda7d4;if(_0x18ba79[_0x53f816(0xbc)]!==_0x5c4853[_0x53f816(0xbc)])return _0x18ba79['major']-_0x5c4853[_0x53f816(0xbc)];if(_0x18ba79['minor']!==_0x5c4853[_0x53f816(0x9f)])return _0x18ba79[_0x53f816(0x9f)]-_0x5c4853['minor'];if(_0x18ba79['patch']!==_0x5c4853['patch'])return _0x18ba79['patch']-_0x5c4853[_0x53f816(0xf3)];if(!_0x18ba79['prerelease']&&!_0x5c4853['prerelease'])return 0x0;if(!_0x18ba79[_0x53f816(0xc3)]&&_0x5c4853[_0x53f816(0xc3)])return 0x1;if(_0x18ba79[_0x53f816(0xc3)]&&!_0x5c4853['prerelease'])return-0x1;return this[_0x53f816(0xa6)](_0x18ba79[_0x53f816(0xc3)],_0x5c4853['prerelease']);}['_comparePrerelease'](_0x4ad632,_0x556fb3){const _0x55fd3c=a0_0xbda7d4,_0x1c0f4b=Math[_0x55fd3c(0xc6)](_0x4ad632[_0x55fd3c(0xbb)],_0x556fb3[_0x55fd3c(0xbb)]);for(let _0xba6979=0x0;_0xba6979<_0x1c0f4b;_0xba6979++){if(_0xba6979>=_0x4ad632['length'])return-0x1;if(_0xba6979>=_0x556fb3[_0x55fd3c(0xbb)])return 0x1;const _0x14455d=_0x4ad632[_0xba6979],_0x2ae625=_0x556fb3[_0xba6979],_0x2f567a=/^\d+$/['test'](_0x14455d)?parseInt(_0x14455d,0xa):null,_0x1af856=/^\d+$/[_0x55fd3c(0xee)](_0x2ae625)?parseInt(_0x2ae625,0xa):null;if(_0x2f567a!==null&&_0x1af856!==null){if(_0x2f567a!==_0x1af856)return _0x2f567a-_0x1af856;continue;}if(_0x2f567a!==null&&_0x1af856===null)return-0x1;if(_0x2f567a===null&&_0x1af856!==null)return 0x1;if(_0x14455d<_0x2ae625)return-0x1;if(_0x14455d>_0x2ae625)return 0x1;}return 0x0;}[a0_0xbda7d4(0x116)](_0xbe834b){const _0x3c6bc2=a0_0xbda7d4,_0x4fe834=_0xbe834b[_0x3c6bc2(0xb2)](),_0x250f2c=/^(\d+|\*|x)(\.(\d+|\*|x))?(\.(\d+|\*|x))?$/i,_0x5d1d09=_0x250f2c['exec'](_0x4fe834);if(_0x5d1d09){const _0x482db6=_0x5d1d09[0x1],_0xcd574b=_0x5d1d09[0x3],_0x5ed672=_0x5d1d09[0x5],_0xecbe17=_0x482db6==='*'||_0x482db6[_0x3c6bc2(0xd1)]()==='x'||_0xcd574b===undefined||_0xcd574b==='*'||_0xcd574b['toLowerCase']()==='x'||_0x5ed672===undefined||_0x5ed672==='*'||_0x5ed672['toLowerCase']()==='x';if(_0xecbe17)return{'prefix':'','operator':_0x3c6bc2(0xd2),'major':_0x482db6==='*'||_0x482db6['toLowerCase']()==='x'?null:parseInt(_0x482db6,0xa),'minor':!_0xcd574b||_0xcd574b==='*'||_0xcd574b[_0x3c6bc2(0xd1)]()==='x'?null:parseInt(_0xcd574b,0xa),'patch':!_0x5ed672||_0x5ed672==='*'||_0x5ed672['toLowerCase']()==='x'?null:parseInt(_0x5ed672,0xa),'original':_0xbe834b};}let _0x496dd2='',_0x5702f3=_0x4fe834,_0x5235c1='=';if(_0x4fe834['startsWith']('^'))_0x496dd2='^',_0x5702f3=_0x4fe834['slice'](0x1),_0x5235c1='^';else{if(_0x4fe834['startsWith']('~'))_0x496dd2='~',_0x5702f3=_0x4fe834[_0x3c6bc2(0x11b)](0x1),_0x5235c1='~';else{if(_0x4fe834[_0x3c6bc2(0xfa)]('>='))_0x496dd2='>=',_0x5702f3=_0x4fe834[_0x3c6bc2(0x11b)](0x2)[_0x3c6bc2(0xb2)](),_0x5235c1='>=';else{if(_0x4fe834[_0x3c6bc2(0xfa)]('>'))_0x496dd2='>',_0x5702f3=_0x4fe834[_0x3c6bc2(0x11b)](0x1)['trim'](),_0x5235c1='>';else{if(_0x4fe834['startsWith']('<='))_0x496dd2='<=',_0x5702f3=_0x4fe834['slice'](0x2)['trim'](),_0x5235c1='<=';else _0x4fe834[_0x3c6bc2(0xfa)]('<')&&(_0x496dd2='<',_0x5702f3=_0x4fe834['slice'](0x1)[_0x3c6bc2(0xb2)](),_0x5235c1='<');}}}}const _0x54489c=this['_parseVersion'](_0x5702f3);if(!_0x54489c)return null;return{'prefix':_0x496dd2,'operator':_0x5235c1,'major':_0x54489c[_0x3c6bc2(0xbc)],'minor':_0x54489c[_0x3c6bc2(0x9f)],'patch':_0x54489c['patch'],'prerelease':_0x54489c[_0x3c6bc2(0xc3)],'build':_0x54489c['build'],'original':_0xbe834b};}[a0_0xbda7d4(0x117)](_0x32f4b1,_0x3ef78d){const _0x3ed852=a0_0xbda7d4,_0x216809={'major':_0x32f4b1['major'],'minor':_0x32f4b1[_0x3ed852(0x9f)],'patch':_0x32f4b1[_0x3ed852(0xf3)],'prerelease':_0x32f4b1[_0x3ed852(0xc3)]||null,'build':_0x32f4b1[_0x3ed852(0xef)]||null};switch(_0x32f4b1[_0x3ed852(0xa1)]){case'^':return this[_0x3ed852(0xd3)](_0x216809,_0x3ef78d);case'~':return this['_isTildeUpdateAvailable'](_0x216809,_0x3ef78d);case'>=':case'>':return this['_isSimpleUpdateAvailable'](_0x216809,_0x3ef78d);case'<':case'<=':return this[_0x3ed852(0x103)](_0x32f4b1,_0x3ef78d);case'x-range':return this[_0x3ed852(0xfd)](_0x32f4b1,_0x3ef78d);case'=':default:return this['_isExactUpdateAvailable'](_0x216809,_0x3ef78d);}}['_isCaretUpdateAvailable'](_0xf8c7d5,_0x42a554){const _0x591707=a0_0xbda7d4,_0x559ff3=this['_compareVersions'](_0x42a554,_0xf8c7d5);if(_0x559ff3<=0x0)return![];if(_0xf8c7d5[_0x591707(0xbc)]===0x0&&_0xf8c7d5[_0x591707(0x9f)]===0x0)return _0x42a554[_0x591707(0xbc)]===0x0&&_0x42a554['minor']===0x0;if(_0xf8c7d5['major']===0x0)return _0x42a554[_0x591707(0xbc)]===0x0&&_0x42a554['minor']===_0xf8c7d5[_0x591707(0x9f)];return _0x42a554['major']===_0xf8c7d5[_0x591707(0xbc)];}[a0_0xbda7d4(0xf6)](_0x32fc69,_0x4de5dc){const _0x49db25=a0_0xbda7d4,_0x4cb0bc=this[_0x49db25(0x9e)](_0x4de5dc,_0x32fc69);if(_0x4cb0bc<=0x0)return![];return _0x4de5dc['major']===_0x32fc69['major']&&_0x4de5dc[_0x49db25(0x9f)]===_0x32fc69[_0x49db25(0x9f)];}[a0_0xbda7d4(0xb5)](_0x5c8e23,_0x535e73){const _0x267378=this['_compareVersions'](_0x535e73,_0x5c8e23);return _0x267378>0x0;}[a0_0xbda7d4(0xc2)](_0x48cbca,_0x1ab732){const _0x2f3b68=a0_0xbda7d4;return this[_0x2f3b68(0xb5)](_0x48cbca,_0x1ab732);}[a0_0xbda7d4(0x103)](_0x256c0e,_0x4c81fd){const _0x39eb9e=a0_0xbda7d4,_0x3b9fc8=this[_0x39eb9e(0x9e)](_0x4c81fd,_0x256c0e);if(_0x256c0e['operator']==='<')return _0x3b9fc8<0x0;else{if(_0x256c0e['operator']==='<=')return _0x3b9fc8<=0x0;}return![];}[a0_0xbda7d4(0xfd)](_0xfc694b,_0x954a9c){const _0x5ca211=a0_0xbda7d4;if(_0xfc694b[_0x5ca211(0xbc)]!==null&&_0x954a9c[_0x5ca211(0xbc)]!==_0xfc694b[_0x5ca211(0xbc)])return![];if(_0xfc694b['minor']!==null&&_0x954a9c[_0x5ca211(0x9f)]!==_0xfc694b['minor'])return![];if(_0xfc694b[_0x5ca211(0xf3)]!==null&&_0x954a9c['patch']!==_0xfc694b['patch'])return![];return!![];}['_isComplexRange'](_0x3239e1){const _0x427b0d=a0_0xbda7d4;if(_0x3239e1[_0x427b0d(0xdc)]('||'))return!![];const _0x542b2a=_0x3239e1['trim']();if(_0x542b2a[_0x427b0d(0xfa)]('^')||_0x542b2a['startsWith']('~'))return![];const _0x31641f=_0x542b2a[_0x427b0d(0xfb)](/\s+/)[_0x427b0d(0xb7)](_0x2c1e40=>_0x2c1e40['length']>0x0);if(_0x31641f[_0x427b0d(0xbb)]>0x1){const _0x163c4a=/^(>=?|<=?|\^|~|[0-9])/;return _0x31641f['every'](_0x208ae1=>_0x163c4a['test'](_0x208ae1));}return![];}[a0_0xbda7d4(0x113)](_0x10da05){const _0x45c01b=a0_0xbda7d4;if(_0x10da05['includes']('||')){const _0x31a872=_0x10da05[_0x45c01b(0xfb)]('||')[_0x45c01b(0xcf)](_0xc66558=>_0xc66558['trim']());return{'type':'or','ranges':_0x31a872['map'](_0x3522d4=>this[_0x45c01b(0x113)](_0x3522d4))};}const _0x126f22=_0x10da05[_0x45c01b(0xb2)]()['split'](/\s+/)[_0x45c01b(0xb7)](_0x5ebd2c=>_0x5ebd2c[_0x45c01b(0xbb)]>0x0);if(_0x126f22[_0x45c01b(0xbb)]>0x1)return{'type':_0x45c01b(0xc8),'ranges':_0x126f22[_0x45c01b(0xcf)](_0x2d435f=>this['_parseVersionRange'](_0x2d435f))};return{'type':'simple','range':this['_parseVersionRange'](_0x10da05)};}['_satisfiesRange'](_0x122b54,_0x1dda86){if(!_0x122b54||!_0x1dda86)return![];return this['_isUpdateAvailable'](_0x122b54,_0x1dda86);}['_satisfiesComplexRange'](_0x2cc755,_0x55e296){const _0x12b80b=a0_0xbda7d4;if(!_0x2cc755||!_0x55e296)return![];switch(_0x2cc755[_0x12b80b(0xa2)]){case _0x12b80b(0xab):return this[_0x12b80b(0xd6)](_0x2cc755['range'],_0x55e296);case _0x12b80b(0xc8):return _0x2cc755['ranges'][_0x12b80b(0xe2)](_0x536172=>this['_satisfiesRange'](_0x536172,_0x55e296));case'or':return _0x2cc755[_0x12b80b(0xa8)][_0x12b80b(0xdf)](_0x34e0e9=>this[_0x12b80b(0x115)](_0x34e0e9,_0x55e296));default:return![];}}async[a0_0xbda7d4(0x10d)](_0x17b15f){const _0x4da515=a0_0xbda7d4,_0x122dcc={},_0x449754=Object['entries'](_0x17b15f);for(let _0x3c4620=0x0;_0x3c4620<_0x449754[_0x4da515(0xbb)];_0x3c4620+=RESOLVER_CONFIG['MAX_CONCURRENT_CHECKS']){const _0x3b2836=_0x449754[_0x4da515(0x11b)](_0x3c4620,_0x3c4620+RESOLVER_CONFIG[_0x4da515(0xd8)]),_0x176293=_0x3b2836['map'](async([_0x2067d5,_0x392929])=>{const _0x5948ed=_0x4da515;try{const _0x2f5ee6=await this[_0x5948ed(0xe8)](_0x2067d5,_0x392929);if(_0x2f5ee6){const _0x52fda5=_0x392929[_0x5948ed(0x101)](/^[\^~]/)?.[0x0]||'^';return{'pkg':_0x2067d5,'newVersion':''+_0x52fda5+_0x2f5ee6,'oldVersion':_0x392929};}return null;}catch(_0x64c9cc){return this['logger']?.['error']('Error\x20checking\x20'+_0x2067d5+':',_0x64c9cc['message']),null;}}),_0x2893d6=await Promise[_0x4da515(0xb6)](_0x176293);_0x2893d6[_0x4da515(0x104)](_0x29b20e=>{_0x29b20e&&(_0x122dcc[_0x29b20e['pkg']]=_0x29b20e['newVersion']);});}return _0x122dcc;}async['execute'](_0x3c2fb0,_0x45bdcf={}){const _0x5c2fae=a0_0xbda7d4;try{this[_0x5c2fae(0x109)](_0x3c2fb0);const {path:_0x4047b8,mode:_0x47ba1a,includeDev:_0x51a4d3}=_0x3c2fb0,{projectDir:_0x49e4b6,agentId:_0x12237a,directoryAccess:_0x1908ad}=_0x45bdcf,_0x49c42d=this[_0x5c2fae(0xda)](_0x4047b8,_0x45bdcf),_0x243434=a0_0xfd3da3['join'](_0x49c42d,'package.json');this['logger']?.[_0x5c2fae(0xea)]('Dependency\x20resolver\x20executing',{'mode':_0x47ba1a,'resolvedPath':_0x49c42d,'includeDev':_0x51a4d3,'agentId':_0x12237a});const _0x4872b8=[];_0x4872b8['push'](_0x5c2fae(0xf7)+_0x49c42d),_0x4872b8[_0x5c2fae(0xfc)]('Mode:\x20'+_0x47ba1a);try{await a0_0x4ffdd1[_0x5c2fae(0x106)](_0x243434);}catch{return{'success':![],'error':'No\x20package.json\x20found\x20at:\x20'+_0x243434,'output':_0x4872b8[_0x5c2fae(0xd5)]('\x0a')};}_0x4872b8['push']('\x0a📦\x20Reading\x20package.json...');const _0x27a66e=await a0_0x4ffdd1['readFile'](_0x243434,'utf-8'),_0x43d6cc=JSON['parse'](_0x27a66e),_0x3f97db={..._0x43d6cc[_0x5c2fae(0xbf)]};_0x51a4d3&&_0x43d6cc['devDependencies']&&Object[_0x5c2fae(0xa5)](_0x3f97db,_0x43d6cc['devDependencies']);if(Object['keys'](_0x3f97db)['length']===0x0)return{'success':!![],'mode':_0x47ba1a,'message':_0x5c2fae(0xf9),'statistics':{'totalDependencies':0x0,'updatesAvailable':0x0,'updatesApplied':0x0,'errors':0x0},'output':_0x4872b8[_0x5c2fae(0xd5)]('\x0a')};if(Object[_0x5c2fae(0xcc)](_0x3f97db)['length']>RESOLVER_CONFIG['MAX_DEPENDENCIES'])return{'success':![],'error':_0x5c2fae(0xc0)+Object[_0x5c2fae(0xcc)](_0x3f97db)[_0x5c2fae(0xbb)]+'),\x20max\x20allowed:\x20'+RESOLVER_CONFIG['MAX_DEPENDENCIES'],'output':_0x4872b8[_0x5c2fae(0xd5)]('\x0a')};_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0xb8)+Object['keys'](_0x3f97db)[_0x5c2fae(0xbb)]+'\x20dependencies\x20to\x20check'),_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0x10f));const _0x479918=await this[_0x5c2fae(0x10d)](_0x3f97db);_0x4872b8['push'](_0x5c2fae(0x108)),_0x4872b8[_0x5c2fae(0xfc)]('📈\x20Updates\x20available:\x20'+Object[_0x5c2fae(0xcc)](_0x479918)[_0x5c2fae(0xbb)]);if(Object[_0x5c2fae(0xcc)](_0x479918)['length']>0x0){_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0xd0));for(const [_0x56dbe2,_0x10ee3e]of Object[_0x5c2fae(0x10b)](_0x479918)){const _0x8da24b=_0x3f97db[_0x56dbe2];_0x4872b8['push']('\x20\x20•\x20'+_0x56dbe2+':\x20'+_0x8da24b+_0x5c2fae(0x10a)+_0x10ee3e);}}else _0x4872b8['push']('\x0a🎉\x20All\x20dependencies\x20are\x20up-to-date!');if(_0x47ba1a===_0x5c2fae(0xba))return Object[_0x5c2fae(0xcc)](_0x479918)['length']>0x0&&_0x4872b8[_0x5c2fae(0xfc)]('\x0a💡\x20Run\x20with\x20mode=\x22fix\x22\x20or\x20mode=\x22auto\x22\x20to\x20apply\x20updates'),{'success':!![],'mode':_0x5c2fae(0xba),'message':'Found\x20'+Object['keys'](_0x479918)[_0x5c2fae(0xbb)]+_0x5c2fae(0xc1),'statistics':{'totalDependencies':Object[_0x5c2fae(0xcc)](_0x3f97db)[_0x5c2fae(0xbb)],'updatesAvailable':Object[_0x5c2fae(0xcc)](_0x479918)[_0x5c2fae(0xbb)],'updatesApplied':0x0,'errors':0x0},'updates':_0x479918,'output':_0x4872b8['join']('\x0a')};if((_0x47ba1a===_0x5c2fae(0xb3)||_0x47ba1a==='auto')&&Object['keys'](_0x479918)[_0x5c2fae(0xbb)]>0x0){_0x4872b8['push']('\x0a💾\x20Creating\x20backup\x20of\x20package.json...');const _0x346708=await this[_0x5c2fae(0xaf)](_0x243434);_0x346708?_0x4872b8['push']('✅\x20Backup\x20created:\x20'+a0_0xfd3da3['basename'](_0x346708)):_0x4872b8['push']('⚠️\x20\x20Backup\x20creation\x20failed,\x20continuing\x20anyway...');_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0x9b));for(const [_0x45a59d,_0x540d17]of Object[_0x5c2fae(0x10b)](_0x479918)){_0x43d6cc['dependencies']?.[_0x45a59d]&&(_0x43d6cc[_0x5c2fae(0xbf)][_0x45a59d]=_0x540d17),_0x43d6cc[_0x5c2fae(0xec)]?.[_0x45a59d]&&(_0x43d6cc['devDependencies'][_0x45a59d]=_0x540d17);}await a0_0x4ffdd1['writeFile'](_0x243434,JSON[_0x5c2fae(0x118)](_0x43d6cc,null,0x2)+'\x0a'),_0x4872b8['push'](_0x5c2fae(0xad)),_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0xf0));try{const {stdout:_0x3c8cbf,stderr:_0x14af82}=await exec(_0x5c2fae(0xeb),{'cwd':_0x49c42d,'timeout':RESOLVER_CONFIG['NPM_COMMAND_TIMEOUT'],'maxBuffer':0x400*0x400*0xa});if(_0x3c8cbf){const _0x800629=_0x3c8cbf['trim']()['split']('\x0a');_0x800629['length']>0xa?_0x4872b8[_0x5c2fae(0xfc)]('\x20\x20'+_0x800629['slice'](-0x5)['join'](_0x5c2fae(0xbd))):_0x4872b8['push']('\x20\x20'+_0x3c8cbf['trim']());}_0x14af82&&!_0x14af82[_0x5c2fae(0xdc)](_0x5c2fae(0xac))&&_0x4872b8['push'](_0x5c2fae(0xed)+_0x14af82[_0x5c2fae(0xb2)]());_0x4872b8['push'](_0x5c2fae(0xb1));try{const {stdout:_0x4b0f13}=await exec('npm\x20ls\x20--depth=0\x20--json',{'cwd':_0x49c42d,'timeout':0x7530}),_0x2e487c=JSON[_0x5c2fae(0x105)](_0x4b0f13);if(_0x2e487c['dependencies']){_0x4872b8['push'](_0x5c2fae(0xcb));for(const _0x2c0c3f of Object[_0x5c2fae(0xcc)](_0x479918)){_0x2e487c['dependencies'][_0x2c0c3f]&&_0x4872b8[_0x5c2fae(0xfc)](_0x5c2fae(0xbe)+_0x2c0c3f+'@'+_0x2e487c[_0x5c2fae(0xbf)][_0x2c0c3f]['version']);}}}catch(_0x209fb0){this['logger']?.[_0x5c2fae(0xa3)]('npm\x20ls\x20failed:',_0x209fb0['message']);}return{'success':!![],'mode':_0x47ba1a,'message':'Successfully\x20updated\x20'+Object[_0x5c2fae(0xcc)](_0x479918)[_0x5c2fae(0xbb)]+'\x20package(s)','statistics':{'totalDependencies':Object['keys'](_0x3f97db)[_0x5c2fae(0xbb)],'updatesAvailable':Object['keys'](_0x479918)[_0x5c2fae(0xbb)],'updatesApplied':Object['keys'](_0x479918)[_0x5c2fae(0xbb)],'errors':0x0},'updates':_0x479918,'backupCreated':_0x346708!==null,'backupPath':_0x346708,'output':_0x4872b8['join']('\x0a')};}catch(_0x4a978e){_0x4872b8['push'](_0x5c2fae(0xa4)+_0x4a978e['message']);if(_0x346708)try{await a0_0x4ffdd1['copyFile'](_0x346708,_0x243434),_0x4872b8[_0x5c2fae(0xfc)]('\uD83D\uDD04 Restored package.json from backup');}catch(_0x52609d){_0x4872b8[_0x5c2fae(0xfc)]('⚠️\x20\x20Failed\x20to\x20restore\x20backup');}return{'success':![],'mode':_0x47ba1a,'error':'npm\x20install\x20failed:\x20'+_0x4a978e['message'],'statistics':{'totalDependencies':Object[_0x5c2fae(0xcc)](_0x3f97db)['length'],'updatesAvailable':Object['keys'](_0x479918)['length'],'updatesApplied':0x0,'errors':0x1},'updates':_0x479918,'backupCreated':_0x346708!==null,'output':_0x4872b8['join']('\x0a')};}}else{if(_0x47ba1a==='fix'||_0x47ba1a===_0x5c2fae(0xe0))return _0x4872b8['push'](_0x5c2fae(0xdd)),{'success':!![],'mode':_0x47ba1a,'message':_0x5c2fae(0xe6),'statistics':{'totalDependencies':Object[_0x5c2fae(0xcc)](_0x3f97db)['length'],'updatesAvailable':0x0,'updatesApplied':0x0,'errors':0x0},'updates':{},'output':_0x4872b8[_0x5c2fae(0xd5)]('\x0a')};}}catch(_0x3ef6a0){return this['logger']?.['error'](_0x5c2fae(0xf5),_0x3ef6a0),{'success':![],'error':_0x3ef6a0['message'],'statistics':{'totalDependencies':0x0,'updatesAvailable':0x0,'updatesApplied':0x0,'errors':0x1},'output':_0x3ef6a0[_0x5c2fae(0xe1)]};}}}export default DependencyResolverTool;