vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850

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 (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Agent Discovery - Validator
3
+ *
4
+ * Validates and deduplicates discovered agents.
5
+ */
6
+
7
+ /**
8
+ * Validate and deduplicate discovered agents
9
+ * @param {Array} agents - Discovered agents
10
+ * @param {Object} logger - Logger instance
11
+ * @returns {Promise<Array>} - Valid, deduplicated agents
12
+ */
13
+ async function validateAndDeduplicateAgents(agents, logger = null) {
14
+ const validAgents = [];
15
+ const seenIds = new Set();
16
+ const seenPaths = new Set();
17
+
18
+ for (const agent of agents) {
19
+ // Validate required fields
20
+ if (!validateRequiredFields(agent, logger)) {
21
+ continue;
22
+ }
23
+
24
+ // Check for duplicates
25
+ if (seenIds.has(agent.id)) {
26
+ if (logger) {
27
+ await logger.warn('Duplicate agent ID found: ' + agent.id);
28
+ }
29
+ continue;
30
+ }
31
+
32
+ if (seenPaths.has(agent.path)) {
33
+ if (logger) {
34
+ await logger.warn('Duplicate agent path found: ' + agent.path);
35
+ }
36
+ continue;
37
+ }
38
+
39
+ // Additional validation
40
+ await validateAgentDetails(agent, logger);
41
+
42
+ validAgents.push(agent);
43
+ seenIds.add(agent.id);
44
+ seenPaths.add(agent.path);
45
+ }
46
+
47
+ return validAgents;
48
+ }
49
+
50
+ /**
51
+ * Validate required agent fields
52
+ * @param {Object} agent - Agent object
53
+ * @param {Object} logger - Logger instance
54
+ * @returns {boolean} - True if valid
55
+ */
56
+ function validateRequiredFields(agent, logger) {
57
+ const requiredFields = ['id', 'name', 'path'];
58
+
59
+ for (const field of requiredFields) {
60
+ if (!agent[field]) {
61
+ if (logger) {
62
+ logger.warn('Invalid agent configuration: missing required field', {
63
+ field,
64
+ agent: agent.id || 'unknown'
65
+ });
66
+ }
67
+ return false;
68
+ }
69
+ }
70
+
71
+ return true;
72
+ }
73
+
74
+ /**
75
+ * Validate agent details
76
+ * @param {Object} agent - Agent object
77
+ * @param {Object} logger - Logger instance
78
+ */
79
+ async function validateAgentDetails(agent, logger) {
80
+ // Check version
81
+ if (agent.version === 'unknown') {
82
+ if (logger) {
83
+ logger.warn(`Agent ${agent.id} has unknown version`);
84
+ }
85
+ }
86
+
87
+ // Validate path exists
88
+ try {
89
+ const fs = require('fs').promises;
90
+ await fs.access(agent.path);
91
+ } catch (error) {
92
+ if (logger) {
93
+ logger.warn(`Agent ${agent.id} path not accessible: ${agent.path}`);
94
+ }
95
+ }
96
+
97
+ // Validate capabilities
98
+ if (!Array.isArray(agent.capabilities)) {
99
+ agent.capabilities = [];
100
+ if (logger) {
101
+ logger.warn(`Agent ${agent.id} has invalid capabilities, reset to empty array`);
102
+ }
103
+ }
104
+
105
+ // Validate type
106
+ const validTypes = ['ai-agent', 'cli-tool', 'automation-bot', 'unknown'];
107
+ if (!validTypes.includes(agent.type)) {
108
+ agent.type = 'unknown';
109
+ if (logger) {
110
+ logger.warn(`Agent ${agent.id} has invalid type, set to unknown`);
111
+ }
112
+ }
113
+ }
114
+
115
+ /**
116
+ * Validate single agent configuration
117
+ * @param {Object} agent - Agent to validate
118
+ * @returns {Object} - Validation result
119
+ */
120
+ function validateAgent(agent) {
121
+ const errors = [];
122
+ const warnings = [];
123
+
124
+ // Required fields
125
+ if (!agent.id) errors.push('Missing agent ID');
126
+ if (!agent.name) errors.push('Missing agent name');
127
+ if (!agent.path) errors.push('Missing agent path');
128
+
129
+ // Format validation
130
+ if (agent.id && !/^[a-z0-9-]+$/.test(agent.id)) {
131
+ errors.push('Agent ID must contain only lowercase letters, numbers, and hyphens');
132
+ }
133
+
134
+ if (agent.name && agent.name.length > 100) {
135
+ warnings.push('Agent name is very long (>100 characters)');
136
+ }
137
+
138
+ if (agent.description && agent.description.length > 500) {
139
+ warnings.push('Agent description is very long (>500 characters)');
140
+ }
141
+
142
+ // Type validation
143
+ const validTypes = ['ai-agent', 'cli-tool', 'automation-bot', 'unknown'];
144
+ if (agent.type && !validTypes.includes(agent.type)) {
145
+ errors.push(`Invalid agent type: ${agent.type}. Must be one of: ${validTypes.join(', ')}`);
146
+ }
147
+
148
+ // Version validation
149
+ if (agent.version && !/^\d+\.\d+(\.\d+)?(-.*)?$/.test(agent.version)) {
150
+ warnings.push(`Version format may be invalid: ${agent.version}`);
151
+ }
152
+
153
+ // Capability validation
154
+ if (agent.capabilities) {
155
+ if (!Array.isArray(agent.capabilities)) {
156
+ errors.push('Capabilities must be an array');
157
+ } else {
158
+ const validCapabilities = [
159
+ 'chat', 'code-generation', 'file-processing', 'web-interaction',
160
+ 'cli-interface', 'help', 'automation', 'analysis', 'monitoring'
161
+ ];
162
+
163
+ for (const cap of agent.capabilities) {
164
+ if (!validCapabilities.includes(cap)) {
165
+ warnings.push(`Unknown capability: ${cap}`);
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ return {
172
+ valid: errors.length === 0,
173
+ errors,
174
+ warnings
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Filter agents by criteria
180
+ * @param {Array} agents - Agents to filter
181
+ * @param {Object} criteria - Filter criteria
182
+ * @returns {Array} - Filtered agents
183
+ */
184
+ function filterAgents(agents, criteria) {
185
+ return agents.filter(agent => {
186
+ // Type filter
187
+ if (criteria.type && agent.type !== criteria.type) {
188
+ return false;
189
+ }
190
+
191
+ // Capability filter
192
+ if (criteria.capability && (!agent.capabilities || !agent.capabilities.includes(criteria.capability))) {
193
+ return false;
194
+ }
195
+
196
+ // Name filter
197
+ if (criteria.name && !agent.name.toLowerCase().includes(criteria.name.toLowerCase())) {
198
+ return false;
199
+ }
200
+
201
+ // Version filter
202
+ if (criteria.version && !agent.version.includes(criteria.version)) {
203
+ return false;
204
+ }
205
+
206
+ // Path filter
207
+ if (criteria.path && !agent.path.includes(criteria.path)) {
208
+ return false;
209
+ }
210
+
211
+ return true;
212
+ });
213
+ }
214
+
215
+ /**
216
+ * Sort agents by criteria
217
+ * @param {Array} agents - Agents to sort
218
+ * @param {string} sortBy - Sort field
219
+ * @param {string} order - Sort order ('asc' or 'desc')
220
+ * @returns {Array} - Sorted agents
221
+ */
222
+ function sortAgents(agents, sortBy = 'name', order = 'asc') {
223
+ return [...agents].sort((a, b) => {
224
+ let aValue = a[sortBy];
225
+ let bValue = b[sortBy];
226
+
227
+ // Handle missing values
228
+ if (aValue === undefined) aValue = '';
229
+ if (bValue === undefined) bValue = '';
230
+
231
+ // String comparison
232
+ if (typeof aValue === 'string' && typeof bValue === 'string') {
233
+ const comparison = aValue.toLowerCase().localeCompare(bValue.toLowerCase());
234
+ return order === 'desc' ? -comparison : comparison;
235
+ }
236
+
237
+ // Number comparison
238
+ if (typeof aValue === 'number' && typeof bValue === 'number') {
239
+ const comparison = aValue - bValue;
240
+ return order === 'desc' ? -comparison : comparison;
241
+ }
242
+
243
+ // Date comparison
244
+ if (aValue instanceof Date && bValue instanceof Date) {
245
+ const comparison = aValue.getTime() - bValue.getTime();
246
+ return order === 'desc' ? -comparison : comparison;
247
+ }
248
+
249
+ // Default comparison
250
+ const comparison = String(aValue).localeCompare(String(bValue));
251
+ return order === 'desc' ? -comparison : comparison;
252
+ });
253
+ }
254
+
255
+ module.exports = {
256
+ validateAndDeduplicateAgents,
257
+ validateAgent,
258
+ validateRequiredFields,
259
+ validateAgentDetails,
260
+ filterAgents,
261
+ sortAgents
262
+ };
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Discovery Results
3
+ *
4
+ * Classes and utilities for managing discovery results.
5
+ */
6
+
7
+ /**
8
+ * Discovered agent information
9
+ */
10
+ class DiscoveredAgent {
11
+ constructor(fileInfo, commandHelp = '') {
12
+ this.name = fileInfo.name;
13
+ this.path = fileInfo.path;
14
+ this.type = fileInfo.type;
15
+ this.help = commandHelp;
16
+ this.confidence = 0;
17
+ this.metadata = {
18
+ discoveredAt: new Date().toISOString(),
19
+ source: 'filesystem_scan',
20
+ verified: false
21
+ };
22
+ }
23
+
24
+ /**
25
+ * Set confidence level
26
+ * @param {number} confidence - Confidence score (0-1)
27
+ */
28
+ setConfidence(confidence) {
29
+ this.confidence = Math.max(0, Math.min(1, confidence));
30
+ this.metadata.confidenceCalculatedAt = new Date().toISOString();
31
+ }
32
+
33
+ /**
34
+ * Mark as verified
35
+ * @param {boolean} verified - Verification status
36
+ */
37
+ setVerified(verified = true) {
38
+ this.metadata.verified = verified;
39
+ this.metadata.verifiedAt = new Date().toISOString();
40
+ }
41
+
42
+ /**
43
+ * Add additional metadata
44
+ * @param {string} key - Metadata key
45
+ * @param {*} value - Metadata value
46
+ */
47
+ addMetadata(key, value) {
48
+ this.metadata[key] = value;
49
+ }
50
+
51
+ /**
52
+ * Convert to JSON
53
+ * @returns {Object} - JSON representation
54
+ */
55
+ toJSON() {
56
+ return {
57
+ name: this.name,
58
+ path: this.path,
59
+ type: this.type,
60
+ help: this.help,
61
+ confidence: this.confidence,
62
+ metadata: this.metadata
63
+ };
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Discovery session result
69
+ */
70
+ class DiscoveryResult {
71
+ constructor(sessionId = null) {
72
+ this.sessionId = sessionId || this.generateSessionId();
73
+ this.agents = [];
74
+ this.warnings = [];
75
+ this.errors = [];
76
+ this.metadata = {
77
+ startedAt: new Date().toISOString(),
78
+ completedAt: null,
79
+ duration: 0,
80
+ pathsScanned: [],
81
+ totalFiles: 0,
82
+ agentCandidates: 0
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Generate unique session ID
88
+ * @returns {string} - Session ID
89
+ */
90
+ generateSessionId() {
91
+ return `discovery_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
92
+ }
93
+
94
+ /**
95
+ * Add discovered agent
96
+ * @param {DiscoveredAgent} agent - Discovered agent
97
+ */
98
+ addAgent(agent) {
99
+ if (agent instanceof DiscoveredAgent) {
100
+ this.agents.push(agent);
101
+ this.metadata.agentCandidates++;
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Add warning
107
+ * @param {string} warning - Warning message
108
+ * @param {Object} context - Warning context
109
+ */
110
+ addWarning(warning, context = {}) {
111
+ this.warnings.push({
112
+ message: warning,
113
+ context,
114
+ timestamp: new Date().toISOString()
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Add error
120
+ * @param {Error|string} error - Error object or message
121
+ * @param {Object} context - Error context
122
+ */
123
+ addError(error, context = {}) {
124
+ this.errors.push({
125
+ message: error.message || error,
126
+ stack: error.stack,
127
+ context,
128
+ timestamp: new Date().toISOString()
129
+ });
130
+ }
131
+
132
+ /**
133
+ * Mark discovery as complete
134
+ */
135
+ complete() {
136
+ this.metadata.completedAt = new Date().toISOString();
137
+ this.metadata.duration = new Date(this.metadata.completedAt) - new Date(this.metadata.startedAt);
138
+ }
139
+
140
+ /**
141
+ * Get summary statistics
142
+ * @returns {Object} - Summary statistics
143
+ */
144
+ getSummary() {
145
+ return {
146
+ sessionId: this.sessionId,
147
+ totalAgents: this.agents.length,
148
+ verifiedAgents: this.agents.filter(a => a.metadata.verified).length,
149
+ highConfidenceAgents: this.agents.filter(a => a.confidence > 0.7).length,
150
+ warnings: this.warnings.length,
151
+ errors: this.errors.length,
152
+ duration: this.metadata.duration,
153
+ success: this.errors.length === 0
154
+ };
155
+ }
156
+
157
+ /**
158
+ * Convert to JSON
159
+ * @returns {Object} - JSON representation
160
+ */
161
+ toJSON() {
162
+ return {
163
+ sessionId: this.sessionId,
164
+ agents: this.agents.map(a => a.toJSON()),
165
+ warnings: this.warnings,
166
+ errors: this.errors,
167
+ metadata: this.metadata,
168
+ summary: this.getSummary()
169
+ };
170
+ }
171
+ }
172
+
173
+ module.exports = {
174
+ DiscoveredAgent,
175
+ DiscoveryResult
176
+ };
@@ -0,0 +1,268 @@
1
+ /**
2
+ * Discovery Scanner
3
+ *
4
+ * Core scanning logic for agent discovery.
5
+ */
6
+
7
+ const {
8
+ commandExists,
9
+ getCommandHelp,
10
+ scanDirectory,
11
+ isAgentTool,
12
+ getFileMetadata
13
+ } = require('./discovery-utils');
14
+
15
+ const { DiscoveredAgent, DiscoveryResult } = require('./discovery-results');
16
+ const { promisify } = require('util');
17
+ const { exec } = require('child_process');
18
+
19
+ const execAsync = promisify(exec);
20
+
21
+ /**
22
+ * Discovery Scanner class
23
+ */
24
+ class DiscoveryScanner {
25
+ constructor(options = {}) {
26
+ this.discoveryPaths = options.discoveryPaths || [
27
+ '/usr/local/bin',
28
+ '/opt/bin',
29
+ '/usr/bin/local/bin',
30
+ '/snap/bin'
31
+ ];
32
+ this.timeout = options.timeout || 30000;
33
+ this.maxConcurrency = options.maxConcurrency || 3;
34
+ this.logger = options.logger || null;
35
+ }
36
+
37
+ /**
38
+ * Scan all configured paths
39
+ * @param {string} sessionId - Discovery session ID
40
+ * @returns {Promise<DiscoveryResult>} - Discovery results
41
+ */
42
+ async scanAllPaths(sessionId = null) {
43
+ const result = new DiscoveryResult(sessionId);
44
+
45
+ try {
46
+ if (this.logger) {
47
+ await this.logger.info('Starting discovery scan', {
48
+ paths: this.discoveryPaths,
49
+ timeout: this.timeout
50
+ });
51
+ }
52
+
53
+ result.metadata.pathsScanned = [...this.discoveryPaths];
54
+
55
+ // Scan all directories concurrently with limit
56
+ const scanPromises = this.discoveryPaths.map(path =>
57
+ this.scanPath(path, result)
58
+ );
59
+
60
+ await Promise.allSettled(scanPromises);
61
+
62
+ // Analyze and rank discovered agents
63
+ await this.analyzeDiscoveredAgents(result);
64
+
65
+ result.complete();
66
+
67
+ if (this.logger) {
68
+ await this.logger.info('Discovery scan completed', result.getSummary());
69
+ }
70
+
71
+ } catch (error) {
72
+ result.addError(error, { phase: 'scanning' });
73
+ result.complete();
74
+ }
75
+
76
+ return result;
77
+ }
78
+
79
+ /**
80
+ * Scan a single path
81
+ * @param {string} scanPath - Path to scan
82
+ * @param {DiscoveryResult} result - Discovery result object
83
+ * @returns {Promise<void>}
84
+ */
85
+ async scanPath(scanPath, result) {
86
+ try {
87
+ const files = await scanDirectory(scanPath);
88
+ result.metadata.totalFiles += files.length;
89
+
90
+ // Process files with concurrency limit
91
+ const chunks = this.chunkArray(files, this.maxConcurrency);
92
+
93
+ for (const chunk of chunks) {
94
+ await Promise.allSettled(
95
+ chunk.map(file => this.processFile(file, result))
96
+ );
97
+ }
98
+
99
+ } catch (error) {
100
+ result.addWarning(`Failed to scan path: ${scanPath}`, { error: error.message });
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Process a single file
106
+ * @param {Object} fileInfo - File information
107
+ * @param {DiscoveryResult} result - Discovery result object
108
+ * @returns {Promise<void>}
109
+ */
110
+ async processFile(fileInfo, result) {
111
+ try {
112
+ // Check if it's an agent tool
113
+ const isAgent = await isAgentTool(fileInfo);
114
+
115
+ if (!isAgent) {
116
+ return;
117
+ }
118
+
119
+ // Get command help for analysis
120
+ let commandHelp = '';
121
+ try {
122
+ commandHelp = await getCommandHelp(fileInfo.path, this.timeout / 10);
123
+ } catch (error) {
124
+ // Help not available, continue without it
125
+ }
126
+
127
+ // Create discovered agent
128
+ const agent = new DiscoveredAgent(fileInfo, commandHelp);
129
+
130
+ result.addAgent(agent);
131
+
132
+ } catch (error) {
133
+ result.addWarning(`Failed to process file: ${fileInfo.name}`, {
134
+ error: error.message
135
+ });
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Calculate confidence score for discovered agent
141
+ * @param {DiscoveredAgent} agent - Discovered agent
142
+ * @returns {Promise<number>} - Confidence score (0-1)
143
+ */
144
+ async calculateConfidence(agent) {
145
+ let confidence = 0;
146
+
147
+ // Help text analysis (40% weight)
148
+ if (agent.help) {
149
+ const helpLower = agent.help.toLowerCase();
150
+ const agentKeywords = [
151
+ 'agent', 'ai', 'assistant', 'chat', 'llm', 'model',
152
+ 'openai', 'anthropic', 'claude', 'gpt', 'gemini'
153
+ ];
154
+
155
+ const keywordMatches = agentKeywords.filter(keyword =>
156
+ helpLower.includes(keyword.toLowerCase())
157
+ ).length;
158
+
159
+ confidence += (keywordMatches / agentKeywords.length) * 0.4;
160
+ }
161
+
162
+ // File name analysis (30% weight)
163
+ const nameLower = agent.name.toLowerCase();
164
+ const nameKeywords = [
165
+ 'agent', 'ai', 'assistant', 'chat', 'llm', 'claude', 'gpt'
166
+ ];
167
+
168
+ const nameMatches = nameKeywords.filter(keyword =>
169
+ nameLower.includes(keyword.toLowerCase())
170
+ ).length;
171
+
172
+ confidence += (nameMatches / nameKeywords.length) * 0.3;
173
+
174
+ // Path analysis (20% weight)
175
+ const pathLower = agent.path.toLowerCase();
176
+ const pathIndicators = ['agent', 'ai', 'tools', 'bin'];
177
+ const pathMatches = pathIndicators.filter(indicator =>
178
+ pathLower.includes(indicator.toLowerCase())
179
+ ).length;
180
+
181
+ confidence += (pathMatches / pathIndicators.length) * 0.2;
182
+
183
+ // Executable status (10% weight)
184
+ try {
185
+ const metadata = await getFileMetadata(agent.path);
186
+ if (metadata.isExecutable) {
187
+ confidence += 0.1;
188
+ }
189
+ } catch (error) {
190
+ // Unable to check executable status
191
+ }
192
+
193
+ return Math.min(1, confidence);
194
+ }
195
+
196
+ /**
197
+ * Analyze and rank discovered agents
198
+ * @param {DiscoveryResult} result - Discovery result object
199
+ * @returns {Promise<void>}
200
+ */
201
+ async analyzeDiscoveredAgents(result) {
202
+ // Calculate confidence scores for all agents
203
+ for (const agent of result.agents) {
204
+ const confidence = await this.calculateConfidence(agent);
205
+ agent.setConfidence(confidence);
206
+ }
207
+
208
+ // Sort agents by confidence score
209
+ result.agents.sort((a, b) => b.confidence - a.confidence);
210
+
211
+ // Verify high-confidence agents
212
+ const highConfidenceAgents = result.agents.filter(a => a.confidence > 0.7);
213
+
214
+ for (const agent of highConfidenceAgents) {
215
+ try {
216
+ const isVerified = await this.verifyAgent(agent);
217
+ agent.setVerified(isVerified);
218
+ } catch (error) {
219
+ result.addWarning(`Failed to verify agent: ${agent.name}`, {
220
+ error: error.message
221
+ });
222
+ }
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Verify a discovered agent
228
+ * @param {DiscoveredAgent} agent - Agent to verify
229
+ * @returns {Promise<boolean>} - True if agent is verified
230
+ */
231
+ async verifyAgent(agent) {
232
+ try {
233
+ // Try to run the agent with --version or --help
234
+ const verifyCommands = ['--version', '--help', '-v', '-h'];
235
+
236
+ for (const cmd of verifyCommands) {
237
+ try {
238
+ await execAsync(`${agent.path} ${cmd}`, {
239
+ timeout: 5000
240
+ });
241
+ return true;
242
+ } catch (error) {
243
+ // Try next command
244
+ }
245
+ }
246
+
247
+ return false;
248
+ } catch (error) {
249
+ return false;
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Split array into chunks
255
+ * @param {Array} array - Array to split
256
+ * @param {number} size - Chunk size
257
+ * @returns {Array<Array>} - Array of chunks
258
+ */
259
+ chunkArray(array, size) {
260
+ const chunks = [];
261
+ for (let i = 0; i < array.length; i += size) {
262
+ chunks.push(array.slice(i, i + size));
263
+ }
264
+ return chunks;
265
+ }
266
+ }
267
+
268
+ module.exports = DiscoveryScanner;