vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/package.json +1 -1
  2. package/src/agents/AgentCheckDiscoveryService.js +180 -0
  3. package/src/agents/AgentCheckService.js +18 -261
  4. package/src/agents/AgentCheckStatisticsService.js +195 -0
  5. package/src/agents/EnvironmentConfigurationManager.js +31 -380
  6. package/src/agents/InstallationType.js +19 -6
  7. package/src/agents/SimpleAgentCheckService.js +472 -0
  8. package/src/agents/config-managers/ConfigUtils.js +72 -0
  9. package/src/agents/config-managers/DefaultConfig.js +58 -0
  10. package/src/agents/config-managers/EnvVarLoader.js +66 -0
  11. package/src/agents/config-managers/FileConfigLoader.js +124 -0
  12. package/src/agents/config-managers/TypeConverters.js +61 -0
  13. package/src/agents/config-managers/VariableMappings.js +92 -0
  14. package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
  15. package/src/agents/discovery/AgentDiscoveryService.js +29 -403
  16. package/src/agents/discovery/agent-validator.js +262 -0
  17. package/src/agents/discovery/discovery-results.js +176 -0
  18. package/src/agents/discovery/discovery-scanner.js +268 -0
  19. package/src/agents/discovery/discovery-utils.js +161 -0
  20. package/src/agents/discovery/executable-analyzer.js +290 -0
  21. package/src/agents/discovery/history-manager.js +310 -0
  22. package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
  23. package/src/agents/verification/ResultAnalyzer.js +30 -431
  24. package/src/agents/verification/analysis-utils.js +310 -0
  25. package/src/agents/verification/batch-analyzer.js +440 -0
  26. package/src/agents/verification/pattern-recognizer.js +369 -0
  27. package/src/agents/verification/report-generator.js +320 -0
  28. package/src/agents/verification/test-analyzer.js +290 -0
  29. package/src/agents/windows/InstallerFactory.js +4 -0
  30. package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
  31. package/src/analysis/analysis-engine.js +314 -0
  32. package/src/analysis/ast-analyzer.js +342 -0
  33. package/src/analysis/boundary-detector-refactored.js +378 -0
  34. package/src/analysis/boundary-detector.js +200 -603
  35. package/src/analysis/boundary-scanner.js +609 -0
  36. package/src/analysis/boundary-types.js +118 -0
  37. package/src/analysis/boundary-utils.js +293 -0
  38. package/src/analysis/deadline-priority-calculator.js +18 -0
  39. package/src/analysis/detection-methods.js +347 -0
  40. package/src/analysis/importance-priority-calculator.js +18 -0
  41. package/src/analysis/priority/factor-calculators.js +204 -0
  42. package/src/analysis/priority/factor-helpers.js +71 -0
  43. package/src/analysis/priority/priority-constants.js +73 -0
  44. package/src/analysis/priority/priority-factor-calculators.js +301 -0
  45. package/src/analysis/priority/reasons-generator.js +44 -0
  46. package/src/analysis/priority-calculator.js +15 -580
  47. package/src/analysis/strategy-generator.js +16 -66
  48. package/src/analysis/type-priority-calculator.js +18 -0
  49. package/src/analysis/urgency-priority-calculator.js +18 -0
  50. package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
  51. package/src/commands/disable-requirement.js +60 -0
  52. package/src/commands/disable-spec.js +60 -0
  53. package/src/commands/enable-requirement.js +60 -0
  54. package/src/commands/enable-spec.js +60 -0
  55. package/src/commands/registry.js +1 -6
  56. package/src/commands/requirements.js +8 -2
  57. package/src/ide-integration/applescript-manager.cjs +9 -24
  58. package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
  59. package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
  60. package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
  61. package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
  62. package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
  63. package/src/ide-integration/cdp-manager.js +28 -573
  64. package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
  65. package/src/ide-integration/ide-openers/claude-opener.js +171 -0
  66. package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
  67. package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
  68. package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
  69. package/src/ide-integration/macos-ide-manager.js +20 -582
  70. package/src/ide-integration/macos-quota-checker.js +164 -0
  71. package/src/ide-integration/macos-text-sender.js +19 -38
  72. package/src/ide-integration/provider-manager.cjs +52 -7
  73. package/src/index.cjs +6 -0
  74. package/src/index.js +10 -0
  75. package/src/llm/direct-llm-manager.cjs +501 -0
  76. package/src/localization/translations/en-part1.js +363 -0
  77. package/src/localization/translations/en-part2.js +320 -0
  78. package/src/localization/translations/en.js +4 -687
  79. package/src/localization/translations/es-part1.js +363 -0
  80. package/src/localization/translations/es-part2.js +320 -0
  81. package/src/localization/translations/es.js +4 -688
  82. package/src/models/file-analysis-collection.js +139 -0
  83. package/src/models/file-analysis-metrics.js +50 -0
  84. package/src/models/file-analysis.js +15 -262
  85. package/src/models/plan-manager.js +410 -0
  86. package/src/models/refactoring-models.js +380 -0
  87. package/src/models/refactoring-plan-refactored.js +81 -0
  88. package/src/models/refactoring-plan.js +2 -663
  89. package/src/monitoring/alert-system.js +4 -45
  90. package/src/monitoring/continuous-scan-notifications.js +37 -191
  91. package/src/monitoring/notification-handlers/base-handler.js +58 -0
  92. package/src/monitoring/notification-handlers/error-handler.js +36 -0
  93. package/src/monitoring/notification-handlers/index.js +21 -0
  94. package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
  95. package/src/monitoring/notification-handlers/progress-handler.js +48 -0
  96. package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
  97. package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
  98. package/src/provider-registry.js +8 -0
  99. package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
  100. package/src/refactoring/boundary/boundary-detector.js +26 -596
  101. package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
  102. package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
  103. package/src/refactoring/boundary/detectors/class-detector.js +247 -0
  104. package/src/refactoring/boundary/detectors/config-detector.js +270 -0
  105. package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
  106. package/src/refactoring/boundary/detectors/function-detector.js +248 -0
  107. package/src/refactoring/boundary/detectors/module-detector.js +249 -0
  108. package/src/refactoring/boundary/detectors/object-detector.js +247 -0
  109. package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
  110. package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
  111. package/src/refactoring/circular-dependency-resolver-original.js +16 -76
  112. package/src/refactoring/code-mover-refactored.js +309 -0
  113. package/src/refactoring/code-mover.js +48 -355
  114. package/src/refactoring/execution-status.js +18 -0
  115. package/src/refactoring/execution-strategies.js +172 -0
  116. package/src/refactoring/file-splitter-core.js +568 -0
  117. package/src/refactoring/file-splitter-types.js +136 -0
  118. package/src/refactoring/file-splitter.js +2 -682
  119. package/src/refactoring/functionality-validator.js +11 -51
  120. package/src/refactoring/import-manager-refactored.js +385 -0
  121. package/src/refactoring/import-manager.js +112 -487
  122. package/src/refactoring/import-models.js +189 -0
  123. package/src/refactoring/import-parser.js +306 -0
  124. package/src/refactoring/move-executor.js +431 -0
  125. package/src/refactoring/move-utils.js +368 -0
  126. package/src/refactoring/operation-executor.js +76 -0
  127. package/src/refactoring/plan-creator.js +36 -0
  128. package/src/refactoring/plan-executor.js +143 -0
  129. package/src/refactoring/plan-validator.js +68 -0
  130. package/src/refactoring/refactoring-executor-result.js +70 -0
  131. package/src/refactoring/refactoring-executor.js +34 -569
  132. package/src/refactoring/refactoring-operation.js +94 -0
  133. package/src/refactoring/refactoring-plan.js +69 -0
  134. package/src/refactoring/refactoring-rollback.js +22 -527
  135. package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
  136. package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
  137. package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
  138. package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
  139. package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
  140. package/src/refactoring/test-validator.js +32 -448
  141. package/src/refactoring/validation/baseline-runner.js +71 -0
  142. package/src/refactoring/validation/report-generator.js +136 -0
  143. package/src/refactoring/validation/result-comparator.js +92 -0
  144. package/src/refactoring/validation/test-suite.js +59 -0
  145. package/src/refactoring/validation/test-validation-result.js +83 -0
  146. package/src/refactoring/validation/validation-runner.js +95 -0
  147. package/src/refactoring/validation/validation-status.js +18 -0
  148. package/src/rui/commands/AgentCommandParser.js +60 -369
  149. package/src/rui/commands/AgentResponseFormatter.js +7 -47
  150. package/src/rui/commands/parsers/CommandMapper.js +148 -0
  151. package/src/rui/commands/parsers/CommandValidator.js +228 -0
  152. package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
  153. package/src/rui/commands/parsers/TokenParser.js +69 -0
  154. package/src/rui/commands/parsers/tokenizer.js +153 -0
  155. package/src/utils/current-requirement-operations.js +50 -1
  156. package/src/utils/report-generator.js +18 -514
  157. package/src/utils/report-generators/analysis-generator.js +115 -0
  158. package/src/utils/report-generators/base-generator.js +141 -0
  159. package/src/utils/report-generators/compliance-generator.js +41 -0
  160. package/src/utils/report-generators/format-handlers.js +185 -0
  161. package/src/utils/report-generators/refactoring-generator.js +46 -0
  162. package/src/utils/report-generators/validation-generator.js +63 -0
  163. package/src/utils/requirement-enable-disable.js +265 -0
  164. package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
  165. package/src/utils/requirement-helpers/requirement-mover.js +88 -1
  166. package/src/utils/requirement-helpers.js +5 -2
  167. package/src/utils/smoke-test-cli.js +45 -8
  168. package/src/utils/specification-enable-disable.js +122 -0
  169. package/src/utils/specification-helpers.js +30 -4
  170. package/src/utils/specification-migration.js +5 -5
  171. package/src/utils/test-comparator.js +118 -0
  172. package/src/utils/test-config.js +54 -0
  173. package/src/utils/test-executor.js +133 -0
  174. package/src/utils/test-parser.js +215 -0
  175. package/src/utils/test-runner-baseline.js +63 -0
  176. package/src/utils/test-runner-core.js +98 -0
  177. package/src/utils/test-runner-report.js +39 -0
  178. package/src/utils/test-runner-validation.js +71 -0
  179. package/src/utils/test-runner.js +11 -535
  180. package/src/validation/comparison-analyzer.js +333 -0
  181. package/src/validation/compliance-reporter-new.js +282 -0
  182. package/src/validation/compliance-reporter-refactored.js +344 -0
  183. package/src/validation/compliance-reporter.js +278 -591
  184. package/src/validation/compliance-utils.js +278 -0
  185. package/src/validation/html-generator.js +446 -0
  186. package/src/validation/metrics/category-calculator.js +137 -0
  187. package/src/validation/metrics/metrics-helpers.js +155 -0
  188. package/src/validation/metrics/overview-calculator.js +85 -0
  189. package/src/validation/metrics/overview-metrics.js +41 -0
  190. package/src/validation/metrics/quality-calculator.js +166 -0
  191. package/src/validation/metrics/size-calculator.js +69 -0
  192. package/src/validation/metrics-calculator.js +27 -551
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibecodingmachine-core",
3
- "version": "2026.02.26-1739",
3
+ "version": "2026.03.09-0850",
4
4
  "description": "Shared core logic for Vibe Coding Machine IDE integration",
