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,548 @@
1
+ // @vibecodingmachine/core - Response Reader
2
+ // Cross-platform chat response reading functionality
3
+
4
+ const { execSync } = require('child_process');
5
+ const { writeFileSync, unlinkSync } = require('fs');
6
+ const { join } = require('path');
7
+ const { tmpdir } = require('os');
8
+
9
+ /**
10
+ * Response Reader for cross-platform chat response reading
11
+ * Handles response reading for all supported IDEs
12
+ */
13
+ class ResponseReader {
14
+ constructor(platform, windowsManager = null) {
15
+ this.logger = console;
16
+ this.platform = platform;
17
+ this.windowsManager = windowsManager;
18
+ }
19
+
20
+ /**
21
+ * Read chat response from IDE using platform-specific methods
22
+ * @param {string} ide - The IDE name ('cursor', 'windsurf', 'vscode')
23
+ * @returns {Promise<string>} The chat response text
24
+ */
25
+ async readChatResponse(ide) {
26
+ if (ide !== 'windsurf' && ide !== 'cursor' && ide !== 'vscode') {
27
+ return 'Error: Response reading is only supported for Cursor, Windsurf, and VS Code';
28
+ }
29
+
30
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'vscode' ? 'VS Code' : 'Unknown';
31
+ this.logger.log(`${ideName} detected - using platform-specific response reading`);
32
+
33
+ try {
34
+ // For Cursor, try CDP first if available
35
+ if (ide === 'cursor' && this.platform === 'darwin') {
36
+ try {
37
+ this.logger.log('🔧 Attempting CDP method for Cursor...');
38
+ const cdpResponse = await this._readCursorResponseViaCDP();
39
+ if (cdpResponse && cdpResponse.length > 20) {
40
+ this.logger.log('✅ Successfully read Cursor response via CDP');
41
+ return cdpResponse;
42
+ }
43
+ } catch (error) {
44
+ this.logger.log('⚠️ CDP method failed, falling back to AppleScript:', error.message);
45
+ }
46
+ }
47
+
48
+ // Try clipboard-based response detection for Cursor
49
+ if (ide === 'cursor' && this.platform === 'darwin') {
50
+ try {
51
+ this.logger.log('🔧 Attempting clipboard-based response detection...');
52
+ const clipboardResponse = await this._readCursorResponseViaClipboard();
53
+ if (clipboardResponse && clipboardResponse.length > 20) {
54
+ this.logger.log('✅ Successfully read Cursor response via clipboard');
55
+ return clipboardResponse;
56
+ }
57
+ } catch (error) {
58
+ this.logger.log('⚠️ Clipboard method failed, falling back to AppleScript:', error.message);
59
+ }
60
+ }
61
+
62
+ // Use platform-specific reading methods
63
+ if (this.platform === 'darwin') {
64
+ return await this._readResponseMacOS(ide);
65
+ } else if (this.platform === 'win32' && this.windowsManager) {
66
+ return await this.windowsManager.readChatResponse(ide);
67
+ } else {
68
+ return `Error: Platform ${this.platform} not supported for response reading`;
69
+ }
70
+ } catch (error) {
71
+ this.logger.log('Response reading failed:', error.message);
72
+ return 'Error: Could not read response via platform-specific methods';
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Read response using macOS AppleScript methods
78
+ * @param {string} ide - IDE name
79
+ * @returns {Promise<string>} Response text
80
+ */
81
+ async _readResponseMacOS(ide) {
82
+ let appleScript;
83
+
84
+ if (ide === 'cursor') {
85
+ appleScript = this._generateCursorReaderScript();
86
+ } else if (ide === 'windsurf') {
87
+ appleScript = this._generateWindsurfReaderScript();
88
+ } else if (ide === 'vscode') {
89
+ appleScript = this._generateVSCodeReaderScript();
90
+ } else {
91
+ return `Error: AppleScript reading is not supported for IDE: ${ide}`;
92
+ }
93
+
94
+ try {
95
+ const result = execSync(`osascript -e '${appleScript}'`, { stdio: 'pipe', encoding: 'utf8' });
96
+ this.logger.log(`Successfully read ${ide} response via AppleScript`);
97
+ this.logger.log('📖 AppleScript result:', result);
98
+ this.logger.log('📏 Result length:', result.length);
99
+ this.logger.log('🔍 Result preview:', result.substring(0, 200));
100
+
101
+ // Check if result is just diagnostic information
102
+ const isDiagnosticResult = result.includes('DEBUG:') ||
103
+ result.includes('diagnostic') ||
104
+ result.includes('No chat content found') ||
105
+ result.includes('Text areas found: 0') ||
106
+ result.includes('Static text found:') ||
107
+ result.includes('Window count:') ||
108
+ result.includes('Sample text:') ||
109
+ result.includes('Could not read') ||
110
+ result.includes('No readable text content detected');
111
+
112
+ if (isDiagnosticResult) {
113
+ this.logger.log('⚠️ AppleScript returned diagnostic info, all methods failed...');
114
+ return `Unable to read ${ide} response - all methods failed. AppleScript diagnostic: ${result.substring(0, 200)}...`;
115
+ }
116
+
117
+ return result.trim();
118
+ } catch (error) {
119
+ this.logger.log('AppleScript reading failed:', error.message);
120
+ return 'Error: Could not read response via AppleScript';
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Generate AppleScript for reading Cursor responses
126
+ * @returns {string} AppleScript code
127
+ */
128
+ _generateCursorReaderScript() {
129
+ return `
130
+ tell application "System Events"
131
+ tell process "Cursor"
132
+ set frontmost to true
133
+ delay 1
134
+
135
+ -- Method 1: Try to get text from web view content (most likely location)
136
+ try
137
+ set webViewGroups to group of window 1
138
+ set responseText to ""
139
+ repeat with grp in webViewGroups
140
+ try
141
+ -- Look for text areas within groups (web view content)
142
+ set textAreas to text area of grp
143
+ repeat with txtArea in textAreas
144
+ try
145
+ set textValue to value of txtArea
146
+ if textValue is not "" and textValue is not missing value then
147
+ set responseText to responseText & textValue & "\\n"
148
+ end if
149
+ on error
150
+ -- Continue to next text area
151
+ end try
152
+ end repeat
153
+
154
+ -- Look for static text within groups
155
+ set staticTexts to static text of grp
156
+ repeat with txt in staticTexts
157
+ try
158
+ set textValue to value of txt
159
+ if textValue is not "" and textValue is not missing value then
160
+ set responseText to responseText & textValue & "\\n"
161
+ end if
162
+ on error
163
+ -- Continue to next static text
164
+ end try
165
+ end repeat
166
+ on error
167
+ -- Continue to next group
168
+ end try
169
+ end repeat
170
+ if responseText is not "" then
171
+ return responseText
172
+ end if
173
+ on error
174
+ -- Continue to next method
175
+ end try
176
+
177
+ -- Method 2: Try to get text from all text areas in window
178
+ try
179
+ set allTextAreas to text area of window 1
180
+ set responseText to ""
181
+ repeat with txtArea in allTextAreas
182
+ try
183
+ set textValue to value of txtArea
184
+ if textValue is not "" and textValue is not missing value then
185
+ set responseText to responseText & textValue & "\\n"
186
+ end if
187
+ on error
188
+ -- Continue to next text area
189
+ end try
190
+ end repeat
191
+ if responseText is not "" then
192
+ return responseText
193
+ end if
194
+ on error
195
+ -- Continue to next method
196
+ end try
197
+
198
+ -- Method 3: Try to get text from all static text elements
199
+ try
200
+ set allTexts to static text of window 1
201
+ set responseText to ""
202
+ repeat with txt in allTexts
203
+ try
204
+ set textValue to value of txt
205
+ if textValue is not "" and textValue is not missing value then
206
+ set responseText to responseText & textValue & "\\n"
207
+ end if
208
+ on error
209
+ -- Continue to next text element
210
+ end try
211
+ end repeat
212
+ if responseText is not "" then
213
+ return responseText
214
+ end if
215
+ on error
216
+ -- Continue to next method
217
+ end try
218
+
219
+ -- Method 4: Try clipboard approach (select all and copy)
220
+ try
221
+ key code 0 using {command down}
222
+ delay 0.5
223
+ key code 8 using {command down}
224
+ delay 0.5
225
+ set clipboardText to (the clipboard)
226
+ if clipboardText is not "" then
227
+ return clipboardText
228
+ end if
229
+ on error
230
+ -- Continue to next method
231
+ end try
232
+
233
+ -- Method 5: Return diagnostic information
234
+ return "No chat content found in Cursor - diagnostic info: Window exists but no readable text content detected. This may be because Cursor's chat interface is in a web view that AppleScript cannot access directly."
235
+ end tell
236
+ end tell
237
+ `;
238
+ }
239
+
240
+ /**
241
+ * Generate AppleScript for reading Windsurf responses
242
+ * @returns {string} AppleScript code
243
+ */
244
+ _generateWindsurfReaderScript() {
245
+ return `
246
+ tell application "System Events"
247
+ tell process "Windsurf"
248
+ set frontmost to true
249
+ delay 1
250
+
251
+ -- Method 1: Try to get all static text from window
252
+ try
253
+ set allText to value of static text of window 1
254
+ if allText is not "" then
255
+ return allText
256
+ end if
257
+ on error
258
+ -- Continue to next method
259
+ end try
260
+
261
+ -- Method 2: Try to get text from groups
262
+ try
263
+ set groups to group of window 1
264
+ set responseText to ""
265
+ repeat with grp in groups
266
+ try
267
+ set groupText to value of static text of grp
268
+ if groupText is not "" then
269
+ set responseText to responseText & groupText & "\\n"
270
+ end if
271
+ on error
272
+ -- Continue to next group
273
+ end try
274
+ end repeat
275
+ if responseText is not "" then
276
+ return responseText
277
+ end if
278
+ on error
279
+ -- Continue to next method
280
+ end try
281
+
282
+ -- Method 3: Try clipboard approach
283
+ try
284
+ key code 0 using {command down}
285
+ delay 0.5
286
+ key code 8 using {command down}
287
+ delay 0.5
288
+ set clipboardText to (the clipboard)
289
+ if clipboardText is not "" then
290
+ return clipboardText
291
+ end if
292
+ on error
293
+ -- Continue to next method
294
+ end try
295
+
296
+ -- Method 4: Return placeholder
297
+ return "No chat content found in Windsurf"
298
+ end tell
299
+ end tell
300
+ `;
301
+ }
302
+
303
+ /**
304
+ * Generate AppleScript for reading VS Code responses
305
+ * @returns {string} AppleScript code
306
+ */
307
+ _generateVSCodeReaderScript() {
308
+ return `
309
+ tell application "System Events"
310
+ tell process "Visual Studio Code"
311
+ set frontmost to true
312
+ delay 1
313
+
314
+ -- Method 1: Try to get all static text from window (GitHub Copilot Chat)
315
+ try
316
+ set allText to value of static text of window 1
317
+ if allText is not "" then
318
+ return allText
319
+ end if
320
+ on error
321
+ -- Continue to next method
322
+ end try
323
+
324
+ -- Method 2: Try to get text from groups (chat panels)
325
+ try
326
+ set groups to group of window 1
327
+ set responseText to ""
328
+ repeat with grp in groups
329
+ try
330
+ set groupText to value of static text of grp
331
+ if groupText is not "" then
332
+ set responseText to responseText & groupText & "\\n"
333
+ end if
334
+ on error
335
+ -- Continue to next group
336
+ end try
337
+ end repeat
338
+ if responseText is not "" then
339
+ return responseText
340
+ end if
341
+ on error
342
+ -- Continue to next method
343
+ end try
344
+
345
+ -- Method 3: Try to get text from text areas (chat input/output areas)
346
+ try
347
+ set textAreas to text area of window 1
348
+ set responseText to ""
349
+ repeat with txtArea in textAreas
350
+ try
351
+ set textValue to value of txtArea
352
+ if textValue is not "" and textValue is not missing value then
353
+ set responseText to responseText & textValue & "\\n"
354
+ end if
355
+ on error
356
+ -- Continue to next text area
357
+ end try
358
+ end repeat
359
+ if responseText is not "" then
360
+ return responseText
361
+ end if
362
+ on error
363
+ -- Continue to next method
364
+ end try
365
+
366
+ -- Method 4: Try clipboard approach (select all chat content and copy)
367
+ try
368
+ key code 0 using {command down}
369
+ delay 0.5
370
+ key code 8 using {command down}
371
+ delay 0.5
372
+ set clipboardText to (the clipboard)
373
+ if clipboardText is not "" then
374
+ return clipboardText
375
+ end if
376
+ on error
377
+ -- Continue to next method
378
+ end try
379
+
380
+ -- Method 5: Return placeholder
381
+ return "No chat content found in VS Code - ensure GitHub Copilot Chat or Continue extension is active"
382
+ end tell
383
+ end tell
384
+ `;
385
+ }
386
+
387
+ /**
388
+ * Read Cursor response via Chrome DevTools Protocol (CDP)
389
+ * @returns {Promise<string>} The chat response text
390
+ */
391
+ async _readCursorResponseViaCDP() {
392
+ try {
393
+ this.logger.log('🔧 Attempting CDP connection to Cursor on port 9225...');
394
+
395
+ // Import CDP dynamically to avoid issues in VSCode extension context
396
+ const CDP = require('chrome-remote-interface');
397
+
398
+ // List available targets
399
+ const targets = await CDP.List({ port: 9225 });
400
+ this.logger.log(`🔧 Found ${targets.length} CDP targets`);
401
+
402
+ // Find the main workbench target (not settings)
403
+ const workbench = targets.find(t =>
404
+ t.title !== 'Cursor Settings' &&
405
+ t.type === 'page' &&
406
+ t.url && t.url.includes('workbench')
407
+ ) || targets[0];
408
+
409
+ if (!workbench) {
410
+ throw new Error('No suitable Cursor workbench target found');
411
+ }
412
+
413
+ this.logger.log(`🔧 Connecting to target: ${workbench.title}`);
414
+
415
+ // Connect to the target
416
+ const client = await CDP({ port: 9225, target: workbench });
417
+ const { Runtime, DOM } = client;
418
+
419
+ // Enable required domains
420
+ await Runtime.enable();
421
+ await DOM.enable();
422
+
423
+ this.logger.log('🔧 CDP connection established, searching for chat content...');
424
+
425
+ // Try multiple selectors to find chat content
426
+ const selectors = [
427
+ '.chat-content',
428
+ '.chat-messages',
429
+ '.response-content',
430
+ '.ai-response',
431
+ '.message-content',
432
+ '[data-testid="chat-message"]',
433
+ '.markdown-content',
434
+ '.prose',
435
+ '.chat-panel',
436
+ '.sidebar-panel'
437
+ ];
438
+
439
+ for (const selector of selectors) {
440
+ try {
441
+ this.logger.log(`🔧 Trying selector: ${selector}`);
442
+
443
+ // Get document root
444
+ const { root } = await DOM.getDocument();
445
+
446
+ // Search for elements with selector
447
+ const { nodeIds } = await DOM.querySelectorAll({ nodeId: root.nodeId, selector });
448
+
449
+ if (nodeIds.length > 0) {
450
+ this.logger.log(`🔧 Found ${nodeIds.length} elements with selector: ${selector}`);
451
+
452
+ // Get text content from first matching element
453
+ const { nodeId } = await DOM.describeNode({ nodeId: nodeIds[0] });
454
+ const { outerHTML } = await DOM.getOuterHTML({ nodeId });
455
+
456
+ // Extract text content (remove HTML tags)
457
+ const textContent = outerHTML.replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim();
458
+
459
+ if (textContent && textContent.length > 20) {
460
+ this.logger.log(`✅ Successfully extracted chat content via CDP: ${textContent.substring(0, 100)}...`);
461
+ await client.close();
462
+ return textContent;
463
+ }
464
+ }
465
+ } catch (error) {
466
+ this.logger.log(`⚠️ Selector ${selector} failed: ${error.message}`);
467
+ }
468
+ }
469
+
470
+ await client.close();
471
+ throw new Error('No chat content found via CDP');
472
+ } catch (error) {
473
+ this.logger.log(`❌ CDP method failed: ${error.message}`);
474
+ throw error;
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Read Cursor response via clipboard (select all and copy)
480
+ * @returns {Promise<string>} The chat response text
481
+ */
482
+ async _readCursorResponseViaClipboard() {
483
+ try {
484
+ this.logger.log('🔧 Attempting clipboard-based response detection...');
485
+
486
+ // AppleScript to select all content in Cursor and copy to clipboard
487
+ const clipboardScript = `
488
+ tell application "System Events"
489
+ tell process "Cursor"
490
+ set frontmost to true
491
+ delay 1
492
+
493
+ -- Try to focus on the chat area first without selecting all content
494
+ try
495
+ -- Just try to copy without selecting all (safer approach)
496
+ key code 8 using {command down} -- Cmd+C to copy
497
+ delay 0.5
498
+ on error
499
+ -- If that fails, return empty response
500
+ return ""
501
+ end try
502
+ end tell
503
+ end tell
504
+ `;
505
+
506
+ const tempFile = join(tmpdir(), `clipboard_${Date.now()}.scpt`);
507
+ try {
508
+ writeFileSync(tempFile, clipboardScript, 'utf8');
509
+ execSync(`osascript "${tempFile}"`, { stdio: 'pipe' });
510
+ } finally {
511
+ try {
512
+ unlinkSync(tempFile);
513
+ } catch (cleanupError) {
514
+ this.logger.log(`⚠️ Failed to cleanup clipboard temp file: ${cleanupError.message}`);
515
+ }
516
+ }
517
+
518
+ // Read from clipboard
519
+ const clipboardScript2 = `
520
+ clipboard
521
+ `;
522
+
523
+ const tempFile2 = join(tmpdir(), `clipboard_read_${Date.now()}.scpt`);
524
+ try {
525
+ writeFileSync(tempFile2, clipboardScript2, 'utf8');
526
+ const clipboardContent = execSync(`osascript "${tempFile2}"`, { stdio: 'pipe', encoding: 'utf8' });
527
+
528
+ if (clipboardContent && clipboardContent.trim().length > 20) {
529
+ this.logger.log(`✅ Successfully read clipboard content: ${clipboardContent.substring(0, 100)}...`);
530
+ return clipboardContent.trim();
531
+ }
532
+
533
+ throw new Error('Clipboard content is empty or too short');
534
+ } finally {
535
+ try {
536
+ unlinkSync(tempFile2);
537
+ } catch (cleanupError) {
538
+ this.logger.log(`⚠️ Failed to cleanup clipboard read temp file: ${cleanupError.message}`);
539
+ }
540
+ }
541
+ } catch (error) {
542
+ this.logger.log(`❌ Clipboard method failed: ${error.message}`);
543
+ throw error;
544
+ }
545
+ }
546
+ }
547
+
548
+ module.exports = ResponseReader;
@@ -257,6 +257,127 @@ try {
257
257
  };
258
258
  }
259
259
  }
260
+
261
+ /**
262
+ * Open VS Code on Windows
263
+ * @param {string} repoPath - Optional repository path to open
264
+ * @returns {Promise<Object>} Result object with success status and details
265
+ */
266
+ async openVSCode(repoPath = null) {
267
+ try {
268
+ this.logger.log('🔧 Windows: Opening VS Code...');
269
+
270
+ let command = 'code';
271
+ if (repoPath) {
272
+ command += ` "${repoPath}"`;
273
+ }
274
+
275
+ // Try to open VS Code
276
+ execSync(command, { stdio: 'pipe' });
277
+
278
+ // Wait for VS Code to start
279
+ await new Promise(resolve => setTimeout(resolve, 3000));
280
+
281
+ this.logger.log('✅ Windows: VS Code opened successfully');
282
+ return {
283
+ success: true,
284
+ message: repoPath ? `VS Code opened with repository: ${repoPath}` : 'VS Code opened successfully',
285
+ method: 'windows-command'
286
+ };
287
+ } catch (error) {
288
+ this.logger.error('❌ Windows: Error opening VS Code:', error.message);
289
+ return {
290
+ success: false,
291
+ error: error.message,
292
+ method: 'windows-command'
293
+ };
294
+ }
295
+ }
296
+
297
+ /**
298
+ * Open AWS Kiro IDE on Windows
299
+ * @param {string} repoPath - Optional repository path to open
300
+ * @returns {Promise<Object>} Result object with success status and details
301
+ */
302
+ async openKiro(repoPath = null) {
303
+ try {
304
+ this.logger.log('🔧 Windows: Opening AWS Kiro...');
305
+
306
+ // Try different possible Kiro executable names/paths on Windows
307
+ const possibleCommands = [
308
+ 'kiro',
309
+ 'aws-kiro',
310
+ '"C:\\Program Files\\AWS\\Kiro\\kiro.exe"',
311
+ '"C:\\Program Files (x86)\\AWS\\Kiro\\kiro.exe"',
312
+ '"C:\\Users\\' + (require('os').userInfo().username) + '\\AppData\\Local\\Programs\\Kiro\\kiro.exe"'
313
+ ];
314
+
315
+ let command = possibleCommands[0]; // Default to 'kiro'
316
+ if (repoPath) {
317
+ command += ` "${repoPath}"`;
318
+ }
319
+
320
+ let lastError;
321
+ for (const cmd of possibleCommands) {
322
+ try {
323
+ const testCommand = repoPath ? `${cmd} "${repoPath}"` : cmd;
324
+ this.logger.log(`🔧 Windows: Trying command: ${testCommand}`);
325
+
326
+ // Test if the command exists by trying to run it with --version or similar
327
+ try {
328
+ execSync(`${cmd} --version`, { stdio: 'pipe', timeout: 5000 });
329
+ } catch (versionError) {
330
+ // If --version doesn't work, try just running the command
331
+ }
332
+
333
+ // Try to open Kiro
334
+ execSync(testCommand, { stdio: 'pipe', timeout: 10000 });
335
+
336
+ // Wait for Kiro to start
337
+ await new Promise(resolve => setTimeout(resolve, 3000));
338
+
339
+ this.logger.log('✅ Windows: AWS Kiro opened successfully');
340
+ return {
341
+ success: true,
342
+ message: repoPath ? `AWS Kiro opened with repository: ${repoPath}` : 'AWS Kiro opened successfully',
343
+ method: 'windows-command',
344
+ command: testCommand
345
+ };
346
+ } catch (error) {
347
+ lastError = error;
348
+ this.logger.log(`⚠️ Windows: Failed to open Kiro with command: ${cmd} - ${error.message}`);
349
+ continue;
350
+ }
351
+ }
352
+
353
+ // If all commands failed, try using 'start' command as fallback
354
+ try {
355
+ this.logger.log('🔧 Windows: Trying fallback with start command...');
356
+ const fallbackCommand = repoPath
357
+ ? `start kiro "${repoPath}"`
358
+ : 'start kiro';
359
+
360
+ execSync(fallbackCommand, { stdio: 'pipe', timeout: 10000 });
361
+ await new Promise(resolve => setTimeout(resolve, 3000));
362
+
363
+ this.logger.log('✅ Windows: AWS Kiro opened via start command');
364
+ return {
365
+ success: true,
366
+ message: repoPath ? `AWS Kiro opened with repository: ${repoPath}` : 'AWS Kiro opened successfully',
367
+ method: 'windows-start-command'
368
+ };
369
+ } catch (fallbackError) {
370
+ throw lastError || fallbackError;
371
+ }
372
+ } catch (error) {
373
+ this.logger.error('❌ Windows: Error opening AWS Kiro:', error.message);
374
+ return {
375
+ success: false,
376
+ error: `Windows automation error: ${error.message}`,
377
+ method: 'windows-command'
378
+ };
379
+ }
380
+ }
260
381
  }
261
382
 
262
383
  module.exports = WindowsAutomationManager;