vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. package/src/sync/sync-engine-backup.js +0 -559
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Rollback Manager
3
+ *
4
+ * Manages rollback capabilities for refactoring operations.
5
+ * Provides safe backup and restore functionality.
6
+ *
7
+ * Refactored into modular components for better maintainability.
8
+ */
9
+
10
+ const path = require('path');
11
+ const { DEFAULT_BACKUP_DIR } = require('./rollback/rollback-types');
12
+ const { RollbackOperation } = require('./rollback/rollback-operation');
13
+ const { RollbackRecorder } = require('./rollback/rollback-recorder');
14
+ const { RollbackHandlers } = require('./rollback/rollback-handlers');
15
+ const { RollbackStateManager } = require('./rollback/rollback-state-manager');
16
+
17
+ /**
18
+ * Main rollback manager class
19
+ */
20
+ class RollbackManager {
21
+ constructor(backupDir = DEFAULT_BACKUP_DIR) {
22
+ this.backupDir = path.resolve(backupDir);
23
+ this.operations = [];
24
+ this.stateManager = new RollbackStateManager(this.backupDir);
25
+ this.sessionId = this.stateManager.generateSessionId();
26
+ this.recorder = new RollbackRecorder(this.backupDir, this.sessionId);
27
+
28
+ this.ensureBackupDirectory();
29
+ }
30
+
31
+ /**
32
+ * Generate unique session ID
33
+ */
34
+ generateSessionId() {
35
+ return this.stateManager.generateSessionId();
36
+ }
37
+
38
+ /**
39
+ * Ensure backup directory exists
40
+ */
41
+ ensureBackupDirectory() {
42
+ this.stateManager.ensureBackupDirectory(this.sessionId);
43
+ }
44
+
45
+ /**
46
+ * Get session backup directory
47
+ */
48
+ getSessionBackupDir() {
49
+ return path.join(this.backupDir, this.sessionId);
50
+ }
51
+
52
+ /**
53
+ * Create backup of a file before modification
54
+ */
55
+ backupFile(filePath) {
56
+ const operation = this.recorder.backupFile(filePath);
57
+ this.operations.push(operation);
58
+ return operation;
59
+ }
60
+
61
+ /**
62
+ * Record file creation
63
+ */
64
+ recordFileCreation(filePath) {
65
+ const operation = this.recorder.recordFileCreation(filePath);
66
+ this.operations.push(operation);
67
+ return operation;
68
+ }
69
+
70
+ /**
71
+ * Record file deletion (with backup)
72
+ */
73
+ recordFileDeletion(filePath) {
74
+ const operation = this.recorder.recordFileDeletion(filePath);
75
+ this.operations.push(operation);
76
+ return operation;
77
+ }
78
+
79
+ /**
80
+ * Record file move/rename
81
+ */
82
+ recordFileMove(oldPath, newPath) {
83
+ const operation = this.recorder.recordFileMove(oldPath, newPath);
84
+ this.operations.push(operation);
85
+ return operation;
86
+ }
87
+
88
+ /**
89
+ * Record directory creation
90
+ */
91
+ recordDirectoryCreation(dirPath) {
92
+ const operation = this.recorder.recordDirectoryCreation(dirPath);
93
+ this.operations.push(operation);
94
+ return operation;
95
+ }
96
+
97
+ /**
98
+ * Record directory deletion (with backup)
99
+ */
100
+ recordDirectoryDeletion(dirPath) {
101
+ const operation = this.recorder.recordDirectoryDeletion(dirPath);
102
+ this.operations.push(operation);
103
+ return operation;
104
+ }
105
+
106
+ /**
107
+ * Execute rollback for all operations
108
+ */
109
+ async rollback() {
110
+ const results = {
111
+ success: [],
112
+ failed: [],
113
+ skipped: []
114
+ };
115
+
116
+ // Execute rollbacks in reverse order
117
+ for (let i = this.operations.length - 1; i >= 0; i--) {
118
+ const operation = this.operations[i];
119
+
120
+ try {
121
+ await RollbackHandlers.rollbackOperation(operation);
122
+ results.success.push(operation);
123
+ } catch (error) {
124
+ operation.error = error.message;
125
+ results.failed.push(operation);
126
+ }
127
+ }
128
+
129
+ return results;
130
+ }
131
+
132
+ /**
133
+ * Rollback a single operation
134
+ */
135
+ async rollbackOperation(operation) {
136
+ return await RollbackHandlers.rollbackOperation(operation);
137
+ }
138
+
139
+ /**
140
+ * Get operation summary
141
+ */
142
+ getSummary() {
143
+ return this.stateManager.generateSummary(this.sessionId, this.operations);
144
+ }
145
+
146
+ /**
147
+ * Save rollback state to file
148
+ */
149
+ saveState() {
150
+ const summary = this.getSummary();
151
+ return this.stateManager.saveState(this.sessionId, this.operations, summary);
152
+ }
153
+
154
+ /**
155
+ * Load rollback state from file
156
+ */
157
+ loadState(sessionId) {
158
+ const state = this.stateManager.loadState(sessionId);
159
+ this.sessionId = state.sessionId;
160
+ this.operations = state.operations;
161
+ this.recorder = new RollbackRecorder(this.backupDir, this.sessionId);
162
+ return state;
163
+ }
164
+
165
+ /**
166
+ * List available rollback sessions
167
+ */
168
+ listSessions() {
169
+ return this.stateManager.listSessions();
170
+ }
171
+
172
+ /**
173
+ * Cleanup old backup sessions
174
+ */
175
+ cleanup(maxAge) {
176
+ return this.stateManager.cleanup(maxAge);
177
+ }
178
+
179
+ /**
180
+ * Clear current session operations
181
+ */
182
+ clear() {
183
+ this.operations = [];
184
+ }
185
+
186
+ /**
187
+ * Get backup size
188
+ */
189
+ getBackupSize() {
190
+ return this.stateManager.getBackupSize(this.sessionId);
191
+ }
192
+ }
193
+
194
+ // Export all components for backward compatibility
195
+ module.exports = {
196
+ RollbackManager,
197
+ RollbackOperation,
198
+ RollbackRecorder,
199
+ RollbackHandlers,
200
+ RollbackStateManager,
201
+ DEFAULT_BACKUP_DIR
202
+ };
@@ -0,0 +1,362 @@
1
+ /**
2
+ * CLI Smoke Testing Utility
3
+ *
4
+ * Provides smoke testing functionality for the CLI interface
5
+ * to ensure it starts and responds to basic commands correctly.
6
+ */
7
+
8
+ const { spawn } = require('child_process');
9
+ const path = require('path');
10
+ const fs = require('fs');
11
+
12
+ class CliSmokeTest {
13
+ constructor(options = {}) {
14
+ this.cliPath = options.cliPath || path.join(__dirname, '../../../cli/bin/vibecodingmachine.js');
15
+ this.timeout = options.timeout || 30000; // 30 seconds default
16
+ this.verbose = options.verbose || false;
17
+ }
18
+
19
+ /**
20
+ * Run comprehensive CLI smoke tests
21
+ * @returns {Promise<Object>} Test results
22
+ */
23
+ async runSmokeTests() {
24
+ const results = {
25
+ passed: 0,
26
+ failed: 0,
27
+ total: 0,
28
+ details: []
29
+ };
30
+
31
+ const tests = [
32
+ { name: 'CLI File Exists', test: () => this.testCliFileExists() },
33
+ { name: 'CLI Starts Without Crashing', test: () => this.testCliStarts() },
34
+ { name: 'CLI --help Command', test: () => this.testHelpCommand() },
35
+ { name: 'CLI --version Command', test: () => this.testVersionCommand() },
36
+ { name: 'CLI Basic Commands Available', test: () => this.testBasicCommands() }
37
+ ];
38
+
39
+ for (const test of tests) {
40
+ results.total++;
41
+ try {
42
+ const result = await test.test();
43
+ if (result.passed) {
44
+ results.passed++;
45
+ if (this.verbose) {
46
+ console.log(`✅ ${test.name}: PASSED`);
47
+ }
48
+ } else {
49
+ results.failed++;
50
+ console.error(`❌ ${test.name}: FAILED - ${result.error}`);
51
+ }
52
+ results.details.push({
53
+ name: test.name,
54
+ passed: result.passed,
55
+ error: result.error,
56
+ details: result.details
57
+ });
58
+ } catch (error) {
59
+ results.failed++;
60
+ console.error(`❌ ${test.name}: ERROR - ${error.message}`);
61
+ results.details.push({
62
+ name: test.name,
63
+ passed: false,
64
+ error: error.message,
65
+ details: null
66
+ });
67
+ }
68
+ }
69
+
70
+ return {
71
+ success: results.failed === 0,
72
+ ...results
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Test if CLI file exists and is executable
78
+ */
79
+ async testCliFileExists() {
80
+ try {
81
+ const exists = fs.existsSync(this.cliPath);
82
+ if (!exists) {
83
+ return { passed: false, error: `CLI file not found: ${this.cliPath}` };
84
+ }
85
+
86
+ const stats = fs.statSync(this.cliPath);
87
+ if (!stats.isFile()) {
88
+ return { passed: false, error: `CLI path is not a file: ${this.cliPath}` };
89
+ }
90
+
91
+ return { passed: true, details: { path: this.cliPath, size: stats.size } };
92
+ } catch (error) {
93
+ return { passed: false, error: error.message };
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Test if CLI starts without crashing
99
+ */
100
+ async testCliStarts() {
101
+ return new Promise((resolve) => {
102
+ const startTime = Date.now();
103
+ const child = spawn('node', [this.cliPath, '--help'], {
104
+ stdio: ['pipe', 'pipe', 'pipe'],
105
+ cwd: path.dirname(this.cliPath)
106
+ });
107
+
108
+ let stdout = '';
109
+ let stderr = '';
110
+
111
+ child.stdout.on('data', (data) => {
112
+ stdout += data.toString();
113
+ });
114
+
115
+ child.stderr.on('data', (data) => {
116
+ stderr += data.toString();
117
+ });
118
+
119
+ const timeoutId = setTimeout(() => {
120
+ child.kill('SIGTERM');
121
+ resolve({
122
+ passed: false,
123
+ error: `CLI startup timeout after ${this.timeout}ms`,
124
+ details: { stdout, stderr }
125
+ });
126
+ }, this.timeout);
127
+
128
+ child.on('close', (code) => {
129
+ clearTimeout(timeoutId);
130
+ const duration = Date.now() - startTime;
131
+
132
+ // Allow exit code 0 or 1 (help command might exit with 1)
133
+ if (code === 0 || code === 1) {
134
+ resolve({
135
+ passed: true,
136
+ details: {
137
+ exitCode: code,
138
+ duration,
139
+ stdout: stdout.substring(0, 500), // First 500 chars
140
+ hasOutput: stdout.length > 0
141
+ }
142
+ });
143
+ } else {
144
+ resolve({
145
+ passed: false,
146
+ error: `CLI exited with code ${code}`,
147
+ details: { exitCode: code, stdout, stderr, duration }
148
+ });
149
+ }
150
+ });
151
+
152
+ child.on('error', (error) => {
153
+ clearTimeout(timeoutId);
154
+ resolve({
155
+ passed: false,
156
+ error: `CLI failed to start: ${error.message}`,
157
+ details: { error: error.message }
158
+ });
159
+ });
160
+ });
161
+ }
162
+
163
+ /**
164
+ * Test --help command specifically
165
+ */
166
+ async testHelpCommand() {
167
+ return new Promise((resolve) => {
168
+ const child = spawn('node', [this.cliPath, '--help'], {
169
+ stdio: ['pipe', 'pipe', 'pipe'],
170
+ cwd: path.dirname(this.cliPath)
171
+ });
172
+
173
+ let stdout = '';
174
+ let stderr = '';
175
+
176
+ child.stdout.on('data', (data) => {
177
+ stdout += data.toString();
178
+ });
179
+
180
+ child.stderr.on('data', (data) => {
181
+ stderr += data.toString();
182
+ });
183
+
184
+ const timeoutId = setTimeout(() => {
185
+ child.kill('SIGTERM');
186
+ resolve({
187
+ passed: false,
188
+ error: `Help command timeout after ${this.timeout}ms`
189
+ });
190
+ }, this.timeout);
191
+
192
+ child.on('close', (code) => {
193
+ clearTimeout(timeoutId);
194
+
195
+ // Check for help-related content
196
+ const hasHelpContent = stdout.includes('Usage:') ||
197
+ stdout.includes('Options:') ||
198
+ stdout.includes('Commands:') ||
199
+ stdout.includes('help');
200
+
201
+ // Allow exit code 0 or 1 for help
202
+ if ((code === 0 || code === 1) && hasHelpContent) {
203
+ resolve({
204
+ passed: true,
205
+ details: {
206
+ exitCode: code,
207
+ hasHelpContent,
208
+ outputLength: stdout.length
209
+ }
210
+ });
211
+ } else {
212
+ resolve({
213
+ passed: false,
214
+ error: `Help command failed - exit code: ${code}, has help content: ${hasHelpContent}`,
215
+ details: { exitCode: code, stdout: stdout.substring(0, 200), stderr }
216
+ });
217
+ }
218
+ });
219
+
220
+ child.on('error', (error) => {
221
+ clearTimeout(timeoutId);
222
+ resolve({
223
+ passed: false,
224
+ error: `Help command error: ${error.message}`
225
+ });
226
+ });
227
+ });
228
+ }
229
+
230
+ /**
231
+ * Test --version command
232
+ */
233
+ async testVersionCommand() {
234
+ return new Promise((resolve) => {
235
+ const child = spawn('node', [this.cliPath, '--version'], {
236
+ stdio: ['pipe', 'pipe', 'pipe'],
237
+ cwd: path.dirname(this.cliPath)
238
+ });
239
+
240
+ let stdout = '';
241
+ let stderr = '';
242
+
243
+ child.stdout.on('data', (data) => {
244
+ stdout += data.toString();
245
+ });
246
+
247
+ child.stderr.on('data', (data) => {
248
+ stderr += data.toString();
249
+ });
250
+
251
+ const timeoutId = setTimeout(() => {
252
+ child.kill('SIGTERM');
253
+ resolve({
254
+ passed: false,
255
+ error: `Version command timeout after ${this.timeout}ms`
256
+ });
257
+ }, this.timeout);
258
+
259
+ child.on('close', (code) => {
260
+ clearTimeout(timeoutId);
261
+
262
+ // Check for version-like content
263
+ const hasVersionContent = /\d+\.\d+\.\d+/.test(stdout) ||
264
+ stdout.includes('version') ||
265
+ stdout.length > 0;
266
+
267
+ if (code === 0 && hasVersionContent) {
268
+ resolve({
269
+ passed: true,
270
+ details: {
271
+ exitCode: code,
272
+ version: stdout.trim(),
273
+ hasVersionContent
274
+ }
275
+ });
276
+ } else {
277
+ resolve({
278
+ passed: false,
279
+ error: `Version command failed - exit code: ${code}`,
280
+ details: { exitCode: code, stdout, stderr }
281
+ });
282
+ }
283
+ });
284
+
285
+ child.on('error', (error) => {
286
+ clearTimeout(timeoutId);
287
+ resolve({
288
+ passed: false,
289
+ error: `Version command error: ${error.message}`
290
+ });
291
+ });
292
+ });
293
+ }
294
+
295
+ /**
296
+ * Test that basic commands are available
297
+ */
298
+ async testBasicCommands() {
299
+ return new Promise((resolve) => {
300
+ const child = spawn('node', [this.cliPath, '--help'], {
301
+ stdio: ['pipe', 'pipe', 'pipe'],
302
+ cwd: path.dirname(this.cliPath)
303
+ });
304
+
305
+ let stdout = '';
306
+
307
+ child.stdout.on('data', (data) => {
308
+ stdout += data.toString();
309
+ });
310
+
311
+ const timeoutId = setTimeout(() => {
312
+ child.kill('SIGTERM');
313
+ resolve({
314
+ passed: false,
315
+ error: `Basic commands check timeout after ${this.timeout}ms`
316
+ });
317
+ }, this.timeout);
318
+
319
+ child.on('close', (code) => {
320
+ clearTimeout(timeoutId);
321
+
322
+ // Look for basic command patterns
323
+ const basicCommands = [
324
+ 'repo', 'auto', 'help', 'version'
325
+ ];
326
+
327
+ const foundCommands = basicCommands.filter(cmd =>
328
+ stdout.toLowerCase().includes(cmd.toLowerCase())
329
+ );
330
+
331
+ const hasEnoughCommands = foundCommands.length >= 2;
332
+
333
+ if ((code === 0 || code === 1) && hasEnoughCommands) {
334
+ resolve({
335
+ passed: true,
336
+ details: {
337
+ exitCode: code,
338
+ foundCommands,
339
+ commandCount: foundCommands.length
340
+ }
341
+ });
342
+ } else {
343
+ resolve({
344
+ passed: false,
345
+ error: `Basic commands check failed - found ${foundCommands.length} commands`,
346
+ details: { exitCode: code, foundCommands, stdout: stdout.substring(0, 300) }
347
+ });
348
+ }
349
+ });
350
+
351
+ child.on('error', (error) => {
352
+ clearTimeout(timeoutId);
353
+ resolve({
354
+ passed: false,
355
+ error: `Basic commands check error: ${error.message}`
356
+ });
357
+ });
358
+ });
359
+ }
360
+ }
361
+
362
+ module.exports = { CliSmokeTest };