vibecodingmachine-core 2026.2.26-1739 → 2026.3.9-850
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/agents/AgentCheckDiscoveryService.js +180 -0
- package/src/agents/AgentCheckService.js +18 -261
- package/src/agents/AgentCheckStatisticsService.js +195 -0
- package/src/agents/EnvironmentConfigurationManager.js +31 -380
- package/src/agents/InstallationType.js +19 -6
- package/src/agents/SimpleAgentCheckService.js +472 -0
- package/src/agents/config-managers/ConfigUtils.js +72 -0
- package/src/agents/config-managers/DefaultConfig.js +58 -0
- package/src/agents/config-managers/EnvVarLoader.js +66 -0
- package/src/agents/config-managers/FileConfigLoader.js +124 -0
- package/src/agents/config-managers/TypeConverters.js +61 -0
- package/src/agents/config-managers/VariableMappings.js +92 -0
- package/src/agents/discovery/AgentDiscoveryService-refactored.js +272 -0
- package/src/agents/discovery/AgentDiscoveryService.js +29 -403
- package/src/agents/discovery/agent-validator.js +262 -0
- package/src/agents/discovery/discovery-results.js +176 -0
- package/src/agents/discovery/discovery-scanner.js +268 -0
- package/src/agents/discovery/discovery-utils.js +161 -0
- package/src/agents/discovery/executable-analyzer.js +290 -0
- package/src/agents/discovery/history-manager.js +310 -0
- package/src/agents/verification/ResultAnalyzer-refactored.js +341 -0
- package/src/agents/verification/ResultAnalyzer.js +30 -431
- package/src/agents/verification/analysis-utils.js +310 -0
- package/src/agents/verification/batch-analyzer.js +440 -0
- package/src/agents/verification/pattern-recognizer.js +369 -0
- package/src/agents/verification/report-generator.js +320 -0
- package/src/agents/verification/test-analyzer.js +290 -0
- package/src/agents/windows/InstallerFactory.js +4 -0
- package/src/agents/windows/VSCodeExtensionInstaller.js +404 -0
- package/src/analysis/analysis-engine.js +314 -0
- package/src/analysis/ast-analyzer.js +342 -0
- package/src/analysis/boundary-detector-refactored.js +378 -0
- package/src/analysis/boundary-detector.js +200 -603
- package/src/analysis/boundary-scanner.js +609 -0
- package/src/analysis/boundary-types.js +118 -0
- package/src/analysis/boundary-utils.js +293 -0
- package/src/analysis/deadline-priority-calculator.js +18 -0
- package/src/analysis/detection-methods.js +347 -0
- package/src/analysis/importance-priority-calculator.js +18 -0
- package/src/analysis/priority/factor-calculators.js +204 -0
- package/src/analysis/priority/factor-helpers.js +71 -0
- package/src/analysis/priority/priority-constants.js +73 -0
- package/src/analysis/priority/priority-factor-calculators.js +301 -0
- package/src/analysis/priority/reasons-generator.js +44 -0
- package/src/analysis/priority-calculator.js +15 -580
- package/src/analysis/strategy-generator.js +16 -66
- package/src/analysis/type-priority-calculator.js +18 -0
- package/src/analysis/urgency-priority-calculator.js +18 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +2 -40
- package/src/commands/disable-requirement.js +60 -0
- package/src/commands/disable-spec.js +60 -0
- package/src/commands/enable-requirement.js +60 -0
- package/src/commands/enable-spec.js +60 -0
- package/src/commands/registry.js +1 -6
- package/src/commands/requirements.js +8 -2
- package/src/ide-integration/applescript-manager.cjs +9 -24
- package/src/ide-integration/cdp-handlers/chat-reader.js +44 -0
- package/src/ide-integration/cdp-handlers/connection-handler.js +88 -0
- package/src/ide-integration/cdp-handlers/continuation-handler.js +314 -0
- package/src/ide-integration/cdp-handlers/message-submitter.js +75 -0
- package/src/ide-integration/cdp-handlers/text-sender.js +138 -0
- package/src/ide-integration/cdp-manager.js +28 -573
- package/src/ide-integration/claude-code-cli-manager.cjs +48 -12
- package/src/ide-integration/ide-openers/claude-opener.js +171 -0
- package/src/ide-integration/ide-openers/cursor-opener.js +53 -0
- package/src/ide-integration/ide-openers/other-ides-opener.js +230 -0
- package/src/ide-integration/ide-openers/vscode-opener.js +147 -0
- package/src/ide-integration/macos-ide-manager.js +20 -582
- package/src/ide-integration/macos-quota-checker.js +164 -0
- package/src/ide-integration/macos-text-sender.js +19 -38
- package/src/ide-integration/provider-manager.cjs +52 -7
- package/src/index.cjs +6 -0
- package/src/index.js +10 -0
- package/src/llm/direct-llm-manager.cjs +501 -0
- package/src/localization/translations/en-part1.js +363 -0
- package/src/localization/translations/en-part2.js +320 -0
- package/src/localization/translations/en.js +4 -687
- package/src/localization/translations/es-part1.js +363 -0
- package/src/localization/translations/es-part2.js +320 -0
- package/src/localization/translations/es.js +4 -688
- package/src/models/file-analysis-collection.js +139 -0
- package/src/models/file-analysis-metrics.js +50 -0
- package/src/models/file-analysis.js +15 -262
- package/src/models/plan-manager.js +410 -0
- package/src/models/refactoring-models.js +380 -0
- package/src/models/refactoring-plan-refactored.js +81 -0
- package/src/models/refactoring-plan.js +2 -663
- package/src/monitoring/alert-system.js +4 -45
- package/src/monitoring/continuous-scan-notifications.js +37 -191
- package/src/monitoring/notification-handlers/base-handler.js +58 -0
- package/src/monitoring/notification-handlers/error-handler.js +36 -0
- package/src/monitoring/notification-handlers/index.js +21 -0
- package/src/monitoring/notification-handlers/new-violation-handler.js +91 -0
- package/src/monitoring/notification-handlers/progress-handler.js +48 -0
- package/src/monitoring/notification-handlers/resolved-violation-handler.js +54 -0
- package/src/monitoring/notification-handlers/threshold-handler.js +36 -0
- package/src/provider-registry.js +8 -0
- package/src/refactoring/boundary/boundary-detector-refactored.js +58 -0
- package/src/refactoring/boundary/boundary-detector.js +26 -596
- package/src/refactoring/boundary/detectors/boundary-analyzers.js +281 -0
- package/src/refactoring/boundary/detectors/boundary-core.js +167 -0
- package/src/refactoring/boundary/detectors/class-detector.js +247 -0
- package/src/refactoring/boundary/detectors/config-detector.js +270 -0
- package/src/refactoring/boundary/detectors/constant-detector.js +269 -0
- package/src/refactoring/boundary/detectors/function-detector.js +248 -0
- package/src/refactoring/boundary/detectors/module-detector.js +249 -0
- package/src/refactoring/boundary/detectors/object-detector.js +247 -0
- package/src/refactoring/boundary/detectors/type-detectors.js +338 -0
- package/src/refactoring/boundary/detectors/utility-detector.js +270 -0
- package/src/refactoring/circular-dependency-resolver-original.js +16 -76
- package/src/refactoring/code-mover-refactored.js +309 -0
- package/src/refactoring/code-mover.js +48 -355
- package/src/refactoring/execution-status.js +18 -0
- package/src/refactoring/execution-strategies.js +172 -0
- package/src/refactoring/file-splitter-core.js +568 -0
- package/src/refactoring/file-splitter-types.js +136 -0
- package/src/refactoring/file-splitter.js +2 -682
- package/src/refactoring/functionality-validator.js +11 -51
- package/src/refactoring/import-manager-refactored.js +385 -0
- package/src/refactoring/import-manager.js +112 -487
- package/src/refactoring/import-models.js +189 -0
- package/src/refactoring/import-parser.js +306 -0
- package/src/refactoring/move-executor.js +431 -0
- package/src/refactoring/move-utils.js +368 -0
- package/src/refactoring/operation-executor.js +76 -0
- package/src/refactoring/plan-creator.js +36 -0
- package/src/refactoring/plan-executor.js +143 -0
- package/src/refactoring/plan-validator.js +68 -0
- package/src/refactoring/refactoring-executor-result.js +70 -0
- package/src/refactoring/refactoring-executor.js +34 -569
- package/src/refactoring/refactoring-operation.js +94 -0
- package/src/refactoring/refactoring-plan.js +69 -0
- package/src/refactoring/refactoring-rollback.js +22 -527
- package/src/refactoring/rollback-handlers/RollbackExecutor.js +107 -0
- package/src/refactoring/rollback-handlers/RollbackManager.js +265 -0
- package/src/refactoring/rollback-handlers/RollbackOperation.js +105 -0
- package/src/refactoring/rollback-handlers/RollbackResult.js +109 -0
- package/src/refactoring/rollback-handlers/RollbackStatistics.js +77 -0
- package/src/refactoring/test-validator.js +32 -448
- package/src/refactoring/validation/baseline-runner.js +71 -0
- package/src/refactoring/validation/report-generator.js +136 -0
- package/src/refactoring/validation/result-comparator.js +92 -0
- package/src/refactoring/validation/test-suite.js +59 -0
- package/src/refactoring/validation/test-validation-result.js +83 -0
- package/src/refactoring/validation/validation-runner.js +95 -0
- package/src/refactoring/validation/validation-status.js +18 -0
- package/src/rui/commands/AgentCommandParser.js +60 -369
- package/src/rui/commands/AgentResponseFormatter.js +7 -47
- package/src/rui/commands/parsers/CommandMapper.js +148 -0
- package/src/rui/commands/parsers/CommandValidator.js +228 -0
- package/src/rui/commands/parsers/ComponentExtractor.js +100 -0
- package/src/rui/commands/parsers/TokenParser.js +69 -0
- package/src/rui/commands/parsers/tokenizer.js +153 -0
- package/src/utils/current-requirement-operations.js +50 -1
- package/src/utils/report-generator.js +18 -514
- package/src/utils/report-generators/analysis-generator.js +115 -0
- package/src/utils/report-generators/base-generator.js +141 -0
- package/src/utils/report-generators/compliance-generator.js +41 -0
- package/src/utils/report-generators/format-handlers.js +185 -0
- package/src/utils/report-generators/refactoring-generator.js +46 -0
- package/src/utils/report-generators/validation-generator.js +63 -0
- package/src/utils/requirement-enable-disable.js +265 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +69 -1
- package/src/utils/requirement-helpers/requirement-mover.js +88 -1
- package/src/utils/requirement-helpers.js +5 -2
- package/src/utils/smoke-test-cli.js +45 -8
- package/src/utils/specification-enable-disable.js +122 -0
- package/src/utils/specification-helpers.js +30 -4
- package/src/utils/specification-migration.js +5 -5
- package/src/utils/test-comparator.js +118 -0
- package/src/utils/test-config.js +54 -0
- package/src/utils/test-executor.js +133 -0
- package/src/utils/test-parser.js +215 -0
- package/src/utils/test-runner-baseline.js +63 -0
- package/src/utils/test-runner-core.js +98 -0
- package/src/utils/test-runner-report.js +39 -0
- package/src/utils/test-runner-validation.js +71 -0
- package/src/utils/test-runner.js +11 -535
- package/src/validation/comparison-analyzer.js +333 -0
- package/src/validation/compliance-reporter-new.js +282 -0
- package/src/validation/compliance-reporter-refactored.js +344 -0
- package/src/validation/compliance-reporter.js +278 -591
- package/src/validation/compliance-utils.js +278 -0
- package/src/validation/html-generator.js +446 -0
- package/src/validation/metrics/category-calculator.js +137 -0
- package/src/validation/metrics/metrics-helpers.js +155 -0
- package/src/validation/metrics/overview-calculator.js +85 -0
- package/src/validation/metrics/overview-metrics.js +41 -0
- package/src/validation/metrics/quality-calculator.js +166 -0
- package/src/validation/metrics/size-calculator.js +69 -0
- package/src/validation/metrics-calculator.js +27 -551
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Specification Enable/Disable Utilities
|
|
3
|
+
* Provides functions to enable and disable specifications using DISABLED.vcm files
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const fs = require('fs-extra');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Enable a specification by removing DISABLED.vcm file if it exists
|
|
11
|
+
* @param {string} specId - Specification ID (e.g., "001-agent-defaults")
|
|
12
|
+
* @param {string} repoPath - Repository root path
|
|
13
|
+
* @returns {Promise<{success: boolean, message: string}>}
|
|
14
|
+
*/
|
|
15
|
+
async function enableSpec(specId, repoPath = process.cwd()) {
|
|
16
|
+
try {
|
|
17
|
+
const specPath = path.join(repoPath, 'specs', specId);
|
|
18
|
+
const disabledFile = path.join(specPath, 'DISABLED.vcm');
|
|
19
|
+
|
|
20
|
+
// Check if spec directory exists
|
|
21
|
+
if (!await fs.pathExists(specPath)) {
|
|
22
|
+
return {
|
|
23
|
+
success: false,
|
|
24
|
+
message: `Specification ${specId} not found`
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Check if spec is currently disabled
|
|
29
|
+
const isDisabled = await fs.pathExists(disabledFile);
|
|
30
|
+
if (!isDisabled) {
|
|
31
|
+
return {
|
|
32
|
+
success: true,
|
|
33
|
+
message: `Specification ${specId} is already enabled`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Remove DISABLED.vcm file to enable the spec
|
|
38
|
+
await fs.remove(disabledFile);
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
success: true,
|
|
42
|
+
message: `Specification ${specId} enabled successfully`
|
|
43
|
+
};
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
message: `Failed to enable specification ${specId}: ${error.message}`
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Disable a specification by creating DISABLED.vcm file
|
|
54
|
+
* @param {string} specId - Specification ID (e.g., "001-agent-defaults")
|
|
55
|
+
* @param {string} repoPath - Repository root path
|
|
56
|
+
* @returns {Promise<{success: boolean, message: string}>}
|
|
57
|
+
*/
|
|
58
|
+
async function disableSpec(specId, repoPath = process.cwd()) {
|
|
59
|
+
try {
|
|
60
|
+
const specPath = path.join(repoPath, 'specs', specId);
|
|
61
|
+
const disabledFile = path.join(specPath, 'DISABLED.vcm');
|
|
62
|
+
|
|
63
|
+
// Check if spec directory exists
|
|
64
|
+
if (!await fs.pathExists(specPath)) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
message: `Specification ${specId} not found`
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check if spec is already disabled
|
|
72
|
+
const isDisabled = await fs.pathExists(disabledFile);
|
|
73
|
+
if (isDisabled) {
|
|
74
|
+
return {
|
|
75
|
+
success: true,
|
|
76
|
+
message: `Specification ${specId} is already disabled`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Create DISABLED.vcm file to disable the spec
|
|
81
|
+
const disabledContent = `# Specification Disabled\n\nThis specification is disabled and will be skipped by auto-mode.\nDisabled at: ${new Date().toISOString()}\n`;
|
|
82
|
+
await fs.writeFile(disabledFile, disabledContent, 'utf8');
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
message: `Specification ${specId} disabled successfully`
|
|
87
|
+
};
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
message: `Failed to disable specification ${specId}: ${error.message}`
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check if a specification is disabled
|
|
98
|
+
* @param {string} specId - Specification ID
|
|
99
|
+
* @param {string} repoPath - Repository root path
|
|
100
|
+
* @returns {Promise<boolean>} - True if disabled, false otherwise
|
|
101
|
+
*/
|
|
102
|
+
async function isSpecDisabled(specId, repoPath = process.cwd()) {
|
|
103
|
+
try {
|
|
104
|
+
const specPath = path.join(repoPath, 'specs', specId);
|
|
105
|
+
const disabledFile = path.join(specPath, 'DISABLED.vcm');
|
|
106
|
+
|
|
107
|
+
if (!await fs.pathExists(specPath)) {
|
|
108
|
+
return false; // Spec doesn't exist, treat as not disabled
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return await fs.pathExists(disabledFile);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// logger.error(`Error checking if spec is disabled: ${error.message}`);
|
|
114
|
+
return false; // Default to not disabled on error
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
module.exports = {
|
|
119
|
+
enableSpec,
|
|
120
|
+
disableSpec,
|
|
121
|
+
isSpecDisabled
|
|
122
|
+
};
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
const fs = require('fs-extra');
|
|
9
9
|
const path = require('path');
|
|
10
10
|
const { migrateAllDisabledSpecs, isMigrationNeeded } = require('./specification-migration');
|
|
11
|
+
const { enableSpec, disableSpec, isSpecDisabled } = require('./specification-enable-disable');
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Extract the title from spec.md content (first H1 or H2)
|
|
@@ -57,6 +58,27 @@ function extractCompletionPercentage(text) {
|
|
|
57
58
|
return null;
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Extract task counts from arbitrary text
|
|
63
|
+
* Looks for patterns like "N/M tasks" or "N of M tasks"
|
|
64
|
+
* @param {string} text
|
|
65
|
+
* @returns {{completed: number, total: number}|null} task counts or null if not found
|
|
66
|
+
*/
|
|
67
|
+
function extractTaskCounts(text) {
|
|
68
|
+
if (!text || typeof text !== 'string') return null;
|
|
69
|
+
|
|
70
|
+
// Match patterns like "5/10 tasks" or "5 / 10 tasks" or "5 of 10 tasks"
|
|
71
|
+
const p1 = text.match(/(\d+)\s*(?:\/|of)\s*(\d+)\s+tasks?/i);
|
|
72
|
+
if (p1) {
|
|
73
|
+
return {
|
|
74
|
+
completed: parseInt(p1[1]),
|
|
75
|
+
total: parseInt(p1[2])
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
60
82
|
/**
|
|
61
83
|
* Check whether a spec directory has a tasks.md file
|
|
62
84
|
* @param {string} specPath - absolute path to spec directory
|
|
@@ -80,7 +102,7 @@ async function isSpecComplete(specPath) {
|
|
|
80
102
|
* Get all specifications in repo's specs/ directory
|
|
81
103
|
* @param {string} repoPath
|
|
82
104
|
* @param {Object} [options] - Optional configuration
|
|
83
|
-
* @param {boolean} [options.skipDisabled=false] - Skip specs with DISABLED.
|
|
105
|
+
* @param {boolean} [options.skipDisabled=false] - Skip specs with DISABLED.vcm file
|
|
84
106
|
* @param {boolean} [options.includeWithoutSpec=false] - Include spec directories even without spec.md
|
|
85
107
|
* @returns {Promise<Array<{directory, title, path, hasPlan, hasPlanPrompt, hasTasks, hasSpec}>>}
|
|
86
108
|
*/
|
|
@@ -97,8 +119,8 @@ async function getAllSpecifications(repoPath, options = {}) {
|
|
|
97
119
|
const stat = await fs.stat(specPath).catch(() => null);
|
|
98
120
|
if (!stat || !stat.isDirectory()) continue;
|
|
99
121
|
|
|
100
|
-
// Skip disabled specs if skipDisabled is true and DISABLED.
|
|
101
|
-
if (skipDisabled && (await fs.pathExists(path.join(specPath, 'DISABLED.
|
|
122
|
+
// Skip disabled specs if skipDisabled is true and DISABLED.vcm exists or directory starts with DISABLED-
|
|
123
|
+
if (skipDisabled && (await fs.pathExists(path.join(specPath, 'DISABLED.vcm')) || entry.startsWith('DISABLED-'))) {
|
|
102
124
|
continue;
|
|
103
125
|
}
|
|
104
126
|
|
|
@@ -231,6 +253,7 @@ async function initializeSpecifications(repoPath) {
|
|
|
231
253
|
module.exports = {
|
|
232
254
|
extractSpecTitle,
|
|
233
255
|
extractCompletionPercentage,
|
|
256
|
+
extractTaskCounts,
|
|
234
257
|
hasImplementation,
|
|
235
258
|
isSpecComplete,
|
|
236
259
|
getAllSpecifications,
|
|
@@ -238,5 +261,8 @@ module.exports = {
|
|
|
238
261
|
getTodoSpecifications,
|
|
239
262
|
createSpecification,
|
|
240
263
|
updateSpecification,
|
|
241
|
-
initializeSpecifications
|
|
264
|
+
initializeSpecifications,
|
|
265
|
+
enableSpec,
|
|
266
|
+
disableSpec,
|
|
267
|
+
isSpecDisabled
|
|
242
268
|
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Specification Migration Utilities
|
|
3
3
|
* Handles migration from old DISABLED- prefix naming convention
|
|
4
|
-
* to
|
|
4
|
+
* to new DISABLED.vcm file-based disable tracking.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const fs = require('fs-extra');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Migrate a single specification from DISABLED- prefix to DISABLED.
|
|
11
|
+
* Migrate a single specification from DISABLED- prefix to DISABLED.vcm file
|
|
12
12
|
* @param {string} specsDir - path to specs/ directory
|
|
13
13
|
* @param {string} dirName - directory name (e.g., "DISABLED-001-example")
|
|
14
14
|
* @returns {Promise<{success: boolean, oldName: string, newName: string|null, error: string|null}>}
|
|
@@ -29,8 +29,8 @@ async function migrateDisabledSpec(specsDir, dirName) {
|
|
|
29
29
|
return { success: false, oldName: dirName, newName: null, error: 'No spec.md found' };
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
// Create DISABLED.
|
|
33
|
-
const disabledFilePath = path.join(oldPath, 'DISABLED.
|
|
32
|
+
// Create DISABLED.vcm in the old directory before renaming
|
|
33
|
+
const disabledFilePath = path.join(oldPath, 'DISABLED.vcm');
|
|
34
34
|
await fs.writeFile(disabledFilePath, '');
|
|
35
35
|
|
|
36
36
|
// Rename directory to remove DISABLED- prefix
|
|
@@ -43,7 +43,7 @@ async function migrateDisabledSpec(specsDir, dirName) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Migrate all DISABLED- prefixed specs to the new DISABLED.
|
|
46
|
+
* Migrate all DISABLED- prefixed specs to the new DISABLED.vcm format
|
|
47
47
|
* @param {string} repoPath - root repository path
|
|
48
48
|
* @returns {Promise<{totalFound: number, migrated: number, failed: number, results: Array}>}
|
|
49
49
|
*/
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Comparator
|
|
3
|
+
*
|
|
4
|
+
* Compares test results to detect regressions and improvements.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compare baseline and current results
|
|
9
|
+
*/
|
|
10
|
+
function compareResults(baseline, current) {
|
|
11
|
+
const comparison = {
|
|
12
|
+
hasRegressions: false,
|
|
13
|
+
regressions: [],
|
|
14
|
+
improvements: [],
|
|
15
|
+
unchanged: [],
|
|
16
|
+
summary: {
|
|
17
|
+
baseline: {
|
|
18
|
+
total: baseline.total,
|
|
19
|
+
passed: baseline.passed,
|
|
20
|
+
failed: baseline.failed,
|
|
21
|
+
duration: baseline.duration
|
|
22
|
+
},
|
|
23
|
+
current: {
|
|
24
|
+
total: current.total,
|
|
25
|
+
passed: current.passed,
|
|
26
|
+
failed: current.failed,
|
|
27
|
+
duration: current.duration
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Check for test count changes
|
|
33
|
+
if (current.total < baseline.total) {
|
|
34
|
+
comparison.regressions.push({
|
|
35
|
+
type: 'missing_tests',
|
|
36
|
+
message: `${baseline.total - current.total} tests are missing`,
|
|
37
|
+
severity: 'high'
|
|
38
|
+
});
|
|
39
|
+
comparison.hasRegressions = true;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (current.total > baseline.total) {
|
|
43
|
+
comparison.improvements.push({
|
|
44
|
+
type: 'new_tests',
|
|
45
|
+
message: `${current.total - baseline.total} new tests added`,
|
|
46
|
+
severity: 'info'
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check for test failures
|
|
51
|
+
if (current.failed > baseline.failed) {
|
|
52
|
+
comparison.regressions.push({
|
|
53
|
+
type: 'new_failures',
|
|
54
|
+
message: `${current.failed - baseline.failed} new test failures`,
|
|
55
|
+
severity: 'high'
|
|
56
|
+
});
|
|
57
|
+
comparison.hasRegressions = true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (current.failed < baseline.failed) {
|
|
61
|
+
comparison.improvements.push({
|
|
62
|
+
type: 'fixed_failures',
|
|
63
|
+
message: `${baseline.failed - current.failed} test failures fixed`,
|
|
64
|
+
severity: 'good'
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Check for performance regression
|
|
69
|
+
const performanceIncrease = current.duration - baseline.duration;
|
|
70
|
+
const performancePercent = (performanceIncrease / baseline.duration) * 100;
|
|
71
|
+
|
|
72
|
+
if (performanceIncrease > 5000 && performancePercent > 10) { // 5s and 10%
|
|
73
|
+
comparison.regressions.push({
|
|
74
|
+
type: 'performance',
|
|
75
|
+
message: `Test execution increased by ${Math.round(performancePercent)}% (${Math.round(performanceIncrease/1000)}s)`,
|
|
76
|
+
severity: 'medium'
|
|
77
|
+
});
|
|
78
|
+
comparison.hasRegressions = true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Compare individual test results
|
|
82
|
+
const baselineTests = new Map();
|
|
83
|
+
for (const test of baseline.tests) {
|
|
84
|
+
baselineTests.set(test.fullName, test);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
for (const test of current.tests) {
|
|
88
|
+
const baselineTest = baselineTests.get(test.fullName);
|
|
89
|
+
|
|
90
|
+
if (!baselineTest) {
|
|
91
|
+
comparison.improvements.push({
|
|
92
|
+
type: 'new_test',
|
|
93
|
+
message: `New test: ${test.title}`,
|
|
94
|
+
severity: 'info'
|
|
95
|
+
});
|
|
96
|
+
} else if (baselineTest.status === 'passed' && test.status === 'failed') {
|
|
97
|
+
comparison.regressions.push({
|
|
98
|
+
type: 'test_regression',
|
|
99
|
+
message: `Test now failing: ${test.title}`,
|
|
100
|
+
severity: 'high',
|
|
101
|
+
test: test
|
|
102
|
+
});
|
|
103
|
+
comparison.hasRegressions = true;
|
|
104
|
+
} else if (baselineTest.status === 'failed' && test.status === 'passed') {
|
|
105
|
+
comparison.improvements.push({
|
|
106
|
+
type: 'test_fixed',
|
|
107
|
+
message: `Test now passing: ${test.title}`,
|
|
108
|
+
severity: 'good'
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return comparison;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
module.exports = {
|
|
117
|
+
compareResults
|
|
118
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Configuration
|
|
3
|
+
*
|
|
4
|
+
* Handles test configuration detection and validation.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Check if tests are available
|
|
11
|
+
*/
|
|
12
|
+
function checkTestAvailability() {
|
|
13
|
+
const testPaths = [
|
|
14
|
+
'package.json',
|
|
15
|
+
'tests',
|
|
16
|
+
'__tests__',
|
|
17
|
+
'test',
|
|
18
|
+
'spec'
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
for (const testPath of testPaths) {
|
|
22
|
+
if (fs.existsSync(testPath)) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Get test configuration
|
|
32
|
+
*/
|
|
33
|
+
function getTestConfig() {
|
|
34
|
+
try {
|
|
35
|
+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
36
|
+
return {
|
|
37
|
+
hasTestScript: !!packageJson.scripts?.test,
|
|
38
|
+
testScript: packageJson.scripts?.test,
|
|
39
|
+
jestConfig: packageJson.jest,
|
|
40
|
+
dependencies: {
|
|
41
|
+
jest: packageJson.dependencies?.jest || packageJson.devDependencies?.jest,
|
|
42
|
+
mocha: packageJson.dependencies?.mocha || packageJson.devDependencies?.mocha,
|
|
43
|
+
jasmine: packageJson.dependencies?.jasmine || packageJson.devDependencies?.jasmine
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
} catch (error) {
|
|
47
|
+
return { hasTestScript: false };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = {
|
|
52
|
+
checkTestAvailability,
|
|
53
|
+
getTestConfig
|
|
54
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test Executor
|
|
3
|
+
*
|
|
4
|
+
* Handles test execution and process management.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { spawn } = require('child_process');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Execute tests and collect results
|
|
11
|
+
*/
|
|
12
|
+
async function executeTests(options = {}) {
|
|
13
|
+
const defaultOptions = {
|
|
14
|
+
verbose: false,
|
|
15
|
+
timeout: 300000, // 5 minutes
|
|
16
|
+
cwd: process.cwd()
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const opts = { ...defaultOptions, ...options };
|
|
20
|
+
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
const startTime = Date.now();
|
|
23
|
+
let output = '';
|
|
24
|
+
let errorOutput = '';
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// Use npm test with JSON reporter if available
|
|
28
|
+
const testProcess = spawn('npm', ['test', '--', '--json', '--verbose'], {
|
|
29
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
30
|
+
cwd: opts.cwd
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
testProcess.stdout.on('data', (data) => {
|
|
34
|
+
output += data.toString();
|
|
35
|
+
if (opts.verbose) {
|
|
36
|
+
process.stdout.write(data);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
testProcess.stderr.on('data', (data) => {
|
|
41
|
+
errorOutput += data.toString();
|
|
42
|
+
if (opts.verbose) {
|
|
43
|
+
process.stderr.write(data);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
testProcess.on('close', (code) => {
|
|
48
|
+
const duration = Date.now() - startTime;
|
|
49
|
+
resolve({
|
|
50
|
+
stdout: output,
|
|
51
|
+
stderr: errorOutput,
|
|
52
|
+
exitCode: code,
|
|
53
|
+
duration
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
testProcess.on('error', (error) => {
|
|
58
|
+
reject(new Error(`Test process failed: ${error.message}`));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Set timeout
|
|
62
|
+
if (opts.timeout) {
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
testProcess.kill('SIGKILL');
|
|
65
|
+
reject(new Error(`Test execution timed out after ${opts.timeout}ms`));
|
|
66
|
+
}, opts.timeout);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
} catch (error) {
|
|
70
|
+
reject(new Error(`Failed to start test process: ${error.message}`));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Run specific test files
|
|
77
|
+
*/
|
|
78
|
+
async function runSpecificTests(testFiles, options = {}) {
|
|
79
|
+
const defaultOptions = {
|
|
80
|
+
verbose: false,
|
|
81
|
+
cwd: process.cwd()
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const opts = { ...defaultOptions, ...options };
|
|
85
|
+
|
|
86
|
+
console.log(`Running ${testFiles.length} specific tests...`);
|
|
87
|
+
|
|
88
|
+
const testArgs = ['test', '--', ...testFiles];
|
|
89
|
+
|
|
90
|
+
return new Promise((resolve, reject) => {
|
|
91
|
+
const startTime = Date.now();
|
|
92
|
+
let output = '';
|
|
93
|
+
let errorOutput = '';
|
|
94
|
+
|
|
95
|
+
const testProcess = spawn('npm', testArgs, {
|
|
96
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
97
|
+
cwd: opts.cwd
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
testProcess.stdout.on('data', (data) => {
|
|
101
|
+
output += data.toString();
|
|
102
|
+
if (opts.verbose) {
|
|
103
|
+
process.stdout.write(data);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
testProcess.stderr.on('data', (data) => {
|
|
108
|
+
errorOutput += data.toString();
|
|
109
|
+
if (opts.verbose) {
|
|
110
|
+
process.stderr.write(data);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
testProcess.on('close', (code) => {
|
|
115
|
+
const duration = Date.now() - startTime;
|
|
116
|
+
resolve({
|
|
117
|
+
stdout: output,
|
|
118
|
+
stderr: errorOutput,
|
|
119
|
+
exitCode: code,
|
|
120
|
+
duration
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
testProcess.on('error', (error) => {
|
|
125
|
+
reject(new Error(`Test process failed: ${error.message}`));
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = {
|
|
131
|
+
executeTests,
|
|
132
|
+
runSpecificTests
|
|
133
|
+
};
|