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,472 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple Agent Check Service
|
|
3
|
+
*
|
|
4
|
+
* Simplified agent checking that does exactly 5 steps:
|
|
5
|
+
* 1. Check if agent/IDE is installed
|
|
6
|
+
* 2. Add test requirement to hostname-specific requirements file
|
|
7
|
+
* 3. Send simple check command to agent
|
|
8
|
+
* 4. Check for test result
|
|
9
|
+
* 5. Delete test requirement (success or failure)
|
|
10
|
+
*
|
|
11
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const fs = require('fs').promises;
|
|
16
|
+
const fsSync = require('fs');
|
|
17
|
+
const os = require('os');
|
|
18
|
+
const { spawn } = require('child_process');
|
|
19
|
+
|
|
20
|
+
// Constants
|
|
21
|
+
const TEST_REQ_TITLE = 'VCM agent connectivity check';
|
|
22
|
+
const PENDING_HEADER = '## ⏳ Requirements not yet completed';
|
|
23
|
+
const VERIFIED_HEADER = '## ✅ Verified by AI';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get hostname-based requirements file path
|
|
27
|
+
*/
|
|
28
|
+
function getRequirementsPath(repoPath) {
|
|
29
|
+
const hostname = os.hostname();
|
|
30
|
+
return path.join(repoPath, '.vibecodingmachine', `REQUIREMENTS-${hostname}.md`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get result file path
|
|
35
|
+
*/
|
|
36
|
+
function getResultFilePath(repoPath) {
|
|
37
|
+
return path.join(repoPath, '.vibecodingmachine', 'temp', 'TEMP_agent_check.txt');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Simple agent check service class
|
|
42
|
+
*/
|
|
43
|
+
class SimpleAgentCheckService {
|
|
44
|
+
constructor(options = {}) {
|
|
45
|
+
this.logger = options.logger || null;
|
|
46
|
+
this.repoPath = options.repoPath || process.cwd();
|
|
47
|
+
this.timeout = options.timeout || 60000; // 1 minute default
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check if agent is installed
|
|
52
|
+
*/
|
|
53
|
+
async checkAgentInstallation(agentId, agentConfig) {
|
|
54
|
+
if (agentConfig.type === 'ide') {
|
|
55
|
+
// Check if IDE process is running
|
|
56
|
+
const processName = agentConfig.process;
|
|
57
|
+
const { exec } = require('child_process');
|
|
58
|
+
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
exec(`pgrep -f "${processName}"`, (error, stdout, stderr) => {
|
|
61
|
+
const isRunning = !error && stdout.trim().length > 0;
|
|
62
|
+
resolve({ installed: isRunning, processName });
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
// For CLI agents, check if command exists
|
|
67
|
+
const command = agentConfig.command;
|
|
68
|
+
const { exec } = require('child_process');
|
|
69
|
+
|
|
70
|
+
return new Promise((resolve) => {
|
|
71
|
+
exec(`which ${command}`, (error, stdout, stderr) => {
|
|
72
|
+
const isInstalled = !error;
|
|
73
|
+
resolve({ installed: isInstalled, command });
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Add test requirement to requirements file
|
|
81
|
+
*/
|
|
82
|
+
async addTestRequirement(agentId) {
|
|
83
|
+
const reqPath = getRequirementsPath(this.repoPath);
|
|
84
|
+
const resultFile = getResultFilePath(this.repoPath);
|
|
85
|
+
|
|
86
|
+
let content = '';
|
|
87
|
+
try {
|
|
88
|
+
content = await fs.readFile(reqPath, 'utf8');
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if (error.code === 'ENOENT') {
|
|
91
|
+
// Create file with basic structure
|
|
92
|
+
content = `## ⏳ Requirements not yet completed
|
|
93
|
+
|
|
94
|
+
## ✅ Verified by AI
|
|
95
|
+
|
|
96
|
+
`;
|
|
97
|
+
} else {
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Already present?
|
|
103
|
+
if (content.includes(TEST_REQ_TITLE)) {
|
|
104
|
+
return { added: false, reason: 'already_exists' };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const testBlock = `### 1. ${TEST_REQ_TITLE}
|
|
108
|
+
🚦 Current Status: PREPARE
|
|
109
|
+
Create a new file at the following absolute path: ${resultFile}
|
|
110
|
+
The file must contain exactly this text on the first line: VCM_CHECK_OK
|
|
111
|
+
Do not modify any other files. This is an automated connectivity test.
|
|
112
|
+
|
|
113
|
+
`;
|
|
114
|
+
|
|
115
|
+
const pendingIndex = content.indexOf('## ⏳ Requirements not yet completed');
|
|
116
|
+
if (pendingIndex !== -1) {
|
|
117
|
+
// Insert after the pending header
|
|
118
|
+
const afterHeader = pendingIndex + '## ⏳ Requirements not yet completed'.length;
|
|
119
|
+
const before = content.slice(0, afterHeader);
|
|
120
|
+
const after = content.slice(afterHeader).replace(/^\n+/, '');
|
|
121
|
+
const newContent = before + '\n\n' + testBlock + after;
|
|
122
|
+
await fs.writeFile(reqPath, newContent, 'utf8');
|
|
123
|
+
} else {
|
|
124
|
+
// If no pending header, add it
|
|
125
|
+
const newContent = `## ⏳ Requirements not yet completed
|
|
126
|
+
|
|
127
|
+
${testBlock}
|
|
128
|
+
|
|
129
|
+
## ✅ Verified by AI
|
|
130
|
+
|
|
131
|
+
`;
|
|
132
|
+
await fs.writeFile(reqPath, newContent, 'utf8');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return { added: true, reqPath, resultFile };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Send simple check command to agent
|
|
140
|
+
*/
|
|
141
|
+
async sendCheckCommand(agentId, agentConfig) {
|
|
142
|
+
if (agentConfig.type === 'ide') {
|
|
143
|
+
// For IDE agents, use auto mode
|
|
144
|
+
const CLI_ENTRY_POINT = path.join(this.repoPath, 'bin', 'vibecodingmachine.js');
|
|
145
|
+
const args = ['auto', 'start', '--ide', agentId, '--max-chats', '1'];
|
|
146
|
+
|
|
147
|
+
return new Promise((resolve) => {
|
|
148
|
+
const child = spawn('node', args, {
|
|
149
|
+
cwd: this.repoPath,
|
|
150
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
151
|
+
detached: false
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
let output = '';
|
|
155
|
+
child.stdout.on('data', (data) => {
|
|
156
|
+
output += data.toString();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
child.stderr.on('data', (data) => {
|
|
160
|
+
output += data.toString();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
child.on('exit', (code) => {
|
|
164
|
+
resolve({ success: code === 0, output, exitCode: code });
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Timeout
|
|
168
|
+
setTimeout(() => {
|
|
169
|
+
if (!child.killed) {
|
|
170
|
+
child.kill();
|
|
171
|
+
resolve({ success: false, output, exitCode: 'TIMEOUT' });
|
|
172
|
+
}
|
|
173
|
+
}, this.timeout);
|
|
174
|
+
});
|
|
175
|
+
} else {
|
|
176
|
+
// For CLI agents, send agent test command
|
|
177
|
+
const command = agentConfig.command;
|
|
178
|
+
const args = ['agent', 'test', '--repo', this.repoPath, '--result', getResultFilePath(this.repoPath)];
|
|
179
|
+
|
|
180
|
+
return new Promise((resolve) => {
|
|
181
|
+
const child = spawn(command, args, {
|
|
182
|
+
cwd: this.repoPath,
|
|
183
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
184
|
+
detached: false
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
let output = '';
|
|
188
|
+
child.stdout.on('data', (data) => {
|
|
189
|
+
output += data.toString();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
child.stderr.on('data', (data) => {
|
|
193
|
+
output += data.toString();
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
child.on('exit', (code) => {
|
|
197
|
+
resolve({ success: code === 0, output, exitCode: code });
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// Timeout
|
|
201
|
+
setTimeout(() => {
|
|
202
|
+
if (!child.killed) {
|
|
203
|
+
child.kill();
|
|
204
|
+
resolve({ success: false, output, exitCode: 'TIMEOUT' });
|
|
205
|
+
}
|
|
206
|
+
}, this.timeout);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Check for test result
|
|
213
|
+
*/
|
|
214
|
+
async checkTestResult(agentId) {
|
|
215
|
+
const resultFile = getResultFilePath(this.repoPath);
|
|
216
|
+
|
|
217
|
+
// Wait a bit for file to be created
|
|
218
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
if (fsSync.existsSync(resultFile)) {
|
|
222
|
+
const content = fsSync.readFileSync(resultFile, 'utf8');
|
|
223
|
+
const success = content.includes('VCM_CHECK_OK');
|
|
224
|
+
|
|
225
|
+
return { success, content };
|
|
226
|
+
} else {
|
|
227
|
+
return { success: false, reason: 'file_not_found' };
|
|
228
|
+
}
|
|
229
|
+
} catch (error) {
|
|
230
|
+
return { success: false, reason: 'error', error: error.message };
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Remove test requirement
|
|
236
|
+
*/
|
|
237
|
+
async removeTestRequirement(agentId) {
|
|
238
|
+
const reqPath = getRequirementsPath(this.repoPath);
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
let content = '';
|
|
242
|
+
try {
|
|
243
|
+
content = await fs.readFile(reqPath, 'utf8');
|
|
244
|
+
} catch {
|
|
245
|
+
return { removed: false, reason: 'file_not_found' };
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (!content.includes(TEST_REQ_TITLE)) {
|
|
249
|
+
return { removed: false, reason: 'not_found' };
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const lines = content.split('\n');
|
|
253
|
+
let blockStart = -1;
|
|
254
|
+
|
|
255
|
+
for (let i = 0; i < lines.length; i++) {
|
|
256
|
+
if (lines[i].includes(TEST_REQ_TITLE)) {
|
|
257
|
+
blockStart = i;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (blockStart === -1) {
|
|
263
|
+
return { removed: false, reason: 'not_found' };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let blockEnd = blockStart + 1;
|
|
267
|
+
while (blockEnd < lines.length && !lines[blockEnd].startsWith('###') && !lines[blockEnd].startsWith('## ')) {
|
|
268
|
+
blockEnd++;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
lines.splice(blockStart, blockEnd - blockStart);
|
|
272
|
+
const cleaned = lines.join('\n').replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
|
|
273
|
+
await fs.writeFile(reqPath, cleaned, 'utf8');
|
|
274
|
+
|
|
275
|
+
return { removed: true };
|
|
276
|
+
} catch (error) {
|
|
277
|
+
return { removed: false, reason: 'error', error: error.message };
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Clean up test result file
|
|
283
|
+
*/
|
|
284
|
+
async cleanupTestResult(agentId) {
|
|
285
|
+
const resultFile = getResultFilePath(this.repoPath);
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
if (fsSync.existsSync(resultFile)) {
|
|
289
|
+
fsSync.unlinkSync(resultFile);
|
|
290
|
+
}
|
|
291
|
+
} catch (error) {
|
|
292
|
+
// Silently handle cleanup errors
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Check single agent - simplified 5-step process
|
|
298
|
+
*/
|
|
299
|
+
async checkAgent(agent, options = {}) {
|
|
300
|
+
const agentId = agent.id;
|
|
301
|
+
const startTime = Date.now();
|
|
302
|
+
const onProgress = options.onProgress || (() => {});
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
// Step 1: Check installation
|
|
306
|
+
onProgress(agentId, {
|
|
307
|
+
phase: 'step1',
|
|
308
|
+
step: 1,
|
|
309
|
+
message: 'INSTALLED?',
|
|
310
|
+
detail: `Checking ${agent.name} installation...`
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
const installCheck = await this.checkAgentInstallation(agentId, agent);
|
|
314
|
+
|
|
315
|
+
const installDetail = agent.type === 'ide'
|
|
316
|
+
? `Process: ${installCheck.processName || agent.process} - ${installCheck.installed ? 'RUNNING' : 'NOT RUNNING'}`
|
|
317
|
+
: `Command: ${installCheck.command || agent.command} - ${installCheck.installed ? 'AVAILABLE' : 'NOT FOUND'}`;
|
|
318
|
+
|
|
319
|
+
onProgress(agentId, {
|
|
320
|
+
phase: 'step1',
|
|
321
|
+
step: 1,
|
|
322
|
+
message: 'INSTALLED?',
|
|
323
|
+
detail: installDetail
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
if (!installCheck.installed) {
|
|
327
|
+
const message = agent.type === 'ide'
|
|
328
|
+
? `${agent.name} is not running (process: ${installCheck.processName || agent.process})`
|
|
329
|
+
: `${agent.name} is not installed (command: ${installCheck.command || agent.command})`;
|
|
330
|
+
|
|
331
|
+
return {
|
|
332
|
+
success: false,
|
|
333
|
+
agentId,
|
|
334
|
+
status: 'not_installed',
|
|
335
|
+
message,
|
|
336
|
+
duration: Date.now() - startTime,
|
|
337
|
+
timestamp: new Date().toISOString()
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Step 2: Add test requirement
|
|
342
|
+
onProgress(agentId, {
|
|
343
|
+
phase: 'step2',
|
|
344
|
+
step: 2,
|
|
345
|
+
message: 'REQUIREMENTS',
|
|
346
|
+
detail: 'Adding test requirement to requirements file...'
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const reqResult = await this.addTestRequirement(agentId);
|
|
350
|
+
|
|
351
|
+
const reqDetail = reqResult.added
|
|
352
|
+
? `Added test requirement to ${reqResult.reqPath}`
|
|
353
|
+
: `Failed to add requirement: ${reqResult.reason}`;
|
|
354
|
+
|
|
355
|
+
onProgress(agentId, {
|
|
356
|
+
phase: 'step2',
|
|
357
|
+
step: 2,
|
|
358
|
+
message: 'REQUIREMENTS',
|
|
359
|
+
detail: reqDetail
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
if (!reqResult.added) {
|
|
363
|
+
return {
|
|
364
|
+
success: false,
|
|
365
|
+
agentId,
|
|
366
|
+
status: 'requirement_error',
|
|
367
|
+
message: `Failed to add test requirement: ${reqResult.reason}`,
|
|
368
|
+
duration: Date.now() - startTime,
|
|
369
|
+
timestamp: new Date().toISOString()
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Step 3: Send check command
|
|
374
|
+
onProgress(agentId, {
|
|
375
|
+
phase: 'step3',
|
|
376
|
+
step: 3,
|
|
377
|
+
message: 'TEST',
|
|
378
|
+
detail: `Sending check command to ${agent.name}...`
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
const cmdResult = await this.sendCheckCommand(agentId, agent);
|
|
382
|
+
|
|
383
|
+
const cmdDetail = cmdResult.success
|
|
384
|
+
? `Command sent successfully`
|
|
385
|
+
: `Command failed: ${cmdResult.exitCode === 'TIMEOUT' ? 'TIMEOUT' : `Exit code ${cmdResult.exitCode}`}`;
|
|
386
|
+
|
|
387
|
+
onProgress(agentId, {
|
|
388
|
+
phase: 'step3',
|
|
389
|
+
step: 3,
|
|
390
|
+
message: 'TEST',
|
|
391
|
+
detail: cmdDetail
|
|
392
|
+
});
|
|
393
|
+
|
|
394
|
+
// Step 4: Check test result
|
|
395
|
+
const testResult = await this.checkTestResult(agentId);
|
|
396
|
+
|
|
397
|
+
const testDetail = testResult.success
|
|
398
|
+
? `Test result: SUCCESS`
|
|
399
|
+
: `Test result: ${testResult.reason || 'FAILED'}`;
|
|
400
|
+
|
|
401
|
+
onProgress(agentId, {
|
|
402
|
+
phase: 'step4',
|
|
403
|
+
step: 4,
|
|
404
|
+
message: 'DELETE',
|
|
405
|
+
detail: 'Cleaning up test requirement...'
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Step 5: Remove test requirement
|
|
409
|
+
const removeResult = await this.removeTestRequirement(agentId);
|
|
410
|
+
|
|
411
|
+
const removeDetail = removeResult.removed
|
|
412
|
+
? `Test requirement removed successfully`
|
|
413
|
+
: `Remove failed: ${removeResult.reason}`;
|
|
414
|
+
|
|
415
|
+
onProgress(agentId, {
|
|
416
|
+
phase: 'step5',
|
|
417
|
+
step: 5,
|
|
418
|
+
message: 'STATUS',
|
|
419
|
+
detail: testDetail
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Clean up test result file
|
|
423
|
+
await this.cleanupTestResult(agentId);
|
|
424
|
+
|
|
425
|
+
// Determine final status
|
|
426
|
+
let status, message;
|
|
427
|
+
if (testResult.success) {
|
|
428
|
+
status = 'reachable';
|
|
429
|
+
message = `${agent.name} is reachable and responding`;
|
|
430
|
+
} else if (cmdResult.exitCode === 'TIMEOUT') {
|
|
431
|
+
status = 'timeout';
|
|
432
|
+
message = `${agent.name} timed out - may need authentication`;
|
|
433
|
+
} else if (cmdResult.output && cmdResult.output.toLowerCase().includes('rate limit')) {
|
|
434
|
+
status = 'rate_limited';
|
|
435
|
+
message = `${agent.name} is rate limited`;
|
|
436
|
+
} else {
|
|
437
|
+
status = 'unreachable';
|
|
438
|
+
message = `${agent.name} is not responding - check authentication`;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const duration = Date.now() - startTime;
|
|
442
|
+
|
|
443
|
+
return {
|
|
444
|
+
success: testResult.success,
|
|
445
|
+
agentId,
|
|
446
|
+
status,
|
|
447
|
+
message,
|
|
448
|
+
duration,
|
|
449
|
+
timestamp: new Date().toISOString(),
|
|
450
|
+
details: {
|
|
451
|
+
installCheck,
|
|
452
|
+
reqResult,
|
|
453
|
+
cmdResult,
|
|
454
|
+
testResult
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
} catch (error) {
|
|
459
|
+
return {
|
|
460
|
+
success: false,
|
|
461
|
+
agentId,
|
|
462
|
+
status: 'error',
|
|
463
|
+
message: `Check failed: ${error.message}`,
|
|
464
|
+
duration: Date.now() - startTime,
|
|
465
|
+
timestamp: new Date().toISOString(),
|
|
466
|
+
error: error.message
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
module.exports = SimpleAgentCheckService;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Utilities Module
|
|
3
|
+
*
|
|
4
|
+
* Provides utility functions for configuration management.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Set nested configuration value
|
|
10
|
+
* @param {Object} obj - Target object
|
|
11
|
+
* @param {string} path - Dot-separated path
|
|
12
|
+
* @param {*} value - Value to set
|
|
13
|
+
*/
|
|
14
|
+
function setNestedValue(obj, path, value) {
|
|
15
|
+
const keys = path.split('.');
|
|
16
|
+
let current = obj;
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
19
|
+
const key = keys[i];
|
|
20
|
+
if (!(key in current) || typeof current[key] !== 'object') {
|
|
21
|
+
current[key] = {};
|
|
22
|
+
}
|
|
23
|
+
current = current[key];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
current[keys[keys.length - 1]] = value;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get nested configuration value
|
|
31
|
+
* @param {Object} obj - Source object
|
|
32
|
+
* @param {string} path - Dot-separated path
|
|
33
|
+
* @returns {*} - Configuration value
|
|
34
|
+
*/
|
|
35
|
+
function getNestedValue(obj, path) {
|
|
36
|
+
const keys = path.split('.');
|
|
37
|
+
let current = obj;
|
|
38
|
+
|
|
39
|
+
for (const key of keys) {
|
|
40
|
+
if (current && typeof current === 'object' && key in current) {
|
|
41
|
+
current = current[key];
|
|
42
|
+
} else {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return current;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Deep merge objects
|
|
52
|
+
* @param {Object} target - Target object
|
|
53
|
+
* @param {Object} source - Source object
|
|
54
|
+
*/
|
|
55
|
+
function deepMerge(target, source) {
|
|
56
|
+
for (const key in source) {
|
|
57
|
+
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
58
|
+
if (!target[key] || typeof target[key] !== 'object') {
|
|
59
|
+
target[key] = {};
|
|
60
|
+
}
|
|
61
|
+
deepMerge(target[key], source[key]);
|
|
62
|
+
} else {
|
|
63
|
+
target[key] = source[key];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = {
|
|
69
|
+
setNestedValue,
|
|
70
|
+
getNestedValue,
|
|
71
|
+
deepMerge
|
|
72
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default Configuration Module
|
|
3
|
+
*
|
|
4
|
+
* Defines default configuration schema.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Get default configuration schema
|
|
10
|
+
* @returns {Object} - Default configuration
|
|
11
|
+
*/
|
|
12
|
+
function getDefaultConfig() {
|
|
13
|
+
return {
|
|
14
|
+
installation: {
|
|
15
|
+
timeout: 300000,
|
|
16
|
+
maxConcurrent: 2,
|
|
17
|
+
retryAttempts: 3,
|
|
18
|
+
retryDelay: 5000,
|
|
19
|
+
autoElevate: false
|
|
20
|
+
},
|
|
21
|
+
logging: {
|
|
22
|
+
level: 'info',
|
|
23
|
+
file: null,
|
|
24
|
+
format: 'json',
|
|
25
|
+
verbose: false
|
|
26
|
+
},
|
|
27
|
+
cache: {
|
|
28
|
+
directory: './cache',
|
|
29
|
+
maxSize: 100 * 1024 * 1024, // 100MB
|
|
30
|
+
ttl: 3600000 // 1 hour
|
|
31
|
+
},
|
|
32
|
+
network: {
|
|
33
|
+
timeout: 30000,
|
|
34
|
+
proxy: null,
|
|
35
|
+
userAgent: null,
|
|
36
|
+
rateLimitDelay: 1000
|
|
37
|
+
},
|
|
38
|
+
security: {
|
|
39
|
+
strictMode: true,
|
|
40
|
+
maxFileSize: 100 * 1024 * 1024, // 100MB
|
|
41
|
+
allowedExtensions: ['.exe', '.msi', '.zip', '.tar', '.gz']
|
|
42
|
+
},
|
|
43
|
+
performance: {
|
|
44
|
+
monitoring: true,
|
|
45
|
+
metricsFile: null,
|
|
46
|
+
flushInterval: 60000
|
|
47
|
+
},
|
|
48
|
+
agents: {
|
|
49
|
+
defaultFile: './config/agents.json',
|
|
50
|
+
discoveryEnabled: true,
|
|
51
|
+
autoUpdate: false
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
getDefaultConfig
|
|
58
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Variable Loader Module
|
|
3
|
+
*
|
|
4
|
+
* Handles loading configuration from environment variables.
|
|
5
|
+
* Follows constitutional requirements: <555 lines, test-first approach.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { setNestedValue } = require('./ConfigUtils');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load configuration from environment variables
|
|
12
|
+
* @param {Object} variableMappings - Variable mappings
|
|
13
|
+
* @param {string} prefix - Environment variable prefix
|
|
14
|
+
* @param {Object} logger - Logger instance
|
|
15
|
+
* @returns {Object} - Environment configuration
|
|
16
|
+
*/
|
|
17
|
+
function loadEnvironmentVariables(variableMappings, prefix, logger) {
|
|
18
|
+
const config = {};
|
|
19
|
+
|
|
20
|
+
for (const [envVar, configPath] of Object.entries(variableMappings)) {
|
|
21
|
+
const fullEnvVar = prefix + envVar;
|
|
22
|
+
const value = process.env[fullEnvVar];
|
|
23
|
+
|
|
24
|
+
if (value !== undefined) {
|
|
25
|
+
setNestedValue(config, configPath, value);
|
|
26
|
+
|
|
27
|
+
if (logger) {
|
|
28
|
+
logger.debug('Loaded environment variable', {
|
|
29
|
+
variable: fullEnvVar,
|
|
30
|
+
configPath,
|
|
31
|
+
value
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return config;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Export configuration to environment file
|
|
42
|
+
* @param {Object} config - Configuration object
|
|
43
|
+
* @param {Object} defaultConfig - Default configuration
|
|
44
|
+
* @param {Object} variableMappings - Variable mappings
|
|
45
|
+
* @param {string} prefix - Environment variable prefix
|
|
46
|
+
* @param {Function} getNestedValue - Get nested value function
|
|
47
|
+
* @returns {Array<string>} - Environment variable lines
|
|
48
|
+
*/
|
|
49
|
+
function exportToEnvironmentVariables(config, defaultConfig, variableMappings, prefix, getNestedValue) {
|
|
50
|
+
const envVars = [];
|
|
51
|
+
|
|
52
|
+
for (const [envVar, configPath] of Object.entries(variableMappings)) {
|
|
53
|
+
const value = getNestedValue(config, configPath);
|
|
54
|
+
if (value !== undefined && value !== getNestedValue(defaultConfig, configPath)) {
|
|
55
|
+
const fullEnvVar = prefix + envVar;
|
|
56
|
+
envVars.push(`${fullEnvVar}=${JSON.stringify(value)}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return envVars;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
loadEnvironmentVariables,
|
|
65
|
+
exportToEnvironmentVariables
|
|
66
|
+
};
|