5
5
  "main": "src/index.cjs",
6
6
  "module": "src/index.js",
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Agent Check Discovery Service
3
+ *
4
+ * Handles agent discovery integration with check operations.
5
+ * Constitutional requirement: <555 lines, test-first approach.
6
+ */
7
+
8
+ const AgentDiscoveryService = require('./discovery/AgentDiscoveryService');
9
+
10
+ /**
11
+ * Agent check discovery service
12
+ */
13
+ class AgentCheckDiscoveryService {
14
+ /**
15
+ * Create discovery service instance
16
+ * @param {Object} config - Service configuration
17
+ */
18
+ constructor(config = {}) {
19
+ this.configManager = config.configManager || null;
20
+ this.logger = config.logger || null;
21
+ this.fileManager = config.fileManager || null;
22
+
23
+ this.discoveryService = new AgentDiscoveryService({
24
+ configManager: this.configManager,
25
+ logger: this.logger,
26
+ fileManager: this.fileManager,
27
+ ...config.discovery
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Discover new agents in the system
33
+ * @param {Object} options - Discovery options
34
+ * @returns {Promise<Object>} - Discovery results
35
+ */
36
+ async discoverAgents(options = {}) {
37
+ try {
38
+ if (this.logger) {
39
+ await this.logger.info('Starting agent discovery', options);
40
+ }
41
+
42
+ const discoveryOptions = {
43
+ includeDisabled: options.includeDisabled || false,
44
+ scanSystem: options.scanSystem !== false,
45
+ scanConfigFiles: options.scanConfigFiles !== false,
46
+ timeout: options.timeout || 300000, // 5 minutes
47
+ ...options
48
+ };
49
+
50
+ const discoveryResult = await this.discoveryService.discoverAgents(discoveryOptions);
51
+
52
+ if (this.logger) {
53
+ await this.logger.info('Agent discovery completed', {
54
+ discoveredCount: discoveryResult.discovered?.length || 0,
55
+ newCount: discoveryResult.new?.length || 0,
56
+ existingCount: discoveryResult.existing?.length || 0
57
+ });
58
+ }
59
+
60
+ return {
61
+ success: true,
62
+ ...discoveryResult,
63
+ message: `Discovered ${discoveryResult.discovered?.length || 0} agents (${discoveryResult.new?.length || 0} new)`
64
+ };
65
+
66
+ } catch (error) {
67
+ if (this.logger) {
68
+ await this.logger.error('Agent discovery failed', { error: error.message });
69
+ }
70
+
71
+ return {
72
+ success: false,
73
+ error: error.message,
74
+ message: 'Agent discovery failed'
75
+ };
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Check agents with discovery (discover + install + verify)
81
+ * @param {Object} options - Check options with discovery
82
+ * @param {Function} checkAgentsFn - Function to perform agent check
83
+ * @returns {Promise<Object>} - Combined check and discovery results
84
+ */
85
+ async checkAgentsWithDiscovery(options = {}, checkAgentsFn) {
86
+ const {
87
+ runDiscovery = true,
88
+ addDiscovered = false,
89
+ ...checkOptions
90
+ } = options;
91
+
92
+ try {
93
+ const startTime = Date.now();
94
+ const results = {
95
+ discovery: null,
96
+ check: null,
97
+ summary: {
98
+ totalDuration: 0,
99
+ discoverySuccessful: false,
100
+ checkSuccessful: false,
101
+ newAgentsDiscovered: 0,
102
+ agentsChecked: 0
103
+ }
104
+ };
105
+
106
+ // Phase 0: Discovery (if requested)
107
+ if (runDiscovery) {
108
+ if (this.logger) {
109
+ await this.logger.info('Phase 0: Agent Discovery');
110
+ }
111
+
112
+ const discoveryOptions = {
113
+ includeDisabled: false,
114
+ scanSystem: true,
115
+ scanConfigFiles: true,
116
+ timeout: Math.floor((checkOptions.timeout || 600000) * 0.2), // 20% of time for discovery
117
+ ...options.discovery
118
+ };
119
+
120
+ results.discovery = await this.discoverAgents(discoveryOptions);
121
+ results.summary.discoverySuccessful = results.discovery.success;
122
+ results.summary.newAgentsDiscovered = results.discovery.new?.length || 0;
123
+
124
+ // Add discovered agents if requested
125
+ if (addDiscovered && results.discovery.new?.length > 0) {
126
+ if (this.logger) {
127
+ await this.logger.info(`Adding ${results.discovery.new.length} discovered agents`);
128
+ }
129
+
130
+ // Note: This would require AgentAdditionService integration
131
+ // For now, just log the discovered agents
132
+ for (const agent of results.discovery.new) {
133
+ if (this.logger) {
134
+ await this.logger.info(`Discovered new agent: ${agent.id} (${agent.name})`);
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ // Phase 1+: Regular agent check
141
+ if (this.logger) {
142
+ await this.logger.info('Phase 1+: Agent Check (Install + Verify)');
143
+ }
144
+
145
+ results.check = await checkAgentsFn(checkOptions);
146
+ results.summary.checkSuccessful = results.check.summary?.allSuccessful || false;
147
+ results.summary.agentsChecked = results.check.totalAgents || 0;
148
+
149
+ results.summary.totalDuration = Date.now() - startTime;
150
+
151
+ return {
152
+ success: results.summary.discoverySuccessful && results.summary.checkSuccessful,
153
+ ...results,
154
+ message: `Completed: ${results.summary.newAgentsDiscovered} new agents discovered, ${results.summary.agentsChecked} agents checked`
155
+ };
156
+
157
+ } catch (error) {
158
+ if (this.logger) {
159
+ await this.logger.error('Check agents with discovery failed', { error: error.message });
160
+ }
161
+
162
+ return {
163
+ success: false,
164
+ error: error.message,
165
+ message: 'Check agents with discovery failed'
166
+ };
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Create discovery service with default configuration
172
+ * @param {Object} config - Configuration overrides
173
+ * @returns {AgentCheckDiscoveryService} - Service instance
174
+ */
175
+ static createDefault(config = {}) {
176
+ return new AgentCheckDiscoveryService(config);
177
+ }
178
+ }
179
+
180
+ module.exports = AgentCheckDiscoveryService;
@@ -8,7 +8,8 @@
8
8
  const AgentInstallationService = require('./AgentInstallationService');
9
9
  const AgentVerificationService = require('./AgentVerificationService');
10
10
  const AgentSetupService = require('./AgentSetupService');
11
- const AgentDiscoveryService = require('./discovery/AgentDiscoveryService');
11
+ const AgentCheckDiscoveryService = require('./AgentCheckDiscoveryService');
12
+ const AgentCheckStatisticsService = require('./AgentCheckStatisticsService');
12
13
  const { AgentStatus } = require('./AgentStatus');
13
14
 
14
15
  /**
@@ -44,13 +45,20 @@ class AgentCheckService {
44
45
  ...config.setup
45
46
  });
46
47
 
47
- this.discoveryService = new AgentDiscoveryService({
48
+ this.discoveryService = AgentCheckDiscoveryService.createDefault({
48
49
  configManager: this.configManager,
49
50
  logger: this.logger,
50
51
  fileManager: this.fileManager,
51
52
  ...config.discovery
52
53
  });
53
54
 
55
+ this.statisticsService = AgentCheckStatisticsService.createDefault({
56
+ configManager: this.configManager,
57
+ logger: this.logger,
58
+ fileManager: this.fileManager,
59
+ ...config.statistics
60
+ });
61
+
54
62
  // Service configuration
55
63
  this.parallel = config.parallel !== false;
56
64
  this.maxConcurrency = config.maxConcurrency || 2;
@@ -320,78 +328,7 @@ class AgentCheckService {
320
328
  * @returns {Promise<Object>} - Check statistics
321
329
  */
322
330
  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
- }
331
+ return this.statisticsService.getCheckStatistics();
395
332
  }
396
333
 
397
334
  /**
@@ -400,53 +337,7 @@ class AgentCheckService {
400
337
  * @returns {Promise<Object>} - Detailed agent status
401
338
  */
402
339
  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
- }
340
+ return this.statisticsService.getDetailedAgentStatus(agentId);
450
341
  }
451
342
 
452
343
  /**
@@ -456,24 +347,7 @@ class AgentCheckService {
456
347
  * @returns {Promise<Array>} - Status history
457
348
  */
458
349
  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
- }
350
+ return this.statisticsService.getStatusHistory(agentId, limit);
477
351
  }
478
352
 
479
353
  /**
@@ -482,46 +356,7 @@ class AgentCheckService {
482
356
  * @returns {Promise<Object>} - Discovery results
483
357
  */
484
358
  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
- }
359
+ return this.discoveryService.discoverAgents(options);
525
360
  }
526
361
 
527
362
  /**
@@ -530,88 +365,10 @@ class AgentCheckService {
530
365
  * @returns {Promise<Object>} - Combined check and discovery results
531
366
  */
532
367
  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
- }
368
+ return this.discoveryService.checkAgentsWithDiscovery(
369
+ options,
370
+ (checkOptions) => this.checkAgents(checkOptions)
371
+ );
615
372
  }
616
373
 
617
374
  /**
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Agent Check Statistics Service
3
+ *
4
+ * Handles statistics and status tracking for agent checks.
5
+ * Constitutional requirement: <555 lines, test-first approach.
6
+ */
7
+
8
+ const { AgentStatus } = require('./AgentStatus');
9
+
10
+ /**
11
+ * Agent check statistics service
12
+ */
13
+ class AgentCheckStatisticsService {
14
+ /**
15
+ * Create statistics service instance
16
+ * @param {Object} config - Service configuration
17
+ */
18
+ constructor(config = {}) {
19
+ this.configManager = config.configManager || null;
20
+ this.logger = config.logger || null;
21
+ this.fileManager = config.fileManager || null;
22
+ }
23
+
24
+ /**
25
+ * Get check operation statistics
26
+ * @returns {Promise<Object>} - Check statistics
27
+ */
28
+ async getCheckStatistics() {
29
+ try {
30
+ const agents = this.configManager.getEnabledAgents();
31
+
32
+ const stats = {
33
+ totalAgents: agents.length,
34
+ verified: 0,
35
+ notVerified: 0,
36
+ error: 0,
37
+ installing: 0,
38
+ lastCheck: null,
39
+ checkRate: 0
40
+ };
41
+
42
+ let latestCheck = null;
43
+
44
+ for (const agent of agents) {
45
+ const status = await this.configManager.getAgentStatus(agent.id);
46
+
47
+ if (status) {
48
+ switch (status.status) {
49
+ case AgentStatus.VERIFIED:
50
+ stats.verified++;
51
+ break;
52
+ case AgentStatus.NOT_INSTALLED:
53
+ case AgentStatus.INSTALLED:
54
+ stats.notVerified++;
55
+ break;
56
+ case AgentStatus.ERROR:
57
+ stats.error++;
58
+ break;
59
+ case AgentStatus.INSTALLING:
60
+ stats.installing++;
61
+ break;
62
+ }
63
+
64
+ // Track latest check
65
+ if (status.lastChecked) {
66
+ const checkDate = new Date(status.lastChecked);
67
+ if (!latestCheck || checkDate > latestCheck) {
68
+ latestCheck = status.lastChecked;
69
+ }
70
+ }
71
+ } else {
72
+ stats.notVerified++;
73
+ }
74
+ }
75
+
76
+ stats.lastCheck = latestCheck ? latestCheck.toISOString() : null;
77
+
78
+ // Calculate check rate (agents that have been checked at least once)
79
+ const checkedAgents = stats.verified + stats.notVerified + stats.error;
80
+ stats.checkRate = agents.length > 0 ? (checkedAgents / agents.length) * 100 : 0;
81
+
82
+ return stats;
83
+ } catch (error) {
84
+ if (this.logger) {
85
+ await this.logger.error('Failed to get check statistics', {
86
+ error: error.message
87
+ });
88
+ }
89
+
90
+ return {
91
+ totalAgents: 0,
92
+ verified: 0,
93
+ notVerified: 0,
94
+ error: 0,
95
+ installing: 0,
96
+ lastCheck: null,
97
+ checkRate: 0,
98
+ error: error.message
99
+ };
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Get detailed agent status
105
+ * @param {string} agentId - Agent identifier
106
+ * @returns {Promise<Object>} - Detailed agent status
107
+ */
108
+ async getDetailedAgentStatus(agentId) {
109
+ try {
110
+ const agent = this.configManager.getAgent(agentId);
111
+ if (!agent) {
112
+ return {
113
+ agentId,
114
+ found: false,
115
+ error: 'Agent not found'
116
+ };
117
+ }
118
+
119
+ const status = await this.configManager.getAgentStatus(agentId);
120
+ const history = await this.getStatusHistory(agentId, 10);
121
+
122
+ return {
123
+ agentId,
124
+ found: true,
125
+ agent: {
126
+ id: agent.id,
127
+ name: agent.name,
128
+ description: agent.description,
129
+ enabled: agent.enabled,
130
+ status: status ? status.status : AgentStatus.NOT_INSTALLED,
131
+ lastChecked: status ? status.lastChecked : null,
132
+ lastVerified: status ? status.lastVerified : null,
133
+ message: status ? status.message : '',
134
+ installationMethods: agent.installationMethods,
135
+ verificationCommands: agent.verificationCommands
136
+ },
137
+ status,
138
+ history,
139
+ canInstall: agent.enabled && status ? status.status === AgentStatus.NOT_INSTALLED : false,
140
+ canVerify: agent.enabled && status ? [AgentStatus.INSTALLED, AgentStatus.VERIFIED].includes(status.status) : false
141
+ };
142
+ } catch (error) {
143
+ if (this.logger) {
144
+ await this.logger.error('Failed to get detailed agent status', {
145
+ agentId,
146
+ error: error.message
147
+ });
148
+ }
149
+
150
+ return {
151
+ agentId,
152
+ found: false,
153
+ error: error.message
154
+ };
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Get status history for an agent
160
+ * @param {string} agentId - Agent identifier
161
+ * @param {number} limit - Maximum entries
162
+ * @returns {Promise<Array>} - Status history
163
+ */
164
+ async getStatusHistory(agentId, limit = 50) {
165
+ try {
166
+ if (this.fileManager) {
167
+ const logs = await this.fileManager.readLogs('status-change', { limit });
168
+ return logs
169
+ .filter(log => log.agentId === agentId)
170
+ .slice(-limit)
171
+ .reverse(); // Most recent first
172
+ }
173
+ return [];
174
+ } catch (error) {
175
+ if (this.logger) {
176
+ await this.logger.error('Failed to get status history', {
177
+ agentId,
178
+ error: error.message
179
+ });
180
+ }
181
+ return [];
182
+ }
183
+ }
184
+
185
+ /**
186
+ * Create statistics service with default configuration
187
+ * @param {Object} config - Configuration overrides
188
+ * @returns {AgentCheckStatisticsService} - Service instance
189
+ */
190
+ static createDefault(config = {}) {
191
+ return new AgentCheckStatisticsService(config);
192
+ }
193
+ }
194
+
195
+ module.exports = AgentCheckStatisticsService;