vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642

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 (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. package/src/sync/sync-engine-backup.js +0 -559
@@ -0,0 +1,690 @@
1
+ /**
2
+ * Agent Check Service
3
+ *
4
+ * Main service for checking agents (install + verify).
5
+ * Follows constitutional requirements: <555 lines, test-first approach.
6
+ */
7
+
8
+ const AgentInstallationService = require('./AgentInstallationService');
9
+ const AgentVerificationService = require('./AgentVerificationService');
10
+ const AgentSetupService = require('./AgentSetupService');
11
+ const AgentDiscoveryService = require('./discovery/AgentDiscoveryService');
12
+ const { AgentStatus } = require('./AgentStatus');
13
+
14
+ /**
15
+ * Agent check service class
16
+ */
17
+ class AgentCheckService {
18
+ /**
19
+ * Create check service instance
20
+ * @param {Object} config - Service configuration
21
+ */
22
+ constructor(config = {}) {
23
+ this.configManager = config.configManager || null;
24
+ this.logger = config.logger || null;
25
+ this.fileManager = config.fileManager || null;
26
+
27
+ // Create sub-services
28
+ this.installationService = AgentInstallationService.createDefault({
29
+ configManager: this.configManager,
30
+ logger: this.logger,
31
+ fileManager: this.fileManager,
32
+ ...config.installation
33
+ });
34
+
35
+ this.verificationService = AgentVerificationService.createDefault({
36
+ configManager: this.configManager,
37
+ logger: this.logger,
38
+ fileManager: this.fileManager,
39
+ ...config.verification
40
+ });
41
+
42
+ this.setupService = AgentSetupService.createDefault({
43
+ logger: this.logger,
44
+ ...config.setup
45
+ });
46
+
47
+ this.discoveryService = new AgentDiscoveryService({
48
+ configManager: this.configManager,
49
+ logger: this.logger,
50
+ fileManager: this.fileManager,
51
+ ...config.discovery
52
+ });
53
+
54
+ // Service configuration
55
+ this.parallel = config.parallel !== false;
56
+ this.maxConcurrency = config.maxConcurrency || 2;
57
+ this.timeout = config.timeout || 600000; // 10 minutes default
58
+ this.forceReinstall = config.forceReinstall || false;
59
+ this.skipVerification = config.skipVerification || false;
60
+ }
61
+
62
+ /**
63
+ * Check agents (install + verify)
64
+ * @param {Object} options - Check options
65
+ * @returns {Promise<Object>} - Check results
66
+ */
67
+ async checkAgents(options = {}) {
68
+ const {
69
+ agentIds = null,
70
+ forceReinstall = this.forceReinstall,
71
+ skipVerification = this.skipVerification,
72
+ timeout = this.timeout,
73
+ parallel = this.parallel,
74
+ maxConcurrency = this.maxConcurrency
75
+ } = options;
76
+
77
+ if (this.logger) {
78
+ await this.logger.info('Starting agent check operation', {
79
+ agentIds,
80
+ forceReinstall,
81
+ skipVerification,
82
+ timeout,
83
+ parallel,
84
+ maxConcurrency
85
+ });
86
+ }
87
+
88
+ const startTime = Date.now();
89
+ const results = {
90
+ totalAgents: 0,
91
+ installationResults: {},
92
+ verificationResults: {},
93
+ summary: {
94
+ allSuccessful: false,
95
+ hasFailures: false,
96
+ hasSkipped: false
97
+ },
98
+ duration: 0,
99
+ timestamp: new Date().toISOString()
100
+ };
101
+
102
+ try {
103
+ // Get agents to check
104
+ const agents = await this.getAgentsToCheck(agentIds);
105
+ results.totalAgents = agents.length;
106
+
107
+ if (agents.length === 0) {
108
+ return {
109
+ ...results,
110
+ message: 'No agents to check',
111
+ skipped: true
112
+ };
113
+ }
114
+
115
+ // Phase 1: Installation
116
+ if (this.logger) {
117
+ await this.logger.info('Phase 1: Agent Installation', {
118
+ agentCount: agents.length
119
+ });
120
+ }
121
+
122
+ const installationOptions = {
123
+ force: forceReinstall,
124
+ timeout: Math.floor(timeout * 0.6), // 60% of timeout for installation
125
+ parallel,
126
+ maxConcurrency
127
+ };
128
+
129
+ const installationResults = await this.installationService.installAgents(agents, installationOptions);
130
+ results.installationResults = installationResults.results;
131
+
132
+ // Phase 2: Setup (only if installation succeeded)
133
+ const successfullyInstalled = agents.filter(agent => {
134
+ const installResult = installationResults.results[agent.id];
135
+ return installResult && installResult.success;
136
+ });
137
+
138
+ let setupResults = null;
139
+ if (successfullyInstalled.length > 0) {
140
+ if (this.logger) {
141
+ await this.logger.info('Phase 2: Agent Setup', {
142
+ agentCount: successfullyInstalled.length
143
+ });
144
+ }
145
+
146
+ const setupOptions = {
147
+ timeout: Math.floor(timeout * 0.2), // 20% of timeout for setup
148
+ interactive: options.interactiveSetup !== false
149
+ };
150
+
151
+ setupResults = await this.setupService.performSetupBatch(successfullyInstalled, setupOptions);
152
+ results.setupResults = setupResults.results;
153
+ } else {
154
+ if (this.logger) {
155
+ await this.logger.warn('No agents successfully installed, skipping setup');
156
+ }
157
+ }
158
+
159
+ // Phase 3: Verification (only if installation succeeded and not skipped)
160
+ if (!skipVerification) {
161
+ if (this.logger) {
162
+ await this.logger.info('Phase 3: Agent Verification', {
163
+ agentCount: successfullyInstalled.length,
164
+ skipVerification: false
165
+ });
166
+ }
167
+
168
+ if (successfullyInstalled.length > 0) {
169
+ const verificationOptions = {
170
+ timeout: Math.floor(timeout * 0.2), // 20% of timeout for verification
171
+ parallel,
172
+ maxConcurrency
173
+ };
174
+
175
+ const verificationResults = await this.verificationService.verifyAgents(successfullyInstalled, verificationOptions);
176
+ results.verificationResults = verificationResults.results;
177
+ } else {
178
+ if (this.logger) {
179
+ await this.logger.warn('No agents successfully installed, skipping verification');
180
+ }
181
+ }
182
+ } else {
183
+ if (this.logger) {
184
+ await this.logger.info('Verification skipped by configuration');
185
+ }
186
+ }
187
+
188
+ // Calculate overall summary
189
+ this.calculateOverallSummary(results);
190
+
191
+ results.duration = Date.now() - startTime;
192
+
193
+ // Log overall check completion
194
+ await this.logCheckCompletion(results);
195
+
196
+ } catch (error) {
197
+ results.duration = Date.now() - startTime;
198
+ results.error = error.message;
199
+
200
+ if (this.logger) {
201
+ await this.logger.error('Agent check operation failed', {
202
+ agentIds,
203
+ error: error.message,
204
+ duration: results.duration
205
+ });
206
+ }
207
+
208
+ await this.logCheckError(error, results.duration);
209
+ }
210
+
211
+ return results;
212
+ }
213
+
214
+ /**
215
+ * Get agents to check
216
+ * @param {Array<string>} agentIds - Specific agent IDs
217
+ * @returns {Promise<Array>} - Agents to check
218
+ */
219
+ async getAgentsToCheck(agentIds) {
220
+ try {
221
+ if (agentIds && agentIds.length > 0) {
222
+ // Get specific agents
223
+ const agents = [];
224
+ for (const agentId of agentIds) {
225
+ const agent = this.configManager.getAgent(agentId);
226
+ if (agent && agent.enabled) {
227
+ agents.push(agent);
228
+ }
229
+ }
230
+ return agents;
231
+ } else {
232
+ // Get all enabled agents
233
+ return this.configManager.getEnabledAgents();
234
+ }
235
+ } catch (error) {
236
+ if (this.logger) {
237
+ await this.logger.error('Failed to get agents to check', {
238
+ agentIds,
239
+ error: error.message
240
+ });
241
+ }
242
+ return [];
243
+ }
244
+ }
245
+
246
+ /**
247
+ * Calculate overall summary
248
+ * @param {Object} results - Results object to update
249
+ */
250
+ calculateOverallSummary(results) {
251
+ let allSuccessful = true;
252
+ let hasFailures = false;
253
+ let hasSkipped = false;
254
+
255
+ // Check installation results
256
+ for (const [agentId, installResult] of Object.entries(results.installationResults)) {
257
+ if (!installResult.success) {
258
+ allSuccessful = false;
259
+ hasFailures = true;
260
+ }
261
+ }
262
+
263
+ // Check verification results
264
+ for (const [agentId, verifyResult] of Object.entries(results.verificationResults)) {
265
+ if (!verifyResult.success) {
266
+ allSuccessful = false;
267
+ hasFailures = true;
268
+ }
269
+
270
+ if (verifyResult.skipped) {
271
+ hasSkipped = true;
272
+ }
273
+ }
274
+
275
+ results.summary = {
276
+ allSuccessful,
277
+ hasFailures,
278
+ hasSkipped
279
+ };
280
+ }
281
+
282
+ /**
283
+ * Log check completion
284
+ * @param {Object} results - Check results
285
+ */
286
+ async logCheckCompletion(results) {
287
+ if (this.fileManager) {
288
+ await this.fileManager.writeLog('agent-check', {
289
+ operation: 'CHECK_AGENTS',
290
+ status: results.summary.allSuccessful ? 'COMPLETED' : 'FAILED',
291
+ message: `Agent check ${results.summary.allSuccessful ? 'completed' : 'failed'}`,
292
+ duration: results.duration,
293
+ results,
294
+ summary: results.summary,
295
+ timestamp: new Date().toISOString()
296
+ });
297
+ }
298
+ }
299
+
300
+ /**
301
+ * Log check error
302
+ * @param {Error} error - Error that occurred
303
+ * @param {number} duration - Operation duration
304
+ */
305
+ async logCheckError(error, duration) {
306
+ if (this.fileManager) {
307
+ await this.fileManager.writeLog('agent-check', {
308
+ operation: 'CHECK_AGENTS',
309
+ status: 'FAILED',
310
+ message: `Agent check failed: ${error.message}`,
311
+ duration,
312
+ error: error.message,
313
+ timestamp: new Date().toISOString()
314
+ });
315
+ }
316
+ }
317
+
318
+ /**
319
+ * Get check operation statistics
320
+ * @returns {Promise<Object>} - Check statistics
321
+ */
322
+ async getCheckStatistics() {
323
+ try {
324
+ const agents = this.configManager.getEnabledAgents();
325
+
326
+ const stats = {
327
+ totalAgents: agents.length,
328
+ verified: 0,
329
+ notVerified: 0,
330
+ error: 0,
331
+ installing: 0,
332
+ lastCheck: null,
333
+ checkRate: 0
334
+ };
335
+
336
+ let latestCheck = null;
337
+
338
+ for (const agent of agents) {
339
+ const status = await this.configManager.getAgentStatus(agent.id);
340
+
341
+ if (status) {
342
+ switch (status.status) {
343
+ case AgentStatus.VERIFIED:
344
+ stats.verified++;
345
+ break;
346
+ case AgentStatus.NOT_INSTALLED:
347
+ case AgentStatus.INSTALLED:
348
+ stats.notVerified++;
349
+ break;
350
+ case AgentStatus.ERROR:
351
+ stats.error++;
352
+ break;
353
+ case AgentStatus.INSTALLING:
354
+ stats.installing++;
355
+ break;
356
+ }
357
+
358
+ // Track latest check
359
+ if (status.lastChecked) {
360
+ const checkDate = new Date(status.lastChecked);
361
+ if (!latestCheck || checkDate > latestCheck) {
362
+ latestCheck = status.lastChecked;
363
+ }
364
+ }
365
+ } else {
366
+ stats.notVerified++;
367
+ }
368
+ }
369
+
370
+ stats.lastCheck = latestCheck ? latestCheck.toISOString() : null;
371
+
372
+ // Calculate check rate (agents that have been checked at least once)
373
+ const checkedAgents = stats.verified + stats.notVerified + stats.error;
374
+ stats.checkRate = agents.length > 0 ? (checkedAgents / agents.length) * 100 : 0;
375
+
376
+ return stats;
377
+ } catch (error) {
378
+ if (this.logger) {
379
+ await this.logger.error('Failed to get check statistics', {
380
+ error: error.message
381
+ });
382
+ }
383
+
384
+ return {
385
+ totalAgents: 0,
386
+ verified: 0,
387
+ notVerified: 0,
388
+ error: 0,
389
+ installing: 0,
390
+ lastCheck: null,
391
+ checkRate: 0,
392
+ error: error.message
393
+ };
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Get detailed agent status
399
+ * @param {string} agentId - Agent identifier
400
+ * @returns {Promise<Object>} - Detailed agent status
401
+ */
402
+ async getDetailedAgentStatus(agentId) {
403
+ try {
404
+ const agent = this.configManager.getAgent(agentId);
405
+ if (!agent) {
406
+ return {
407
+ agentId,
408
+ found: false,
409
+ error: 'Agent not found'
410
+ };
411
+ }
412
+
413
+ const status = await this.configManager.getAgentStatus(agentId);
414
+ const history = await this.getStatusHistory(agentId, 10);
415
+
416
+ return {
417
+ agentId,
418
+ found: true,
419
+ agent: {
420
+ id: agent.id,
421
+ name: agent.name,
422
+ description: agent.description,
423
+ enabled: agent.enabled,
424
+ status: status ? status.status : AgentStatus.NOT_INSTALLED,
425
+ lastChecked: status ? status.lastChecked : null,
426
+ lastVerified: status ? status.lastVerified : null,
427
+ message: status ? status.message : '',
428
+ installationMethods: agent.installationMethods,
429
+ verificationCommands: agent.verificationCommands
430
+ },
431
+ status,
432
+ history,
433
+ canInstall: agent.enabled && status ? status.status === AgentStatus.NOT_INSTALLED : false,
434
+ canVerify: agent.enabled && status ? [AgentStatus.INSTALLED, AgentStatus.VERIFIED].includes(status.status) : false
435
+ };
436
+ } catch (error) {
437
+ if (this.logger) {
438
+ await this.logger.error('Failed to get detailed agent status', {
439
+ agentId,
440
+ error: error.message
441
+ });
442
+ }
443
+
444
+ return {
445
+ agentId,
446
+ found: false,
447
+ error: error.message
448
+ };
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Get status history for an agent
454
+ * @param {string} agentId - Agent identifier
455
+ * @param {number} limit - Maximum entries
456
+ * @returns {Promise<Array>} - Status history
457
+ */
458
+ async getStatusHistory(agentId, limit = 50) {
459
+ try {
460
+ if (this.fileManager) {
461
+ const logs = await this.fileManager.readLogs('status-change', { limit });
462
+ return logs
463
+ .filter(log => log.agentId === agentId)
464
+ .slice(-limit)
465
+ .reverse(); // Most recent first
466
+ }
467
+ return [];
468
+ } catch (error) {
469
+ if (this.logger) {
470
+ await this.logger.error('Failed to get status history', {
471
+ agentId,
472
+ error: error.message
473
+ });
474
+ }
475
+ return [];
476
+ }
477
+ }
478
+
479
+ /**
480
+ * Discover new agents in the system
481
+ * @param {Object} options - Discovery options
482
+ * @returns {Promise<Object>} - Discovery results
483
+ */
484
+ async discoverAgents(options = {}) {
485
+ try {
486
+ if (this.logger) {
487
+ await this.logger.info('Starting agent discovery', options);
488
+ }
489
+
490
+ const discoveryOptions = {
491
+ includeDisabled: options.includeDisabled || false,
492
+ scanSystem: options.scanSystem !== false,
493
+ scanConfigFiles: options.scanConfigFiles !== false,
494
+ timeout: options.timeout || 300000, // 5 minutes
495
+ ...options
496
+ };
497
+
498
+ const discoveryResult = await this.discoveryService.discoverAgents(discoveryOptions);
499
+
500
+ if (this.logger) {
501
+ await this.logger.info('Agent discovery completed', {
502
+ discoveredCount: discoveryResult.discovered?.length || 0,
503
+ newCount: discoveryResult.new?.length || 0,
504
+ existingCount: discoveryResult.existing?.length || 0
505
+ });
506
+ }
507
+
508
+ return {
509
+ success: true,
510
+ ...discoveryResult,
511
+ message: `Discovered ${discoveryResult.discovered?.length || 0} agents (${discoveryResult.new?.length || 0} new)`
512
+ };
513
+
514
+ } catch (error) {
515
+ if (this.logger) {
516
+ await this.logger.error('Agent discovery failed', { error: error.message });
517
+ }
518
+
519
+ return {
520
+ success: false,
521
+ error: error.message,
522
+ message: 'Agent discovery failed'
523
+ };
524
+ }
525
+ }
526
+
527
+ /**
528
+ * Check agents with discovery (discover + install + verify)
529
+ * @param {Object} options - Check options with discovery
530
+ * @returns {Promise<Object>} - Combined check and discovery results
531
+ */
532
+ async checkAgentsWithDiscovery(options = {}) {
533
+ const {
534
+ runDiscovery = true,
535
+ addDiscovered = false,
536
+ ...checkOptions
537
+ } = options;
538
+
539
+ try {
540
+ const startTime = Date.now();
541
+ const results = {
542
+ discovery: null,
543
+ check: null,
544
+ summary: {
545
+ totalDuration: 0,
546
+ discoverySuccessful: false,
547
+ checkSuccessful: false,
548
+ newAgentsDiscovered: 0,
549
+ agentsChecked: 0
550
+ }
551
+ };
552
+
553
+ // Phase 0: Discovery (if requested)
554
+ if (runDiscovery) {
555
+ if (this.logger) {
556
+ await this.logger.info('Phase 0: Agent Discovery');
557
+ }
558
+
559
+ const discoveryOptions = {
560
+ includeDisabled: false,
561
+ scanSystem: true,
562
+ scanConfigFiles: true,
563
+ timeout: Math.floor((checkOptions.timeout || 600000) * 0.2), // 20% of time for discovery
564
+ ...options.discovery
565
+ };
566
+
567
+ results.discovery = await this.discoverAgents(discoveryOptions);
568
+ results.summary.discoverySuccessful = results.discovery.success;
569
+ results.summary.newAgentsDiscovered = results.discovery.new?.length || 0;
570
+
571
+ // Add discovered agents if requested
572
+ if (addDiscovered && results.discovery.new?.length > 0) {
573
+ if (this.logger) {
574
+ await this.logger.info(`Adding ${results.discovery.new.length} discovered agents`);
575
+ }
576
+
577
+ // Note: This would require AgentAdditionService integration
578
+ // For now, just log the discovered agents
579
+ for (const agent of results.discovery.new) {
580
+ if (this.logger) {
581
+ await this.logger.info(`Discovered new agent: ${agent.id} (${agent.name})`);
582
+ }
583
+ }
584
+ }
585
+ }
586
+
587
+ // Phase 1+: Regular agent check
588
+ if (this.logger) {
589
+ await this.logger.info('Phase 1+: Agent Check (Install + Verify)');
590
+ }
591
+
592
+ results.check = await this.checkAgents(checkOptions);
593
+ results.summary.checkSuccessful = results.check.summary?.allSuccessful || false;
594
+ results.summary.agentsChecked = results.check.totalAgents || 0;
595
+
596
+ results.summary.totalDuration = Date.now() - startTime;
597
+
598
+ return {
599
+ success: results.summary.discoverySuccessful && results.summary.checkSuccessful,
600
+ ...results,
601
+ message: `Completed: ${results.summary.newAgentsDiscovered} new agents discovered, ${results.summary.agentsChecked} agents checked`
602
+ };
603
+
604
+ } catch (error) {
605
+ if (this.logger) {
606
+ await this.logger.error('Check agents with discovery failed', { error: error.message });
607
+ }
608
+
609
+ return {
610
+ success: false,
611
+ error: error.message,
612
+ message: 'Check agents with discovery failed'
613
+ };
614
+ }
615
+ }
616
+
617
+ /**
618
+ * Get service information
619
+ * @returns {Object} - Service info
620
+ */
621
+ getServiceInfo() {
622
+ return {
623
+ parallel: this.parallel,
624
+ maxConcurrency: this.maxConcurrency,
625
+ timeout: this.timeout,
626
+ forceReinstall: this.forceReinstall,
627
+ skipVerification: this.skipVerification,
628
+ phases: [
629
+ {
630
+ name: 'Installation',
631
+ description: 'Install agents using available installers',
632
+ service: 'AgentInstallationService'
633
+ },
634
+ {
635
+ name: 'Verification',
636
+ description: 'Verify installed agents using configured tests',
637
+ service: 'AgentVerificationService'
638
+ }
639
+ ],
640
+ features: [
641
+ 'two-phase operation (install + verify)',
642
+ 'parallel processing',
643
+ 'error handling',
644
+ 'status tracking',
645
+ 'detailed logging',
646
+ 'progress reporting'
647
+ ],
648
+ limitations: [
649
+ 'depends on external installers',
650
+ 'verification test availability',
651
+ 'timeout affects all phases',
652
+ 'network dependency'
653
+ ]
654
+ };
655
+ }
656
+
657
+ /**
658
+ * Create check service with default configuration
659
+ * @param {Object} config - Configuration overrides
660
+ * @returns {AgentCheckService} - Service instance
661
+ */
662
+ static createDefault(config = {}) {
663
+ return new AgentCheckService({
664
+ parallel: true,
665
+ maxConcurrency: 2,
666
+ timeout: 600000,
667
+ forceReinstall: false,
668
+ skipVerification: false,
669
+ ...config
670
+ });
671
+ }
672
+
673
+ /**
674
+ * Create check service for sequential execution
675
+ * @param {Object} config - Configuration overrides
676
+ * @returns {AgentCheckService} - Sequential service instance
677
+ */
678
+ static createSequential(config = {}) {
679
+ return new AgentCheckService({
680
+ parallel: false,
681
+ maxConcurrency: 1,
682
+ timeout: 900000, // Longer timeout for sequential
683
+ forceReinstall: false,
684
+ skipVerification: false,
685
+ ...config
686
+ });
687
+ }
688
+ }
689
+
690
+ module.exports = AgentCheckService;