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.
- package/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- 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;
|