vibecodingmachine-core 2026.3.14-1528 → 2026.6.17-1835

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 (414) hide show
  1. package/package.json +7 -2
  2. package/src/agents/Agent.js +1 -1
  3. package/src/agents/AgentAdditionService.js +1 -1
  4. package/src/agents/AgentCheckDiscoveryService.js +2 -2
  5. package/src/agents/AgentCheckService.js +16 -16
  6. package/src/agents/AgentCheckStatisticsService.js +11 -11
  7. package/src/agents/AgentInstallationService.js +6 -6
  8. package/src/agents/AgentSetupService.js +15 -15
  9. package/src/agents/AgentStatus.js +8 -8
  10. package/src/agents/AgentVerificationService.js +39 -39
  11. package/src/agents/ConfigurationSchemaValidator.js +8 -8
  12. package/src/agents/EnvironmentConfigurationManager.js +28 -28
  13. package/src/agents/InstallationErrorHandler.js +11 -11
  14. package/src/agents/InstallationLog.js +18 -18
  15. package/src/agents/InstallationMethod.js +1 -1
  16. package/src/agents/InstallationOrchestrator.js +37 -37
  17. package/src/agents/InstallationProgressReporter.js +13 -13
  18. package/src/agents/InstallationRetryManager.js +20 -20
  19. package/src/agents/InstallationType.js +14 -14
  20. package/src/agents/OperationTypes.js +12 -12
  21. package/src/agents/PerformanceMetricsCollector.js +59 -59
  22. package/src/agents/SecurityValidationService.js +17 -17
  23. package/src/agents/SimpleAgentCheckService.js +79 -74
  24. package/src/agents/VerificationTest.js +26 -26
  25. package/src/agents/VerificationType.js +5 -5
  26. package/src/agents/WindowsPermissionHandler.js +30 -30
  27. package/src/agents/config/AgentDefaultsRegistry.js +3 -3
  28. package/src/agents/config-managers/ConfigUtils.js +5 -5
  29. package/src/agents/config-managers/DefaultConfig.js +1 -1
  30. package/src/agents/config-managers/EnvVarLoader.js +7 -7
  31. package/src/agents/config-managers/FileConfigLoader.js +22 -22
  32. package/src/agents/config-managers/TypeConverters.js +1 -1
  33. package/src/agents/config-managers/VariableMappings.js +7 -7
  34. package/src/agents/discovery/AgentDiscoveryService-refactored.js +8 -8
  35. package/src/agents/discovery/AgentDiscoveryService.js +14 -14
  36. package/src/agents/discovery/agent-validator.js +4 -4
  37. package/src/agents/discovery/discovery-results.js +1 -1
  38. package/src/agents/discovery/discovery-scanner.js +29 -29
  39. package/src/agents/discovery/discovery-utils.js +6 -6
  40. package/src/agents/discovery/executable-analyzer.js +27 -27
  41. package/src/agents/discovery/history-manager.js +2 -2
  42. package/src/agents/logging/AgentLogger.js +20 -20
  43. package/src/agents/status/AgentStatusManager.js +30 -30
  44. package/src/agents/storage/FileManager.js +15 -15
  45. package/src/agents/validation.js +4 -4
  46. package/src/agents/verification/AgentCommunicationTester.js +46 -46
  47. package/src/agents/verification/BaseVerifier.js +31 -31
  48. package/src/agents/verification/CommandVerifier.js +34 -34
  49. package/src/agents/verification/FileOperationVerifier.js +14 -14
  50. package/src/agents/verification/ResultAnalyzer-refactored.js +7 -7
  51. package/src/agents/verification/ResultAnalyzer.js +29 -29
  52. package/src/agents/verification/TestRequirementManager.js +49 -49
  53. package/src/agents/verification/VerificationRunner.js +18 -18
  54. package/src/agents/verification/analysis-utils.js +27 -27
  55. package/src/agents/verification/batch-analyzer.js +55 -55
  56. package/src/agents/verification/pattern-recognizer.js +49 -49
  57. package/src/agents/verification/report-generator.js +9 -9
  58. package/src/agents/verification/test-analyzer.js +29 -29
  59. package/src/agents/windows/BaseWindowsInstaller.js +22 -22
  60. package/src/agents/windows/ChocolateyInstaller.js +31 -31
  61. package/src/agents/windows/DirectInstaller.js +23 -23
  62. package/src/agents/windows/InstallerFactory.js +16 -16
  63. package/src/agents/windows/NpmInstaller.js +39 -39
  64. package/src/agents/windows/PowerShellInstaller.js +27 -27
  65. package/src/agents/windows/VSCodeExtensionInstaller.js +10 -10
  66. package/src/agents/windows/WinGetInstaller.js +23 -23
  67. package/src/analysis/analysis-engine.js +35 -35
  68. package/src/analysis/analysis-reporter.js +7 -7
  69. package/src/analysis/ast-analyzer.js +28 -28
  70. package/src/analysis/boundary-detector-refactored.js +35 -35
  71. package/src/analysis/boundary-detector.js +35 -35
  72. package/src/analysis/boundary-scanner.js +52 -52
  73. package/src/analysis/boundary-types.js +3 -3
  74. package/src/analysis/boundary-utils.js +33 -33
  75. package/src/analysis/categorizer.js +20 -20
  76. package/src/analysis/codebase-scanner.js +22 -22
  77. package/src/analysis/detection-methods.js +25 -25
  78. package/src/analysis/line-counter.js +14 -14
  79. package/src/analysis/report/analysis-report.js +9 -9
  80. package/src/analysis/report/package-analyzer.js +33 -33
  81. package/src/analysis/report/recommendation-generator.js +29 -29
  82. package/src/analysis/report/statistics-generator.js +53 -53
  83. package/src/analysis/reports/analysis-report-model.js +4 -4
  84. package/src/analysis/reports/recommendation-generator.js +25 -25
  85. package/src/analysis/reports/report-generators.js +9 -9
  86. package/src/analysis/reports/statistics-calculator.js +23 -23
  87. package/src/analysis/reports/trend-analyzer.js +19 -19
  88. package/src/analysis/strategy-generator.js +5 -5
  89. package/src/auth/shared-auth-storage.js +15 -7
  90. package/src/auto-mode/AutoModeBusinessLogic.js +9 -15
  91. package/src/auto-mode/auto-mode-streaks.js +104 -0
  92. package/src/auto-mode/direct-run-recovery.js +99 -0
  93. package/src/auto-mode/rate-limit-budget.js +169 -0
  94. package/src/auto-mode/rate-limit-handler.js +218 -0
  95. package/src/auto-mode/rate-limit-store.js +174 -0
  96. package/src/auto-mode/stage-change-log.js +60 -0
  97. package/src/auto-mode/stage-stall-tracker.js +123 -0
  98. package/src/auto-mode-error-detector/error-detector.js +135 -0
  99. package/src/autonomous-mode/feature-implementer.js +20 -24
  100. package/src/beta-request.js +1 -1
  101. package/src/chat-management/chat-manager.js +3 -3
  102. package/src/commands/base.js +8 -8
  103. package/src/commands/disable-requirement.js +2 -2
  104. package/src/commands/disable-spec.js +2 -2
  105. package/src/commands/enable-requirement.js +2 -2
  106. package/src/commands/enable-spec.js +2 -2
  107. package/src/commands/help.js +5 -5
  108. package/src/commands/registry.js +12 -12
  109. package/src/commands/requirements.js +2 -2
  110. package/src/commands/resolver.js +7 -7
  111. package/src/commands/settings.js +79 -4
  112. package/src/compliance/compliance-manager.js +10 -10
  113. package/src/compliance/compliance-prompt.js +6 -6
  114. package/src/config/refactoring-config.js +6 -6
  115. package/src/database/migrations.js +1 -1
  116. package/src/database/user-database-client.js +1 -1
  117. package/src/database/user-schema.js +2 -2
  118. package/src/feedback/feedback-config-manager.js +95 -0
  119. package/src/feedback/feedback-manager.js +501 -0
  120. package/src/feedback/ui-preferences-manager.js +87 -0
  121. package/src/git/commit-manager.js +475 -0
  122. package/src/health-tracking/health-reporter.js +14 -14
  123. package/src/health-tracking/ide-health-tracker.js +17 -3
  124. package/src/health-tracking/json-storage.js +4 -4
  125. package/src/ide-integration/agent-test-runner.js +275 -0
  126. package/src/ide-integration/aider/commands/configuration-manager.js +39 -0
  127. package/src/ide-integration/aider/commands/installation-manager.js +111 -0
  128. package/src/ide-integration/aider/processes/process-manager.js +37 -0
  129. package/src/ide-integration/aider/utils/ollama-manager.js +154 -0
  130. package/src/ide-integration/aider-cli-manager.cjs +16 -241
  131. package/src/ide-integration/applescript-antigravity-quota.cjs +515 -0
  132. package/src/ide-integration/applescript-cursor-quota.cjs +351 -0
  133. package/src/ide-integration/applescript-ide-opener.cjs +489 -0
  134. package/src/ide-integration/applescript-kiro-quota.cjs +549 -0
  135. package/src/ide-integration/applescript-manager-core.js +30 -12
  136. package/src/ide-integration/applescript-manager.cjs +45 -3201
  137. package/src/ide-integration/applescript-manager.js +34 -16
  138. package/src/ide-integration/applescript-response-reader.cjs +658 -0
  139. package/src/ide-integration/applescript-send-text.cjs +307 -0
  140. package/src/ide-integration/applescript-status-continuation.cjs +581 -0
  141. package/src/ide-integration/applescript-utils.js +203 -192
  142. package/src/ide-integration/cdp-handlers/connection-handler.js +2 -2
  143. package/src/ide-integration/cdp-handlers/continuation-handler.js +7 -7
  144. package/src/ide-integration/cdp-handlers/text-sender.js +1 -1
  145. package/src/ide-integration/cdp-manager.js +2 -2
  146. package/src/ide-integration/cli-direct-runner.js +483 -0
  147. package/src/ide-integration/cli-session-manager.js +180 -0
  148. package/src/ide-integration/cline-cli-manager.js +24 -24
  149. package/src/ide-integration/continuation-handler.js +18 -18
  150. package/src/ide-integration/continue-cli-manager.js +14 -14
  151. package/src/ide-integration/ide-openers/claude-opener.js +23 -7
  152. package/src/ide-integration/ide-openers/other-ides-opener.js +17 -63
  153. package/src/ide-integration/ide-status-checker.js +20 -20
  154. package/src/ide-integration/macos-ide-manager.js +55 -4
  155. package/src/ide-integration/macos-quota-checker.js +1 -1
  156. package/src/ide-integration/macos-text-sender.js +204 -68
  157. package/src/ide-integration/quota-detector.cjs +11 -11
  158. package/src/ide-integration/quota-detector.js +11 -11
  159. package/src/ide-integration/response-reader.js +10 -10
  160. package/src/ide-integration/windows/cursor-automation.js +304 -0
  161. package/src/ide-integration/windows/ide-automation.js +735 -0
  162. package/src/ide-integration/windows/window-operations.js +183 -0
  163. package/src/ide-integration/windows-automation-manager.js +92 -865
  164. package/src/ide-integration/windows-ide-manager.js +13 -13
  165. package/src/index.cjs +87 -6
  166. package/src/index.js +56 -41
  167. package/src/installation/config-manager.js +247 -0
  168. package/src/installation/config-paths.js +64 -0
  169. package/src/installation/fs-validators.js +166 -0
  170. package/src/installation/index.js +30 -0
  171. package/src/installation/path-resolver.js +73 -0
  172. package/src/installation/types.js +57 -0
  173. package/src/installation/version-detector.js +233 -0
  174. package/src/items/item-conversation.js +101 -0
  175. package/src/items/items-migrator.js +358 -0
  176. package/src/items/items-slug.js +55 -0
  177. package/src/items/items-store-io.js +257 -0
  178. package/src/items/items-store.js +541 -0
  179. package/src/localization/index.js +3 -3
  180. package/src/localization/translations/en-part1.js +1 -1
  181. package/src/localization/translations/en-part2.js +1 -1
  182. package/src/localization/translations/es-part1.js +1 -1
  183. package/src/localization/translations/es-part2.js +1 -1
  184. package/src/models/compliance-report.js +44 -44
  185. package/src/models/file-analysis.js +33 -33
  186. package/src/models/plan-manager.js +44 -44
  187. package/src/models/refactoring-models.js +4 -4
  188. package/src/models/refactoring-plan-refactored.js +2 -2
  189. package/src/models/refactoring-plan.js +5 -5
  190. package/src/monitoring/alert-system.js +84 -84
  191. package/src/monitoring/compliance-progress-tracker.js +19 -19
  192. package/src/monitoring/continuous-scan-notifications.js +54 -54
  193. package/src/monitoring/continuous-scanner.js +24 -24
  194. package/src/monitoring/file-monitor/file-analyzer.js +23 -23
  195. package/src/monitoring/file-monitor/file-monitor.js +20 -20
  196. package/src/monitoring/file-monitor/watcher.js +18 -18
  197. package/src/monitoring/file-monitor.js +1 -1
  198. package/src/monitoring/notification-handlers/base-handler.js +3 -3
  199. package/src/monitoring/notification-handlers/error-handler.js +1 -1
  200. package/src/monitoring/notification-handlers/index.js +1 -1
  201. package/src/monitoring/notification-handlers/new-violation-handler.js +5 -5
  202. package/src/monitoring/notification-handlers/progress-handler.js +2 -2
  203. package/src/monitoring/notification-handlers/resolved-violation-handler.js +4 -4
  204. package/src/monitoring/notification-handlers/threshold-handler.js +1 -1
  205. package/src/monitoring/notification-manager.js +36 -36
  206. package/src/monitoring/scanner-core.js +43 -43
  207. package/src/monitoring/scanner-events.js +26 -26
  208. package/src/monitoring/violation-notification-system.js +10 -10
  209. package/src/progress/metrics-aggregator.js +194 -0
  210. package/src/progress/metrics-store.js +263 -0
  211. package/src/provider-registry.js +5 -5
  212. package/src/quota-management/index.js +2 -2
  213. package/src/refactoring/boundaries/cohesion-analyzer.js +21 -21
  214. package/src/refactoring/boundaries/extraction-result.js +1 -1
  215. package/src/refactoring/boundaries/extraction-strategies.js +27 -27
  216. package/src/refactoring/boundaries/module-boundary.js +8 -8
  217. package/src/refactoring/boundary/boundary-detector-refactored.js +1 -1
  218. package/src/refactoring/boundary/boundary-detector.js +26 -26
  219. package/src/refactoring/boundary/boundary-types.js +21 -21
  220. package/src/refactoring/boundary/detectors/boundary-analyzers.js +34 -34
  221. package/src/refactoring/boundary/detectors/boundary-core.js +14 -14
  222. package/src/refactoring/boundary/detectors/class-detector.js +28 -28
  223. package/src/refactoring/boundary/detectors/config-detector.js +28 -28
  224. package/src/refactoring/boundary/detectors/constant-detector.js +28 -28
  225. package/src/refactoring/boundary/detectors/function-detector.js +28 -28
  226. package/src/refactoring/boundary/detectors/module-detector.js +29 -29
  227. package/src/refactoring/boundary/detectors/object-detector.js +28 -28
  228. package/src/refactoring/boundary/detectors/type-detectors.js +34 -34
  229. package/src/refactoring/boundary/detectors/utility-detector.js +28 -28
  230. package/src/refactoring/boundary/extraction-strategies.js +61 -61
  231. package/src/refactoring/boundary-extraction-result.js +3 -3
  232. package/src/refactoring/boundary-extraction-strategies.js +28 -28
  233. package/src/refactoring/boundary-extractor.js +13 -13
  234. package/src/refactoring/boundary-types.js +1 -1
  235. package/src/refactoring/circular/circular-dependency.js +4 -4
  236. package/src/refactoring/circular/cycle-detection.js +10 -10
  237. package/src/refactoring/circular/dependency-node.js +1 -1
  238. package/src/refactoring/circular/dependency-result.js +1 -1
  239. package/src/refactoring/circular/dependency-types.js +2 -2
  240. package/src/refactoring/circular/graph-builder.js +25 -25
  241. package/src/refactoring/circular/resolution-strategy.js +1 -1
  242. package/src/refactoring/circular/strategy-generator.js +28 -28
  243. package/src/refactoring/circular-dependency-resolver-original.js +70 -70
  244. package/src/refactoring/circular-dependency-resolver.js +19 -19
  245. package/src/refactoring/code-mover-refactored.js +31 -31
  246. package/src/refactoring/code-mover.js +53 -53
  247. package/src/refactoring/execution-status.js +1 -1
  248. package/src/refactoring/execution-strategies.js +28 -28
  249. package/src/refactoring/file-splitter-core.js +58 -58
  250. package/src/refactoring/file-splitter-types.js +1 -1
  251. package/src/refactoring/file-splitter.js +1 -1
  252. package/src/refactoring/functionality-validator.js +90 -90
  253. package/src/refactoring/import-manager-refactored.js +42 -42
  254. package/src/refactoring/import-manager.js +57 -57
  255. package/src/refactoring/import-models.js +1 -1
  256. package/src/refactoring/import-parser.js +41 -41
  257. package/src/refactoring/module-boundary.js +3 -3
  258. package/src/refactoring/move-executor.js +45 -45
  259. package/src/refactoring/move-utils.js +27 -27
  260. package/src/refactoring/operation-executor.js +7 -7
  261. package/src/refactoring/plan-creator.js +3 -3
  262. package/src/refactoring/plan-executor.js +21 -21
  263. package/src/refactoring/plan-validator.js +10 -10
  264. package/src/refactoring/refactoring-executor-result.js +1 -1
  265. package/src/refactoring/refactoring-executor.js +5 -5
  266. package/src/refactoring/refactoring-operation.js +3 -3
  267. package/src/refactoring/refactoring-plan.js +2 -2
  268. package/src/refactoring/refactoring-rollback.js +1 -1
  269. package/src/refactoring/rollback-handlers/RollbackExecutor.js +12 -12
  270. package/src/refactoring/rollback-handlers/RollbackManager.js +34 -34
  271. package/src/refactoring/rollback-handlers/RollbackOperation.js +2 -2
  272. package/src/refactoring/rollback-handlers/RollbackResult.js +5 -5
  273. package/src/refactoring/rollback-handlers/RollbackStatistics.js +8 -8
  274. package/src/refactoring/test-validator.js +19 -19
  275. package/src/refactoring/validation/baseline-runner.js +10 -10
  276. package/src/refactoring/validation/report-generator.js +16 -16
  277. package/src/refactoring/validation/result-comparator.js +10 -10
  278. package/src/refactoring/validation/test-suite.js +2 -2
  279. package/src/refactoring/validation/test-validation-result.js +2 -2
  280. package/src/refactoring/validation/validation-runner.js +16 -16
  281. package/src/refactoring/validation/validation-status.js +1 -1
  282. package/src/repos/repos-store.js +220 -0
  283. package/src/requirement-management/default-requirement-manager.js +20 -20
  284. package/src/requirement-management/requirement-file-parser.js +3 -3
  285. package/src/requirement-management/requirement-sequencer.js +17 -17
  286. package/src/rui/base.js +6 -6
  287. package/src/rui/commands/AgentCommandParser.js +6 -6
  288. package/src/rui/commands/AgentCommands.js +26 -26
  289. package/src/rui/commands/AgentResponseFormatter.js +12 -12
  290. package/src/rui/commands/parsers/CommandMapper.js +5 -5
  291. package/src/rui/commands/parsers/CommandValidator.js +5 -5
  292. package/src/rui/commands/parsers/ComponentExtractor.js +4 -4
  293. package/src/rui/commands/parsers/TokenParser.js +6 -6
  294. package/src/rui/commands/parsers/tokenizer.js +9 -9
  295. package/src/rui/index.js +5 -5
  296. package/src/rui/registry.js +5 -5
  297. package/src/rui/resolver.js +3 -3
  298. package/src/screenshot/analysis-engine.js +249 -0
  299. package/src/screenshot/capture-engine.js +251 -0
  300. package/src/screenshot/verification-loop.js +191 -0
  301. package/src/scripts/verify-full-compliance.js +32 -32
  302. package/src/spec-management/queue-storage.js +320 -0
  303. package/src/spec-management/retry-manager.js +243 -0
  304. package/src/spec-management/spec-counter.js +301 -0
  305. package/src/spec-management/spec-fingerprint.js +148 -0
  306. package/src/spec-management/spec-logger.js +329 -0
  307. package/src/spec-management/spec-scanner.js +313 -0
  308. package/src/sync/aws-setup.js +41 -41
  309. package/src/sync/remote-control-server.js +50 -50
  310. package/src/sync/sync-engine-conflicts.js +10 -10
  311. package/src/sync/sync-engine-core.js +9 -9
  312. package/src/sync/sync-engine-file-ops.js +7 -7
  313. package/src/sync/sync-engine.js +12 -12
  314. package/src/task-generation/automated-task-generator.js +20 -20
  315. package/src/task-generation/prioritizer.js +39 -39
  316. package/src/task-generation/task-list-updater.js +29 -29
  317. package/src/task-generation/task-management-integration.js +92 -92
  318. package/src/task-generation/task-manager-integration.js +18 -18
  319. package/src/task-generation/violation-task-generator.js +54 -54
  320. package/src/task-management/continuous-scan-integration.js +25 -25
  321. package/src/ui/ChatInterface.js +1 -1
  322. package/src/ui/ChromeExtensionAdapter.js +309 -0
  323. package/src/ui/FeedbackComponent.js +334 -0
  324. package/src/utils/analyzer.js +18 -18
  325. package/src/utils/cleanup.js +28 -28
  326. package/src/utils/config-helpers.js +64 -4
  327. package/src/utils/constants.js +19 -0
  328. package/src/utils/current-requirement-operations.js +63 -11
  329. package/src/utils/dependency-mapper.js +8 -8
  330. package/src/utils/duplicate-detector.js +29 -29
  331. package/src/utils/error-reporter.js +6 -6
  332. package/src/utils/file-monitor.js +20 -20
  333. package/src/utils/git-branch-manager.js +157 -1
  334. package/src/utils/import-updater.js +10 -10
  335. package/src/utils/refactor-plan.js +22 -22
  336. package/src/utils/refactoring-tools.js +7 -7
  337. package/src/utils/repo-helpers.cjs +16 -11
  338. package/src/utils/repo-helpers.js +15 -8
  339. package/src/utils/report-generator.js +1 -1
  340. package/src/utils/report-generators/analysis-generator.js +4 -4
  341. package/src/utils/report-generators/base-generator.js +7 -7
  342. package/src/utils/report-generators/compliance-generator.js +2 -2
  343. package/src/utils/report-generators/format-handlers.js +16 -16
  344. package/src/utils/report-generators/refactoring-generator.js +1 -1
  345. package/src/utils/report-generators/validation-generator.js +3 -3
  346. package/src/utils/reports/report-analysis.js +13 -13
  347. package/src/utils/reports/report-types.js +1 -1
  348. package/src/utils/reports/summary-generators.js +4 -4
  349. package/src/utils/requirement-enable-disable.js +69 -44
  350. package/src/utils/requirement-file-management.js +10 -28
  351. package/src/utils/requirement-helpers/requirement-file-ops.js +22 -17
  352. package/src/utils/requirement-helpers/requirement-mover.js +13 -13
  353. package/src/utils/requirement-helpers/requirement-parser.js +6 -10
  354. package/src/utils/requirement-helpers/requirement-status.js +20 -18
  355. package/src/utils/requirement-helpers-new.js +8 -8
  356. package/src/utils/requirement-helpers-refactored.js +1 -1
  357. package/src/utils/requirement-helpers.js +1 -1
  358. package/src/utils/requirement-loader.js +238 -0
  359. package/src/utils/requirement-movement.js +46 -46
  360. package/src/utils/requirement-writer.js +466 -0
  361. package/src/utils/rollback/rollback-handlers.js +2 -2
  362. package/src/utils/rollback/rollback-operation.js +1 -1
  363. package/src/utils/rollback/rollback-recorder.js +4 -4
  364. package/src/utils/rollback/rollback-state-manager.js +5 -5
  365. package/src/utils/rollback/rollback-types.js +1 -1
  366. package/src/utils/rollback/rollback-utils.js +4 -4
  367. package/src/utils/rollback-manager-original.js +14 -14
  368. package/src/utils/rollback-manager.js +4 -4
  369. package/src/utils/smoke-test-cli.js +20 -20
  370. package/src/utils/smoke-test-gui.js +34 -34
  371. package/src/utils/smoke-test-orchestrator.js +24 -24
  372. package/src/utils/smoke-test-runner.js +5 -5
  373. package/src/utils/smoke-test-web.js +22 -22
  374. package/src/utils/spec-loader.js +308 -0
  375. package/src/utils/spec-writer.js +295 -0
  376. package/src/utils/specification-enable-disable.js +10 -10
  377. package/src/utils/task-parser.js +141 -0
  378. package/src/utils/test-comparator.js +2 -2
  379. package/src/utils/test-config.js +1 -1
  380. package/src/utils/test-executor.js +7 -7
  381. package/src/utils/test-parser.js +4 -4
  382. package/src/utils/test-runner-baseline.js +5 -5
  383. package/src/utils/test-runner-core.js +2 -2
  384. package/src/utils/test-runner-report.js +1 -1
  385. package/src/utils/test-runner-validation.js +9 -9
  386. package/src/utils/test-runner.js +1 -1
  387. package/src/utils/validation-framework.js +27 -27
  388. package/src/utils/verification-summary-validator.js +51 -0
  389. package/src/validation/comparison-analyzer.js +34 -34
  390. package/src/validation/compliance-analyzer.js +23 -23
  391. package/src/validation/compliance-report-generator.js +23 -23
  392. package/src/validation/compliance-reporter-new.js +18 -18
  393. package/src/validation/compliance-reporter-refactored.js +18 -18
  394. package/src/validation/compliance-reporter.js +45 -30
  395. package/src/validation/compliance-rules.js +12 -12
  396. package/src/validation/compliance-utils.js +20 -20
  397. package/src/validation/constitution-validator-new.js +16 -16
  398. package/src/validation/constitution-validator.js +1 -1
  399. package/src/validation/file-validators.js +13 -13
  400. package/src/validation/html-generator.js +27 -27
  401. package/src/validation/line-limit/file-analyzer.js +15 -15
  402. package/src/validation/line-limit/line-limit-validator.js +10 -10
  403. package/src/validation/line-limit/validation-result.js +6 -6
  404. package/src/validation/line-limit-core.js +29 -29
  405. package/src/validation/line-limit-reporter.js +20 -20
  406. package/src/validation/line-limit-result.js +3 -3
  407. package/src/validation/line-limit-validator.js +5 -5
  408. package/src/validation/metrics/category-calculator.js +9 -9
  409. package/src/validation/metrics/metrics-helpers.js +16 -16
  410. package/src/validation/metrics/overview-calculator.js +2 -2
  411. package/src/validation/metrics/overview-metrics.js +1 -1
  412. package/src/validation/metrics/quality-calculator.js +22 -22
  413. package/src/validation/metrics/size-calculator.js +3 -3
  414. package/src/validation/metrics-calculator.js +2 -2
