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.
- package/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Continuous Scan Integration with Task Management
|
|
3
|
+
*
|
|
4
|
+
* Integrates the continuous scanner with the task management system
|
|
5
|
+
* to automatically create and track refactoring tasks.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { EventEmitter } = require('events');
|
|
11
|
+
|
|
12
|
+
const { ViolationPrioritizer } = require('../task-generation/prioritizer');
|
|
13
|
+
const { TaskListUpdater } = require('../task-generation/task-list-updater');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Continuous Scan Integration
|
|
17
|
+
*/
|
|
18
|
+
class ContinuousScanIntegration extends EventEmitter {
|
|
19
|
+
constructor(options = {}) {
|
|
20
|
+
super();
|
|
21
|
+
|
|
22
|
+
this.options = {
|
|
23
|
+
tasksFilePath: options.tasksFilePath || './specs/010-555-max-file-size/tasks.md',
|
|
24
|
+
autoCreateTasks: options.autoCreateTasks !== false,
|
|
25
|
+
maxTasksPerScan: options.maxTasksPerScan || 10,
|
|
26
|
+
taskTemplate: options.taskTemplate || this._getDefaultTaskTemplate(),
|
|
27
|
+
...options
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
this.prioritizer = new ViolationPrioritizer();
|
|
31
|
+
this.taskUpdater = new TaskListUpdater();
|
|
32
|
+
this.createdTasks = new Map();
|
|
33
|
+
this.lastScanResults = null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Initialize integration with scanner
|
|
38
|
+
*/
|
|
39
|
+
initialize(scanner) {
|
|
40
|
+
this.scanner = scanner;
|
|
41
|
+
|
|
42
|
+
// Setup event handlers
|
|
43
|
+
scanner.on('scan_completed', (data) => {
|
|
44
|
+
this._handleScanCompleted(data);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
scanner.on('violations_found', (data) => {
|
|
48
|
+
this._handleViolationsFound(data);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
this.emit('initialized');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Handle scan completion
|
|
56
|
+
*/
|
|
57
|
+
async _handleScanCompleted(data) {
|
|
58
|
+
this.lastScanResults = data;
|
|
59
|
+
|
|
60
|
+
if (this.options.autoCreateTasks && data.violations.length > 0) {
|
|
61
|
+
await this._createTasksForViolations(data.violations);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.emit('scan_processed', {
|
|
65
|
+
timestamp: data.timestamp,
|
|
66
|
+
violationsCount: data.violations.length,
|
|
67
|
+
tasksCreated: this.createdTasks.size
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Handle violations found
|
|
73
|
+
*/
|
|
74
|
+
async _handleViolationsFound(data) {
|
|
75
|
+
const prioritizedViolations = this.prioritizer.prioritizeViolations(data.violations);
|
|
76
|
+
const topViolations = prioritizedViolations.slice(0, this.options.maxTasksPerScan);
|
|
77
|
+
|
|
78
|
+
if (topViolations.length > 0) {
|
|
79
|
+
await this._createTasksForViolations(topViolations);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Create tasks for violations
|
|
85
|
+
*/
|
|
86
|
+
async _createTasksForViolations(violations) {
|
|
87
|
+
const tasks = [];
|
|
88
|
+
|
|
89
|
+
for (const violation of violations) {
|
|
90
|
+
const task = this._createTaskForViolation(violation);
|
|
91
|
+
if (task) {
|
|
92
|
+
tasks.push(task);
|
|
93
|
+
this.createdTasks.set(violation.file, task);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (tasks.length > 0) {
|
|
98
|
+
await this._addTasksToTaskList(tasks);
|
|
99
|
+
this.emit('tasks_created', { count: tasks.length, tasks });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Create task for a single violation
|
|
105
|
+
*/
|
|
106
|
+
_createTaskForViolation(violation) {
|
|
107
|
+
const taskId = this._generateTaskId(violation);
|
|
108
|
+
const story = this._determineUserStory(violation);
|
|
109
|
+
const priority = this._determinePriority(violation);
|
|
110
|
+
|
|
111
|
+
// Skip if task already exists
|
|
112
|
+
if (this._taskExists(taskId)) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const task = {
|
|
117
|
+
id: taskId,
|
|
118
|
+
priority: priority ? '[P]' : '',
|
|
119
|
+
story: story,
|
|
120
|
+
description: this._generateTaskDescription(violation),
|
|
121
|
+
filePath: violation.file,
|
|
122
|
+
lineCount: this._getLineCount(violation),
|
|
123
|
+
violationCount: violation.violations.length,
|
|
124
|
+
violations: violation.violations,
|
|
125
|
+
createdAt: new Date().toISOString()
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return task;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Generate task ID
|
|
133
|
+
*/
|
|
134
|
+
_generateTaskId(violation) {
|
|
135
|
+
const fileName = path.basename(violation.file, path.extname(violation.file));
|
|
136
|
+
const sanitized = fileName.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
|
|
137
|
+
return `T${Date.now()}-${sanitized}`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Determine user story
|
|
142
|
+
*/
|
|
143
|
+
_determineUserStory(violation) {
|
|
144
|
+
// Based on violation type and file location
|
|
145
|
+
if (violation.file.includes('/core/')) {
|
|
146
|
+
return '[US2]'; // User Story 2 - Modular Refactoring
|
|
147
|
+
} else if (violation.file.includes('/cli/') || violation.file.includes('/electron-app/')) {
|
|
148
|
+
return '[US2]'; // User Story 2 - Modular Refactoring
|
|
149
|
+
} else {
|
|
150
|
+
return '[US2]'; // Default to User Story 2
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Determine if task can run in parallel
|
|
156
|
+
*/
|
|
157
|
+
_determinePriority(violation) {
|
|
158
|
+
// Tasks can run in parallel if they're in different files
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Generate task description
|
|
164
|
+
*/
|
|
165
|
+
_generateTaskDescription(violation) {
|
|
166
|
+
const lineCount = this._getLineCount(violation);
|
|
167
|
+
const violationTypes = this._getViolationTypes(violation);
|
|
168
|
+
|
|
169
|
+
let description = `Refactor ${path.basename(violation.file)} (${lineCount} lines)`;
|
|
170
|
+
|
|
171
|
+
if (violationTypes.length > 0) {
|
|
172
|
+
description += ` - fix ${violationTypes.join(', ')}`;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return description;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Get line count from violation
|
|
180
|
+
*/
|
|
181
|
+
_getLineCount(violation) {
|
|
182
|
+
if (violation.violations) {
|
|
183
|
+
const sizeViolation = violation.violations.find(v => v.rule === 'maxFileSize');
|
|
184
|
+
if (sizeViolation && sizeViolation.line) {
|
|
185
|
+
return sizeViolation.line;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get violation types
|
|
193
|
+
*/
|
|
194
|
+
_getViolationTypes(violation) {
|
|
195
|
+
const types = new Set();
|
|
196
|
+
|
|
197
|
+
if (violation.violations) {
|
|
198
|
+
violation.violations.forEach(v => {
|
|
199
|
+
switch (v.rule) {
|
|
200
|
+
case 'maxFileSize':
|
|
201
|
+
types.add('file size limit');
|
|
202
|
+
break;
|
|
203
|
+
case 'noTrailingWhitespace':
|
|
204
|
+
types.add('trailing whitespace');
|
|
205
|
+
break;
|
|
206
|
+
case 'fileEndsWithNewline':
|
|
207
|
+
types.add('missing newline');
|
|
208
|
+
break;
|
|
209
|
+
case 'maxLineLength':
|
|
210
|
+
types.add('long lines');
|
|
211
|
+
break;
|
|
212
|
+
default:
|
|
213
|
+
types.add(v.rule);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return Array.from(types);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Check if task already exists
|
|
223
|
+
*/
|
|
224
|
+
_taskExists(taskId) {
|
|
225
|
+
try {
|
|
226
|
+
if (!fs.existsSync(this.options.tasksFilePath)) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const content = fs.readFileSync(this.options.tasksFilePath, 'utf8');
|
|
231
|
+
return content.includes(taskId);
|
|
232
|
+
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error('Error checking if task exists:', error.message);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Add tasks to task list
|
|
241
|
+
*/
|
|
242
|
+
async _addTasksToTaskList(tasks) {
|
|
243
|
+
try {
|
|
244
|
+
await this.taskUpdater.addTasks(this.options.tasksFilePath, tasks);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error('Failed to add tasks to task list:', error.message);
|
|
247
|
+
this.emit('error', error);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get integration status
|
|
253
|
+
*/
|
|
254
|
+
getStatus() {
|
|
255
|
+
return {
|
|
256
|
+
createdTasks: this.createdTasks.size,
|
|
257
|
+
lastScanResults: this.lastScanResults,
|
|
258
|
+
options: this.options
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get created tasks
|
|
264
|
+
*/
|
|
265
|
+
getCreatedTasks() {
|
|
266
|
+
return Array.from(this.createdTasks.entries()).map(([file, task]) => ({
|
|
267
|
+
file,
|
|
268
|
+
task
|
|
269
|
+
}));
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Clear created tasks cache
|
|
274
|
+
*/
|
|
275
|
+
clearCache() {
|
|
276
|
+
this.createdTasks.clear();
|
|
277
|
+
this.lastScanResults = null;
|
|
278
|
+
this.emit('cache_cleared');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Get default task template
|
|
283
|
+
*/
|
|
284
|
+
_getDefaultTaskTemplate() {
|
|
285
|
+
return `- [ ] {taskId} {priority} {story} {description}`;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Generate integration report
|
|
290
|
+
*/
|
|
291
|
+
generateReport() {
|
|
292
|
+
const createdTasks = this.getCreatedTasks();
|
|
293
|
+
const status = this.getStatus();
|
|
294
|
+
|
|
295
|
+
return {
|
|
296
|
+
timestamp: new Date().toISOString(),
|
|
297
|
+
summary: {
|
|
298
|
+
totalTasksCreated: createdTasks.length,
|
|
299
|
+
lastScanAt: status.lastScanResults?.timestamp || null,
|
|
300
|
+
autoCreateTasksEnabled: this.options.autoCreateTasks
|
|
301
|
+
},
|
|
302
|
+
tasks: createdTasks,
|
|
303
|
+
recommendations: this._generateIntegrationRecommendations()
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Generate integration recommendations
|
|
309
|
+
*/
|
|
310
|
+
_generateIntegrationRecommendations() {
|
|
311
|
+
const recommendations = [];
|
|
312
|
+
|
|
313
|
+
if (this.createdTasks.size === 0) {
|
|
314
|
+
recommendations.push({
|
|
315
|
+
type: 'info',
|
|
316
|
+
title: 'No Tasks Created',
|
|
317
|
+
description: 'No refactoring tasks have been created yet',
|
|
318
|
+
action: 'Wait for the next scan or check scanner configuration'
|
|
319
|
+
});
|
|
320
|
+
} else {
|
|
321
|
+
recommendations.push({
|
|
322
|
+
type: 'action',
|
|
323
|
+
title: 'Review Created Tasks',
|
|
324
|
+
description: `${this.createdTasks.size} tasks have been created`,
|
|
325
|
+
action: 'Review the tasks.md file and prioritize implementation'
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (!this.options.autoCreateTasks) {
|
|
330
|
+
recommendations.push({
|
|
331
|
+
type: 'suggestion',
|
|
332
|
+
title: 'Enable Auto Task Creation',
|
|
333
|
+
description: 'Automatic task creation is currently disabled',
|
|
334
|
+
action: 'Enable autoCreateTasks option to streamline workflow'
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return recommendations;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
module.exports = { ContinuousScanIntegration };
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Timeout Management Module
|
|
3
|
+
*
|
|
4
|
+
* Provides adaptive timeout calculation and management for IDE interactions.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { TimeoutCalculator } = require('./timeout-calculator');
|
|
8
|
+
const { TimeoutConfigManager } = require('./timeout-config-manager');
|
|
9
|
+
const { ResponseTimeTracker } = require('./response-time-tracker');
|
|
3
10
|
|
|
4
11
|
module.exports = {
|
|
5
|
-
|
|
12
|
+
TimeoutCalculator,
|
|
13
|
+
TimeoutConfigManager,
|
|
14
|
+
ResponseTimeTracker
|
|
6
15
|
};
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResponseTimeTracker
|
|
3
|
+
*
|
|
4
|
+
* Maintains response time samples for an IDE and provides statistical analysis
|
|
5
|
+
* including mean, median, standard deviation, and trend detection.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const EventEmitter = require('events');
|
|
9
|
+
|
|
10
|
+
class ResponseTimeTracker extends EventEmitter {
|
|
11
|
+
/**
|
|
12
|
+
* Create response time tracker
|
|
13
|
+
* @param {string} ideId - IDE identifier
|
|
14
|
+
* @param {Object} [options] - Tracker options
|
|
15
|
+
* @param {number} [options.maxSamples=50] - Maximum samples to keep
|
|
16
|
+
*/
|
|
17
|
+
constructor(ideId, options = {}) {
|
|
18
|
+
super();
|
|
19
|
+
|
|
20
|
+
this.ideId = ideId;
|
|
21
|
+
this.maxSamples = options.maxSamples || 50;
|
|
22
|
+
this.samples = [];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Add response time sample
|
|
27
|
+
* @param {number} responseTime - Response time in milliseconds
|
|
28
|
+
*/
|
|
29
|
+
addSample(responseTime) {
|
|
30
|
+
if (responseTime < 0) {
|
|
31
|
+
throw new Error('Response time must be non-negative');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
this.samples.push(responseTime);
|
|
35
|
+
|
|
36
|
+
// Maintain max samples limit
|
|
37
|
+
if (this.samples.length > this.maxSamples) {
|
|
38
|
+
this.samples.shift(); // Remove oldest
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
this.emit('sample-added', responseTime);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get all samples
|
|
46
|
+
* @returns {number[]} Copy of samples array
|
|
47
|
+
*/
|
|
48
|
+
getSamples() {
|
|
49
|
+
return [...this.samples];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get recent N samples
|
|
54
|
+
* @param {number} n - Number of recent samples to get
|
|
55
|
+
* @returns {number[]} Recent samples
|
|
56
|
+
*/
|
|
57
|
+
getRecentSamples(n) {
|
|
58
|
+
if (n >= this.samples.length) {
|
|
59
|
+
return [...this.samples];
|
|
60
|
+
}
|
|
61
|
+
return this.samples.slice(-n);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get statistical analysis of samples
|
|
66
|
+
* @returns {Object} Statistics object
|
|
67
|
+
*/
|
|
68
|
+
getStatistics() {
|
|
69
|
+
if (this.samples.length === 0) {
|
|
70
|
+
return {
|
|
71
|
+
sampleCount: 0,
|
|
72
|
+
mean: null,
|
|
73
|
+
median: null,
|
|
74
|
+
stdDev: null,
|
|
75
|
+
min: null,
|
|
76
|
+
max: null
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Calculate mean
|
|
81
|
+
const sum = this.samples.reduce((acc, val) => acc + val, 0);
|
|
82
|
+
const mean = sum / this.samples.length;
|
|
83
|
+
|
|
84
|
+
// Calculate median
|
|
85
|
+
const sorted = [...this.samples].sort((a, b) => a - b);
|
|
86
|
+
let median;
|
|
87
|
+
const mid = Math.floor(sorted.length / 2);
|
|
88
|
+
if (sorted.length % 2 === 0) {
|
|
89
|
+
median = (sorted[mid - 1] + sorted[mid]) / 2;
|
|
90
|
+
} else {
|
|
91
|
+
median = sorted[mid];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Calculate standard deviation
|
|
95
|
+
const variance = this.samples.reduce((acc, val) => {
|
|
96
|
+
const diff = val - mean;
|
|
97
|
+
return acc + (diff * diff);
|
|
98
|
+
}, 0) / this.samples.length;
|
|
99
|
+
const stdDev = Math.sqrt(variance);
|
|
100
|
+
|
|
101
|
+
// Min and max
|
|
102
|
+
const min = Math.min(...this.samples);
|
|
103
|
+
const max = Math.max(...this.samples);
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
sampleCount: this.samples.length,
|
|
107
|
+
mean,
|
|
108
|
+
median,
|
|
109
|
+
stdDev,
|
|
110
|
+
min,
|
|
111
|
+
max
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Detect trend in response times
|
|
117
|
+
* @returns {string|null} Trend ('increasing', 'decreasing', 'stable') or null
|
|
118
|
+
*/
|
|
119
|
+
detectTrend() {
|
|
120
|
+
// Need at least 5 samples for trend detection
|
|
121
|
+
if (this.samples.length < 5) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Use simple linear regression to detect trend
|
|
126
|
+
const n = this.samples.length;
|
|
127
|
+
let sumX = 0;
|
|
128
|
+
let sumY = 0;
|
|
129
|
+
let sumXY = 0;
|
|
130
|
+
let sumX2 = 0;
|
|
131
|
+
|
|
132
|
+
for (let i = 0; i < n; i++) {
|
|
133
|
+
const x = i;
|
|
134
|
+
const y = this.samples[i];
|
|
135
|
+
sumX += x;
|
|
136
|
+
sumY += y;
|
|
137
|
+
sumXY += x * y;
|
|
138
|
+
sumX2 += x * x;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Calculate slope
|
|
142
|
+
const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
|
143
|
+
|
|
144
|
+
// Calculate mean for threshold
|
|
145
|
+
const mean = sumY / n;
|
|
146
|
+
const threshold = mean * 0.05; // 5% of mean
|
|
147
|
+
|
|
148
|
+
// Determine trend based on slope
|
|
149
|
+
if (slope > threshold) {
|
|
150
|
+
return 'increasing';
|
|
151
|
+
} else if (slope < -threshold) {
|
|
152
|
+
return 'decreasing';
|
|
153
|
+
} else {
|
|
154
|
+
return 'stable';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Clear all samples
|
|
160
|
+
*/
|
|
161
|
+
clear() {
|
|
162
|
+
this.samples = [];
|
|
163
|
+
this.emit('samples-cleared');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = { ResponseTimeTracker };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TimeoutCalculator
|
|
3
|
+
*
|
|
4
|
+
* Provides static methods for calculating adaptive timeouts based on
|
|
5
|
+
* historical response times using EWMA (Exponentially Weighted Moving Average).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class TimeoutCalculator {
|
|
9
|
+
/**
|
|
10
|
+
* Calculate timeout value based on EWMA and buffer percentage
|
|
11
|
+
* @param {Object} options - Calculation options
|
|
12
|
+
* @param {number|null} options.ewma - Current EWMA value (null for fixed mode)
|
|
13
|
+
* @param {number} options.defaultTimeout - Default timeout to use when no EWMA
|
|
14
|
+
* @param {number} options.bufferPercentage - Buffer percentage to add (0-200)
|
|
15
|
+
* @param {number} [options.minTimeout=30000] - Minimum timeout (30 seconds)
|
|
16
|
+
* @param {number} [options.maxTimeout=600000] - Maximum timeout (10 minutes)
|
|
17
|
+
* @returns {number} Calculated timeout in milliseconds
|
|
18
|
+
*/
|
|
19
|
+
static calculateTimeout(options) {
|
|
20
|
+
const {
|
|
21
|
+
ewma,
|
|
22
|
+
defaultTimeout,
|
|
23
|
+
bufferPercentage,
|
|
24
|
+
minTimeout = 30000,
|
|
25
|
+
maxTimeout = 600000
|
|
26
|
+
} = options;
|
|
27
|
+
|
|
28
|
+
// Use default timeout if no EWMA available or EWMA is zero
|
|
29
|
+
if (!ewma || ewma === 0) {
|
|
30
|
+
return defaultTimeout;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Calculate timeout with buffer
|
|
34
|
+
const buffer = ewma * (bufferPercentage / 100);
|
|
35
|
+
let timeout = Math.round(ewma + buffer);
|
|
36
|
+
|
|
37
|
+
// Enforce bounds
|
|
38
|
+
timeout = Math.max(minTimeout, timeout);
|
|
39
|
+
timeout = Math.min(maxTimeout, timeout);
|
|
40
|
+
|
|
41
|
+
return timeout;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Calculate EWMA from array of samples
|
|
46
|
+
* @param {number[]} samples - Array of response time samples
|
|
47
|
+
* @param {number} alpha - EWMA alpha weight (0-1)
|
|
48
|
+
* @returns {number|null} Calculated EWMA or null if no samples
|
|
49
|
+
*/
|
|
50
|
+
static calculateEWMA(samples, alpha) {
|
|
51
|
+
if (!samples || samples.length === 0) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (samples.length === 1) {
|
|
56
|
+
return samples[0];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Start with first sample
|
|
60
|
+
let ewma = samples[0];
|
|
61
|
+
|
|
62
|
+
// Apply EWMA formula for remaining samples
|
|
63
|
+
for (let i = 1; i < samples.length; i++) {
|
|
64
|
+
ewma = this.updateEWMA(ewma, samples[i], alpha);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return ewma;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Update EWMA with new sample
|
|
72
|
+
* @param {number|null} currentEWMA - Current EWMA value
|
|
73
|
+
* @param {number} newSample - New response time sample
|
|
74
|
+
* @param {number} alpha - EWMA alpha weight (0-1)
|
|
75
|
+
* @returns {number} Updated EWMA
|
|
76
|
+
*/
|
|
77
|
+
static updateEWMA(currentEWMA, newSample, alpha) {
|
|
78
|
+
// If no current EWMA, use new sample
|
|
79
|
+
if (currentEWMA === null || currentEWMA === undefined) {
|
|
80
|
+
return newSample;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// EWMA formula: alpha * newSample + (1 - alpha) * currentEWMA
|
|
84
|
+
return Math.round(alpha * newSample + (1 - alpha) * currentEWMA);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Detect if a sample is an outlier
|
|
89
|
+
* @param {number[]} samples - Historical samples
|
|
90
|
+
* @param {number} newSample - New sample to check
|
|
91
|
+
* @param {number} [threshold=2.0] - Standard deviation threshold
|
|
92
|
+
* @returns {boolean} True if outlier detected
|
|
93
|
+
*/
|
|
94
|
+
static detectOutlier(samples, newSample, threshold = 2.0) {
|
|
95
|
+
// Need at least 3 samples for meaningful statistics
|
|
96
|
+
if (!samples || samples.length < 3) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Calculate mean
|
|
101
|
+
const mean = samples.reduce((sum, val) => sum + val, 0) / samples.length;
|
|
102
|
+
|
|
103
|
+
// Calculate standard deviation
|
|
104
|
+
const variance = samples.reduce((sum, val) => {
|
|
105
|
+
const diff = val - mean;
|
|
106
|
+
return sum + (diff * diff);
|
|
107
|
+
}, 0) / samples.length;
|
|
108
|
+
const stdDev = Math.sqrt(variance);
|
|
109
|
+
|
|
110
|
+
// Check if new sample is beyond threshold
|
|
111
|
+
const deviation = Math.abs(newSample - mean);
|
|
112
|
+
return deviation > (threshold * stdDev);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Recommend buffer percentage based on response time variance
|
|
117
|
+
* @param {number[]} samples - Historical response time samples
|
|
118
|
+
* @returns {number} Recommended buffer percentage (20-200)
|
|
119
|
+
*/
|
|
120
|
+
static recommendBufferPercentage(samples) {
|
|
121
|
+
// Need at least 3 samples for meaningful statistics
|
|
122
|
+
if (!samples || samples.length < 3) {
|
|
123
|
+
return 50; // Default
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Calculate coefficient of variation (CV = stdDev / mean)
|
|
127
|
+
const mean = samples.reduce((sum, val) => sum + val, 0) / samples.length;
|
|
128
|
+
|
|
129
|
+
const variance = samples.reduce((sum, val) => {
|
|
130
|
+
const diff = val - mean;
|
|
131
|
+
return sum + (diff * diff);
|
|
132
|
+
}, 0) / samples.length;
|
|
133
|
+
const stdDev = Math.sqrt(variance);
|
|
134
|
+
|
|
135
|
+
const cv = stdDev / mean;
|
|
136
|
+
|
|
137
|
+
// Map CV to buffer percentage
|
|
138
|
+
// Low CV (< 0.2) -> 20-40% buffer
|
|
139
|
+
// Medium CV (0.2-0.5) -> 40-80% buffer
|
|
140
|
+
// High CV (> 0.5) -> 80-200% buffer
|
|
141
|
+
let bufferPercentage;
|
|
142
|
+
|
|
143
|
+
if (cv < 0.2) {
|
|
144
|
+
bufferPercentage = 20 + (cv / 0.2) * 20; // 20-40%
|
|
145
|
+
} else if (cv < 0.5) {
|
|
146
|
+
bufferPercentage = 40 + ((cv - 0.2) / 0.3) * 40; // 40-80%
|
|
147
|
+
} else {
|
|
148
|
+
bufferPercentage = 80 + Math.min((cv - 0.5) * 120, 120); // 80-200%
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Enforce bounds
|
|
152
|
+
bufferPercentage = Math.max(20, bufferPercentage);
|
|
153
|
+
bufferPercentage = Math.min(200, bufferPercentage);
|
|
154
|
+
|
|
155
|
+
return Math.round(bufferPercentage);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
module.exports = { TimeoutCalculator };
|