@@ -0,0 +1,483 @@
1
+ // @vibecodingmachine/core - Direct CLI Runner
2
+ //
3
+ // Runs a CLI agent (e.g. Claude Code) as a hidden child process of VCM,
4
+ // streaming stdout/stderr to a caller-supplied logger so the output lands
5
+ // in the VCM Console panel without opening a Terminal window, stealing
6
+ // foreground focus, or pasting into whatever the user happens to be typing
7
+ // in.
8
+ //
9
+ // Replaces the older "wt.exe cmd /k claude" + PowerShell SetForegroundWindow +
10
+ // SendKeys Ctrl+V/Enter pipeline for Auto Mode invocations.
11
+
12
+ const { spawn } = require('child_process');
13
+
14
+ // Billing errors — need human action (add credits), NOT a time-based reset.
15
+ // Detected the same as rate limits (stop retrying) but flagged separately so
16
+ // the UI shows the raw message with no countdown timer.
17
+ const BILLING_PATTERNS = [
18
+ /credit balance is too low/i,
19
+ /credit limit reached/i,
20
+ /insufficient.*credit/i,
21
+ /payment.*required/i,
22
+ /billing.*error/i,
23
+ /add.*credit/i,
24
+ /top.*up.*account/i,
25
+ ];
26
+
27
+ // Strong patterns — verbatim system-error markers that don't appear in
28
+ // assistant prose. A hit on any of these is sufficient to flag the line.
29
+ const RATE_LIMIT_STRONG_PATTERNS = [
30
+ /Claude usage limit reached/i,
31
+ /weekly Claude limit/i,
32
+ /spending cap reached/i,
33
+ /you'?ve hit your limit/i,
34
+ /session limit reached/i,
35
+ /account limit reached/i,
36
+ /approaching weekly limit/i,
37
+ /weekly limit reached/i,
38
+ ];
39
+
40
+ // Weaker phrases that ALSO appear in assistant-generated content. We only
41
+ // flag these when the same line also contains an "Error:" or "HTTP 429"
42
+ // marker (FR-015 / SC-006 false-positive guard).
43
+ const RATE_LIMIT_WEAK_PATTERNS = [
44
+ /rate limit reached/i,
45
+ /quota limit/i,
46
+ /too many requests/i,
47
+ /limit exceeded/i
48
+ ];
49
+ const SYSTEM_ERROR_MARKER = /(?:^|\s)(?:Error:|ERROR:|HTTP\s+429|\b429\b|\bClaude\b)/;
50
+
51
+ const { parseResetTime } = require('../auto-mode/rate-limit-handler');
52
+
53
+ function _findBillingLine(output) {
54
+ if (typeof output !== 'string') return null;
55
+ const lines = output.split('\n');
56
+ for (const line of lines) {
57
+ for (const pat of BILLING_PATTERNS) {
58
+ if (pat.test(line)) return line.trim();
59
+ }
60
+ }
61
+ return null;
62
+ }
63
+
64
+ function _findRateLimitLine(output) {
65
+ if (typeof output !== 'string') return null;
66
+ const lines = output.split('\n');
67
+ for (const line of lines) {
68
+ for (const pat of RATE_LIMIT_STRONG_PATTERNS) {
69
+ if (pat.test(line)) return line.trim();
70
+ }
71
+ for (const pat of RATE_LIMIT_WEAK_PATTERNS) {
72
+ if (pat.test(line) && SYSTEM_ERROR_MARKER.test(line)) return line.trim();
73
+ }
74
+ }
75
+ return null;
76
+ }
77
+
78
+ function detectRateLimit(output) {
79
+ // Check billing errors first — they share the "stop retrying" behaviour but
80
+ // must never show a countdown timer (only adding credits fixes them).
81
+ const billingLine = _findBillingLine(output);
82
+ if (billingLine) {
83
+ return {
84
+ isRateLimited: true,
85
+ isBillingError: true,
86
+ rawMessage: billingLine,
87
+ resetTime: null,
88
+ resetAt: null,
89
+ source: 'billing',
90
+ message: billingLine
91
+ };
92
+ }
93
+
94
+ const line = _findRateLimitLine(output);
95
+ if (!line) return { isRateLimited: false };
96
+
97
+ // Legacy hour-of-day "resets at 3pm" parse, kept for back-compat with
98
+ // call sites that read result.resetTime as a string.
99
+ const legacy = line.match(/resets?\s+(?:at\s+)?(\d+)\s*([ap]m)/i);
100
+ const resetTime = legacy ? `${legacy[1]}${legacy[2].toLowerCase()}` : null;
101
+
102
+ // New broader parse — returns an absolute Date when extractable.
103
+ const parsed = parseResetTime(line);
104
+
105
+ return {
106
+ isRateLimited: true,
107
+ isBillingError: false,
108
+ rawMessage: line,
109
+ resetTime,
110
+ resetAt: parsed.resetAt,
111
+ source: parsed.source,
112
+ message: 'Rate limit detected in CLI output'
113
+ };
114
+ }
115
+
116
+ function resolveDefaultCommand(ide, options) {
117
+ if (options && options.command) return options.command;
118
+ switch (ide) {
119
+ case 'claude':
120
+ case 'claude-code':
121
+ return process.env.VCM_CLAUDE_CLI || 'claude';
122
+ default:
123
+ return null;
124
+ }
125
+ }
126
+
127
+ function resolveDefaultArgs(ide, text, options) {
128
+ if (options && Array.isArray(options.args)) return options.args;
129
+ switch (ide) {
130
+ case 'claude':
131
+ case 'claude-code':
132
+ // --print runs Claude Code headless. --output-format stream-json
133
+ // emits JSONL events as they happen (assistant message deltas,
134
+ // tool use, tool result, etc.) instead of buffering all output
135
+ // until the final response. --verbose is required for stream-json
136
+ // to actually stream. We humanize each JSONL line in StreamBuffer
137
+ // so the Console panel sees readable text instead of raw JSON.
138
+ // --dangerously-skip-permissions lets the agent edit files
139
+ // without interactive approval.
140
+ return ['--print', '--dangerously-skip-permissions', '--verbose', '--output-format', 'stream-json', text];
141
+ default:
142
+ return [text];
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Extract the usage block from a Claude Code stream-json line, if any.
148
+ * Assistant messages carry a `usage` object the Anthropic API returns:
149
+ * { input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens }
150
+ * Returns null when the line has no usage payload (tool_result, system, etc.).
151
+ */
152
+ function extractClaudeUsage(rawLine) {
153
+ if (!rawLine || typeof rawLine !== 'string') return null;
154
+ let evt;
155
+ try { evt = JSON.parse(rawLine); }
156
+ catch (_) { return null; }
157
+ if (!evt || typeof evt !== 'object') return null;
158
+ const u = evt.message && evt.message.usage;
159
+ if (!u || typeof u !== 'object') return null;
160
+ return {
161
+ input: Number(u.input_tokens) || 0,
162
+ output: Number(u.output_tokens) || 0,
163
+ cacheRead: Number(u.cache_read_input_tokens) || 0,
164
+ cacheWrite: Number(u.cache_creation_input_tokens) || 0
165
+ };
166
+ }
167
+
168
+ // Convert a single Claude Code stream-json event into one or more
169
+ // human-readable lines for the Console. Returns an array (possibly
170
+ // empty) of strings.
171
+ function humanizeClaudeStreamLine(rawLine) {
172
+ if (!rawLine || !rawLine.trim()) return [];
173
+ let evt;
174
+ try { evt = JSON.parse(rawLine); }
175
+ catch (_) {
176
+ // Not JSON — pass through unchanged so the user still sees it.
177
+ return [rawLine];
178
+ }
179
+ if (!evt || typeof evt !== 'object') return [rawLine];
180
+
181
+ const out = [];
182
+ const t = evt.type;
183
+
184
+ // Assistant message (the model's text + tool-use blocks)
185
+ if (t === 'assistant' && evt.message && Array.isArray(evt.message.content)) {
186
+ for (const block of evt.message.content) {
187
+ if (!block || !block.type) continue;
188
+ if (block.type === 'text' && typeof block.text === 'string') {
189
+ // Split on newlines so each paragraph gets its own console line.
190
+ for (const ln of block.text.split(/\r?\n/)) {
191
+ if (ln.trim()) out.push(`🤖 ${ln}`);
192
+ }
193
+ } else if (block.type === 'tool_use') {
194
+ const name = block.name || 'unknown';
195
+ const summary = _summarizeToolInput(name, block.input);
196
+ out.push(`🔧 ${name}${summary ? ' ' + summary : ''}`);
197
+ }
198
+ }
199
+ // Tool result (the user message in stream-json carries it)
200
+ } else if (t === 'user' && evt.message && Array.isArray(evt.message.content)) {
201
+ for (const block of evt.message.content) {
202
+ if (block && block.type === 'tool_result') {
203
+ const content = block.content;
204
+ let txt = '';
205
+ if (typeof content === 'string') txt = content;
206
+ else if (Array.isArray(content)) {
207
+ txt = content.map(c => (c && c.type === 'text' && c.text) ? c.text : '').filter(Boolean).join('\n');
208
+ }
209
+ const firstLine = (txt || '').split(/\r?\n/)[0] || '';
210
+ const preview = firstLine.length > 200 ? firstLine.slice(0, 200) + '…' : firstLine;
211
+ if (preview) out.push(` ↳ ${preview}`);
212
+ }
213
+ }
214
+ // Final result event
215
+ } else if (t === 'result') {
216
+ if (evt.is_error) out.push(`❌ Error: ${evt.error || evt.subtype || 'unknown'}`);
217
+ else if (evt.subtype === 'success') out.push(`✅ done in ${evt.duration_ms || '?'}ms`);
218
+ } else if (t === 'system') {
219
+ // Init / metadata — skip silently to keep the Console focused on the
220
+ // actual conversation.
221
+ } else if (typeof evt.text === 'string') {
222
+ // Fallback for any event with a top-level text field.
223
+ out.push(evt.text);
224
+ }
225
+ return out;
226
+ }
227
+
228
+ function _summarizeToolInput(name, input) {
229
+ if (!input || typeof input !== 'object') return '';
230
+ const lc = String(name).toLowerCase();
231
+ if (lc === 'read' && input.file_path) return `(${input.file_path})`;
232
+ if (lc === 'write' && input.file_path) return `(${input.file_path})`;
233
+ if (lc === 'edit' && input.file_path) return `(${input.file_path})`;
234
+ if (lc === 'bash' && input.command) {
235
+ const cmd = String(input.command);
236
+ return `(${cmd.length > 100 ? cmd.slice(0, 100) + '…' : cmd})`;
237
+ }
238
+ if (lc === 'glob' && input.pattern) return `(${input.pattern})`;
239
+ if (lc === 'grep' && input.pattern) return `(${input.pattern})`;
240
+ return '';
241
+ }
242
+
243
+ function emitLine(logger, level, line) {
244
+ if (!line) return;
245
+ const trimmed = line.replace(/\r$/, '');
246
+ if (!trimmed) return;
247
+ if (!logger) {
248
+ if (level === 'error') process.stderr.write(`${trimmed}\n`);
249
+ else process.stdout.write(`${trimmed}\n`);
250
+ return;
251
+ }
252
+ const method = level === 'error' ? (logger.error || logger.log) : (logger.log || logger.info);
253
+ if (typeof method === 'function') {
254
+ method.call(logger, trimmed);
255
+ }
256
+ }
257
+
258
+ class StreamBuffer {
259
+ constructor(level, logger, onLine, transform) {
260
+ this.level = level;
261
+ this.logger = logger;
262
+ this.onLine = onLine;
263
+ // Optional transform: takes a raw line, returns an array of zero or
264
+ // more output lines. Used to turn Claude's stream-json events into
265
+ // human-readable Console text.
266
+ this.transform = transform || null;
267
+ this.buffer = '';
268
+ }
269
+
270
+ _emit(line) {
271
+ if (this.transform) {
272
+ const transformed = this.transform(line);
273
+ if (Array.isArray(transformed)) {
274
+ for (const t of transformed) {
275
+ if (t) emitLine(this.logger, this.level, t);
276
+ }
277
+ }
278
+ } else {
279
+ emitLine(this.logger, this.level, line);
280
+ }
281
+ if (this.onLine) this.onLine(line);
282
+ }
283
+
284
+ write(chunk) {
285
+ this.buffer += chunk.toString('utf8');
286
+ let idx;
287
+ // Treat both \n and \r as line breaks so Claude's TUI progress redraws
288
+ // (which use \r) don't all collapse into one giant unreadable line.
289
+ while ((idx = this.buffer.search(/[\r\n]/)) !== -1) {
290
+ const line = this.buffer.slice(0, idx);
291
+ this.buffer = this.buffer.slice(idx + 1);
292
+ this._emit(line);
293
+ }
294
+ }
295
+
296
+ flush() {
297
+ if (this.buffer.length > 0) {
298
+ const line = this.buffer;
299
+ this.buffer = '';
300
+ this._emit(line);
301
+ }
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Run a CLI agent directly and stream its output to the caller-supplied
307
+ * logger. Resolves once the child exits.
308
+ *
309
+ * @param {Object} options
310
+ * @param {string} options.ide IDE identifier (e.g. 'claude-code')
311
+ * @param {string} options.text Prompt text for the agent
312
+ * @param {string} [options.repoPath] Working directory for the child
313
+ * @param {string} [options.command] Override the resolved command name
314
+ * @param {string[]} [options.args] Override the resolved argv
315
+ * @param {Object} [options.logger] Logger with .log/.error methods.
316
+ * Defaults to console; in the Electron
317
+ * main process pass safeLogger so the
318
+ * output flows into the Console panel.
319
+ * @param {number} [options.timeoutMs] Kill the child after this many ms.
320
+ * 0/undefined = no timeout.
321
+ * @param {Object} [options.env] Extra env vars merged onto process.env
322
+ * @param {Function} [options.spawnFn] Injected spawn (for tests)
323
+ * @returns {Promise<Object>}
324
+ */
325
+ async function runCliDirect(options = {}) {
326
+ const {
327
+ ide,
328
+ text,
329
+ repoPath,
330
+ logger = console,
331
+ timeoutMs,
332
+ env: extraEnv,
333
+ spawnFn = spawn,
334
+ // Per-message usage callback. Receives { input, output, cacheRead, cacheWrite }
335
+ // for every stream-json line that carries a `usage` payload. Wired by the
336
+ // electron-app's rate-limit-bridge into the RateLimitBudget tracker so the
337
+ // Agents-tab "X% of 5h limit used" indicator updates live during a run.
338
+ onUsage
339
+ } = options;
340
+
341
+ if (!ide) {
342
+ throw new Error('runCliDirect: ide is required');
343
+ }
344
+ if (typeof text !== 'string' || text.length === 0) {
345
+ throw new Error('runCliDirect: text is required');
346
+ }
347
+
348
+ const command = resolveDefaultCommand(ide, options);
349
+ if (!command) {
350
+ return {
351
+ success: false,
352
+ method: 'cli-direct',
353
+ error: `No direct-spawn command configured for IDE: ${ide}`
354
+ };
355
+ }
356
+ const args = resolveDefaultArgs(ide, text, options);
357
+
358
+ const preview = text.length > 120 ? `${text.slice(0, 120)}…` : text;
359
+ if (logger && typeof logger.log === 'function') {
360
+ logger.log(`[cli-direct] ${command} (${ide}) ← ${preview.replace(/\s+/g, ' ')}`);
361
+ }
362
+
363
+ return new Promise((resolve) => {
364
+ let child;
365
+ const startedAt = Date.now();
366
+ const combined = [];
367
+
368
+ try {
369
+ // Strip ANTHROPIC_API_KEY from the subprocess env so Claude Code uses
370
+ // its saved OAuth/Pro credentials instead of API-key billing. When the
371
+ // key is set in the shell, it overrides the login session and hits the
372
+ // API-account balance (which may be zero) rather than the Pro plan.
373
+ const childEnv = { ...process.env, ...(extraEnv || {}) };
374
+ if ((ide === 'claude' || ide === 'claude-code') && childEnv.ANTHROPIC_API_KEY) {
375
+ delete childEnv.ANTHROPIC_API_KEY;
376
+ }
377
+ child = spawnFn(command, args, {
378
+ cwd: repoPath || process.cwd(),
379
+ env: childEnv,
380
+ // Important: no `shell: true` — we don't want any Terminal popup or
381
+ // shell window. windowsHide ensures the helper console for the
382
+ // child is suppressed on Windows.
383
+ windowsHide: true,
384
+ stdio: ['ignore', 'pipe', 'pipe']
385
+ });
386
+ } catch (err) {
387
+ resolve({
388
+ success: false,
389
+ method: 'cli-direct',
390
+ error: `Failed to spawn ${command}: ${err.message}`,
391
+ command,
392
+ args
393
+ });
394
+ return;
395
+ }
396
+
397
+ // For Claude in stream-json mode, transform each raw JSONL line into
398
+ // human-readable Console text before emitting. Non-Claude IDEs (or a
399
+ // future caller that opts out of stream-json) get the raw line.
400
+ const isClaude = ide === 'claude' || ide === 'claude-code';
401
+ const transform = isClaude ? humanizeClaudeStreamLine : null;
402
+ const onStdoutLine = (line) => {
403
+ combined.push(line);
404
+ // Forward per-message Anthropic usage to the caller if Claude printed one.
405
+ if (isClaude && typeof onUsage === 'function') {
406
+ const usage = extractClaudeUsage(line);
407
+ if (usage) {
408
+ try { onUsage(usage); } catch (_) { /* never block the stream on a listener throw */ }
409
+ }
410
+ }
411
+ };
412
+ const stdoutBuf = new StreamBuffer('info', logger, onStdoutLine, transform);
413
+ const stderrBuf = new StreamBuffer('error', logger, (line) => combined.push(line), null);
414
+
415
+ child.stdout.on('data', (chunk) => stdoutBuf.write(chunk));
416
+ child.stderr.on('data', (chunk) => stderrBuf.write(chunk));
417
+
418
+ let killedByTimeout = false;
419
+ let timer = null;
420
+ if (timeoutMs && timeoutMs > 0) {
421
+ timer = setTimeout(() => {
422
+ killedByTimeout = true;
423
+ try { child.kill('SIGTERM'); } catch (_) { /* ignore */ }
424
+ }, timeoutMs);
425
+ }
426
+
427
+ child.on('error', (err) => {
428
+ if (timer) clearTimeout(timer);
429
+ resolve({
430
+ success: false,
431
+ method: 'cli-direct',
432
+ error: `Spawn error: ${err.message}`,
433
+ command,
434
+ args
435
+ });
436
+ });
437
+
438
+ child.on('close', (code, signal) => {
439
+ if (timer) clearTimeout(timer);
440
+ stdoutBuf.flush();
441
+ stderrBuf.flush();
442
+
443
+ const output = combined.join('\n');
444
+ const rl = detectRateLimit(output);
445
+
446
+ const durationMs = Date.now() - startedAt;
447
+ if (logger && typeof logger.log === 'function') {
448
+ logger.log(`[cli-direct] ${command} exited code=${code} signal=${signal || 'none'} in ${durationMs}ms`);
449
+ }
450
+
451
+ const success = !killedByTimeout && code === 0 && !rl.isRateLimited;
452
+ resolve({
453
+ success,
454
+ method: 'cli-direct',
455
+ exitCode: code,
456
+ signal,
457
+ durationMs,
458
+ command,
459
+ args,
460
+ output,
461
+ isRateLimited: rl.isRateLimited,
462
+ resetTime: rl.resetTime || undefined,
463
+ rateLimitMessage: rl.isRateLimited ? rl.message : undefined,
464
+ error: success
465
+ ? undefined
466
+ : (killedByTimeout
467
+ ? `Killed after ${timeoutMs}ms timeout`
468
+ : rl.isRateLimited
469
+ ? rl.message
470
+ : `Exited with code ${code}`)
471
+ });
472
+ });
473
+ });
474
+ }
475
+
476
+ module.exports = {
477
+ runCliDirect,
478
+ detectRateLimit,
479
+ extractClaudeUsage,
480
+ // Exposed for tests
481
+ StreamBuffer,
482
+ humanizeClaudeStreamLine
483
+ };
@@ -0,0 +1,180 @@
1
+ // @vibecodingmachine/core - CLI Session Manager
2
+ // Manages persistent terminal sessions for CLI-based agents (Claude, etc.)
3
+
4
+ const { execSync } = require('child_process');
5
+ const { join } = require('path');
6
+ const { homedir } = require('os');
7
+ const { readFileSync, writeFileSync, mkdirSync, unlinkSync, existsSync } = require('fs');
8
+ const { tmpdir } = require('os');
9
+
10
+ /**
11
+ * CLI Session Manager
12
+ * Manages persistent terminal sessions for CLI-based IDEs/agents
13
+ */
14
+ class CliSessionManager {
15
+ constructor() {
16
+ this.logger = console;
17
+ this.sessionDir = join(homedir(), '.vibecodingmachine', 'cli-sessions');
18
+ this._ensureSessionDir();
19
+ }
20
+
21
+ /**
22
+ * Ensure session directory exists
23
+ */
24
+ _ensureSessionDir() {
25
+ try {
26
+ mkdirSync(this.sessionDir, { recursive: true });
27
+ } catch (error) {
28
+ this.logger.error('Failed to create session directory:', error.message);
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Get or create a session for a CLI IDE
34
+ * @param {string} ide - IDE name (e.g., 'claude', 'cursor')
35
+ * @param {string} repoPath - Repository path
36
+ * @returns {Object} Session info with status
37
+ */
38
+ getOrCreateSession(ide, repoPath) {
39
+ const sessionFile = join(this.sessionDir, `${ide}.json`);
40
+
41
+ try {
42
+ // Try to load existing session
43
+ const sessionData = JSON.parse(readFileSync(sessionFile, 'utf8'));
44
+
45
+ // Verify the session is still valid (terminal still running the CLI)
46
+ if (this._isSessionActive(sessionData)) {
47
+ this.logger.log(`✅ [${ide}] Reusing existing session`);
48
+ return sessionData;
49
+ }
50
+
51
+ this.logger.log(`⚠️ [${ide}] Previous session is no longer active, creating new one`);
52
+ } catch (error) {
53
+ this.logger.log(`📝 [${ide}] No existing session found, creating new one`);
54
+ }
55
+
56
+ // Create new session
57
+ const newSession = this._createNewSession(ide, repoPath);
58
+
59
+ try {
60
+ writeFileSync(sessionFile, JSON.stringify(newSession, null, 2), 'utf8');
61
+ } catch (error) {
62
+ this.logger.error('Failed to save session:', error.message);
63
+ }
64
+
65
+ return newSession;
66
+ }
67
+
68
+ /**
69
+ * Check if a session is still active by looking for the CLI process
70
+ * @param {Object} sessionData - Session data
71
+ * @returns {boolean} True if session is active
72
+ */
73
+ _isSessionActive(sessionData) {
74
+ if (!sessionData.ide) {
75
+ return false;
76
+ }
77
+
78
+ try {
79
+ // Check if the CLI process is still running
80
+ const command = sessionData.ide === 'claude' ? 'claude' : sessionData.ide === 'cursor' ? 'cursor' : null;
81
+
82
+ if (!command) return false;
83
+
84
+ const processCheck = execSync(`ps aux | grep "${command} --dangerously" | grep -v grep | wc -l`, {
85
+ encoding: 'utf8',
86
+ timeout: 5000
87
+ }).trim();
88
+
89
+ const isActive = parseInt(processCheck) > 0;
90
+ this.logger.log(`🔍 [${sessionData.ide}] Session active check: ${isActive ? 'YES' : 'NO'}`);
91
+ return isActive;
92
+ } catch (error) {
93
+ this.logger.log(`⚠️ Session check failed: ${error.message}`);
94
+ return false;
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Create a new terminal session for a CLI IDE
100
+ * @param {string} ide - IDE name
101
+ * @param {string} repoPath - Repository path
102
+ * @returns {Object} New session object
103
+ */
104
+ _createNewSession(ide, repoPath) {
105
+ const sessionId = `${ide}-${Date.now()}`;
106
+
107
+ this.logger.log(`🚀 [${ide}] Launching ${ide} in terminal...`);
108
+
109
+ try {
110
+ const command = ide === 'claude' ? 'claude' : ide === 'cursor' ? 'cursor' : null;
111
+
112
+ if (!command) {
113
+ throw new Error(`Unsupported CLI IDE: ${ide}`);
114
+ }
115
+
116
+ // Create AppleScript to launch terminal and CLI
117
+ // Use simple script that activates Terminal and runs commands in active window
118
+ const escapedPath = repoPath.replace(/'/g, "'\\''");
119
+ const launchScript = `tell application "Terminal"
120
+ activate
121
+ delay 0.5
122
+ do script "cd '${escapedPath}' && ${command} --dangerously-skip-permissions"
123
+ delay 3
124
+ end tell`;
125
+
126
+ const tempFile = join(tmpdir(), `cli_launch_${ide}_${Date.now()}.scpt`);
127
+ writeFileSync(tempFile, launchScript, 'utf8');
128
+
129
+ try {
130
+ execSync(`osascript "${tempFile}"`, {
131
+ encoding: 'utf8',
132
+ timeout: 20000,
133
+ stdio: 'pipe'
134
+ });
135
+ } finally {
136
+ try { unlinkSync(tempFile); } catch (e) { /* ignore */ }
137
+ }
138
+
139
+ this.logger.log(`✅ [${ide}] Terminal activated and ${command} launched`);
140
+
141
+ return {
142
+ ide,
143
+ sessionId,
144
+ repoPath,
145
+ command,
146
+ createdAt: new Date().toISOString(),
147
+ status: 'active'
148
+ };
149
+ } catch (error) {
150
+ this.logger.error(`❌ [${ide}] Failed to launch session: ${error.message}`);
151
+ return {
152
+ ide,
153
+ sessionId,
154
+ repoPath,
155
+ createdAt: new Date().toISOString(),
156
+ status: 'error',
157
+ error: error.message
158
+ };
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Clear a session (for cleanup or reset)
164
+ * @param {string} ide - IDE name
165
+ */
166
+ clearSession(ide) {
167
+ const sessionFile = join(this.sessionDir, `${ide}.json`);
168
+
169
+ try {
170
+ if (existsSync(sessionFile)) {
171
+ unlinkSync(sessionFile);
172
+ this.logger.log(`🧹 [${ide}] Session cleared`);
173
+ }
174
+ } catch (error) {
175
+ this.logger.error(`Failed to clear session: ${error.message}`);
176
+ }
177
+ }
178
+ }
179
+
180
+ module.exports = CliSessionManager;