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,528 @@
1
+ // @vibecodingmachine/core - macOS Text Sender
2
+ // macOS-specific text sending operations using AppleScript
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
+ * macOS Text Sender for IDE interactions
11
+ * Handles text sending operations for macOS IDEs
12
+ */
13
+ class MacOSTextSender {
14
+ constructor(appleScriptUtils) {
15
+ this.logger = console;
16
+ this.appleScriptUtils = appleScriptUtils;
17
+ }
18
+
19
+ /**
20
+ * Send text to an IDE using AppleScript
21
+ * @param {string} text - The text to send
22
+ * @param {string} ide - The IDE name ('cursor', 'windsurf', 'claude')
23
+ * @param {string} repoPath - The repository path (optional, used for Claude)
24
+ * @returns {Promise<Object>} Result object with success status and details
25
+ */
26
+ async sendText(text, ide, repoPath = null) {
27
+ const ideName = ide === 'windsurf' ? 'Windsurf' : ide === 'cursor' ? 'Cursor' : ide === 'antigravity' ? 'Antigravity' : (ide === 'claude' || ide === 'claude-code') ? 'Claude' : ide === 'vscode' ? 'VS Code' : ide === 'kiro' ? 'AWS Kiro' : 'Unknown IDE';
28
+
29
+ this.logger.log(`🚀 [${ideName}] Starting text send on macOS platform`);
30
+ this.logger.log(`🚀 [${ideName}] Text to send: "${text}"`);
31
+
32
+ try {
33
+ let appleScript;
34
+
35
+ if (ide === 'windsurf') {
36
+ appleScript = this._generateWindsurfScript(text);
37
+ } else if (ide === 'claude' || ide === 'claude-code') {
38
+ return await this._sendTextToClaude(text, repoPath);
39
+ } else if (ide === 'cursor') {
40
+ appleScript = this.appleScriptUtils.generateAIPanelFocusScript(text, 'Cursor');
41
+ } else if (ide === 'vscode' || ide === 'github-copilot' || ide === 'amazon-q') {
42
+ return await this._sendTextToVSCode(text);
43
+ } else if (ide === 'antigravity') {
44
+ appleScript = this._generateAntigravityScript(text);
45
+ } else if (ide === 'kiro') {
46
+ appleScript = this._generateKiroScript(text);
47
+ } else {
48
+ return {
49
+ success: false,
50
+ error: `Unsupported IDE for AppleScript: ${ide}`,
51
+ note: 'AppleScript is only supported for Cursor, Windsurf, Antigravity, VS Code, GitHub Copilot, Amazon Q, AWS Kiro, and Claude'
52
+ };
53
+ }
54
+
55
+ return await this._executeAppleScript(appleScript, ideName);
56
+ } catch (error) {
57
+ return this._handleAppleScriptError(error, ideName, ide);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Generate AppleScript for Windsurf
63
+ * @param {string} text - Text to send
64
+ * @returns {string} AppleScript code
65
+ */
66
+ _generateWindsurfScript(text) {
67
+ return `
68
+ tell application "System Events"
69
+ tell process "Windsurf"
70
+ -- Check if process is running before attempting to interact
71
+ try
72
+ set frontmost to true
73
+ delay 1
74
+
75
+ -- Step 1: Open Command Palette to start a new chat
76
+ key code 35 using {command down, shift down}
77
+ delay 0.8
78
+
79
+ -- Step 2: Type "New Chat" to start a fresh conversation
80
+ keystroke "New Chat"
81
+ delay 0.8
82
+
83
+ -- Step 3: Press Enter to execute the command
84
+ key code 36
85
+ delay 2.0
86
+
87
+ -- Step 4: Now find and click on chat input field
88
+ try
89
+ set chatInput to text field 1 of group 1 of window 1
90
+ click chatInput
91
+ delay 0.5
92
+ on error
93
+ try
94
+ -- Method 2: Try to find text area for chat
95
+ set chatInput to text area 1 of group 1 of window 1
96
+ click chatInput
97
+ delay 0.5
98
+ on error
99
+ try
100
+ -- Method 3: Try to find any input field
101
+ set chatInput to text field 1 of window 1
102
+ click chatInput
103
+ delay 0.5
104
+ on error
105
+ -- Method 4: Just try typing (fallback)
106
+ delay 0.5
107
+ end try
108
+ end try
109
+ end try
110
+
111
+ -- Type message
112
+ keystroke "${text.replace(/"/g, '\\"')}"
113
+ delay 0.5
114
+
115
+ -- Try multiple submission methods
116
+ key code 36
117
+ delay 0.5
118
+ key code 36 using {command down}
119
+ delay 0.5
120
+ key code 36 using {command down, shift down}
121
+ delay 0.5
122
+ key code 1 using {command down}
123
+ delay 0.5
124
+ on error
125
+ -- Process not running or not accessible
126
+ error "Process 'Windsurf' is not running or not accessible. VibeCodingMachine does not open IDEs - please open Windsurf manually first."
127
+ end try
128
+ end tell
129
+ end tell
130
+ `;
131
+ }
132
+
133
+ /**
134
+ * Generate AppleScript for Antigravity
135
+ * @param {string} text - Text to send
136
+ * @returns {string} AppleScript code
137
+ */
138
+ _generateAntigravityScript(text) {
139
+ return `
140
+ tell application "System Events"
141
+ tell process "Antigravity"
142
+ -- Check if process is running before attempting to interact
143
+ try
144
+ set frontmost to true
145
+ delay 1
146
+
147
+ -- Open Agent chat with Cmd+Shift+L (does not toggle)
148
+ key code 37 using {command down, shift down}
149
+ delay 1.5
150
+
151
+ -- Type message
152
+ keystroke "${text.replace(/"/g, '\\"')}"
153
+ delay 0.5
154
+
155
+ -- Send with Enter
156
+ key code 36
157
+ delay 0.5
158
+
159
+ return "Message sent to Antigravity Agent"
160
+ on error
161
+ -- Process not running or not accessible
162
+ error "Process 'Antigravity' is not running or not accessible. VibeCodingMachine does not open IDEs - please open Antigravity manually first."
163
+ end try
164
+ end tell
165
+ end tell
166
+ `;
167
+ }
168
+
169
+ /**
170
+ * Generate AppleScript for AWS Kiro
171
+ * @param {string} text - Text to send
172
+ * @returns {string} AppleScript code
173
+ */
174
+ _generateKiroScript(text) {
175
+ return `
176
+ tell application "System Events"
177
+ set processName to "AWS Kiro"
178
+ try
179
+ if not (exists process "AWS Kiro") then
180
+ set processName to "Kiro"
181
+ end if
182
+ on error
183
+ set processName to "Kiro"
184
+ end try
185
+
186
+ tell process processName
187
+ set frontmost to true
188
+ delay 1.0
189
+
190
+ -- Attempt to focus chat via standard AI IDE shortcuts
191
+ -- Try Cmd+L (Cursor/Windsurf standard)
192
+ try
193
+ key code 37 using {command down}
194
+ delay 0.5
195
+ on error
196
+ -- Ignore if fails
197
+ end try
198
+
199
+ -- Use clipboard for more reliable text entry than keystrokes
200
+ set clipboard to "${text.replace(/"/g, '\\"')}"
201
+ delay 0.3
202
+
203
+ -- Paste
204
+ key code 9 using {command down}
205
+ delay 0.5
206
+
207
+ -- Send Enter
208
+ key code 36
209
+ delay 0.5
210
+ end tell
211
+ end tell
212
+ `;
213
+ }
214
+
215
+ /**
216
+ * Send text to Claude terminal
217
+ * @param {string} text - Text to send
218
+ * @param {string} repoPath - Repository path
219
+ * @returns {Promise<Object>} Result object
220
+ */
221
+ async _sendTextToClaude(text, repoPath) {
222
+ const targetRepoPath = repoPath || '/Users/jesse/code/mediawink/vibecodingmachine';
223
+ this.logger.log(`🔍 [Claude] Using repo path for terminal detection: "${targetRepoPath}" (passed: "${repoPath}")`);
224
+
225
+ // Check if Claude process is running
226
+ let claudeProcessCount = 0;
227
+ try {
228
+ const processCheck = execSync('ps aux | grep -i "claude" | grep -v grep | grep -v "Claude.app" | wc -l', { encoding: 'utf8' }).trim();
229
+ claudeProcessCount = parseInt(processCheck);
230
+ this.logger.log(`🔍 [Claude] Found ${claudeProcessCount} Claude processes`);
231
+ } catch (error) {
232
+ this.logger.log(`⚠️ [Claude] Process check failed: ${error.message}`);
233
+ }
234
+
235
+ if (claudeProcessCount === 0) {
236
+ // No Claude process running - try to open it
237
+ this.logger.log('⚠️ [Claude] No Claude process found, attempting to open Claude...');
238
+ // This would call the openClaude method from MacOSIDEManager
239
+ // For now, return error since we can't open from here
240
+ return {
241
+ success: false,
242
+ method: 'applescript',
243
+ error: `No Claude process found. Please open Claude manually first.`,
244
+ note: 'Claude CLI not running'
245
+ };
246
+ }
247
+
248
+ // Claude process exists - find and send text to specific Claude terminal window
249
+ return await this._findAndSendToClaudeTerminal(text, targetRepoPath);
250
+ }
251
+
252
+ /**
253
+ * Find and send text to Claude terminal
254
+ * @param {string} text - Text to send
255
+ * @param {string} targetRepoPath - Repository path
256
+ * @returns {Promise<Object>} Result object
257
+ */
258
+ async _findAndSendToClaudeTerminal(text, targetRepoPath) {
259
+ const escapedRepoPath = targetRepoPath.replace(/'/g, "'\\''");
260
+
261
+ const findAndSendToClaudeScript = `
262
+ tell application "Terminal"
263
+ activate
264
+ set claudeWindow to null
265
+ set claudeTab to null
266
+ set windowCount to count of windows
267
+
268
+ -- Search through all terminal windows to find the one running Claude IN THE CORRECT DIRECTORY
269
+ repeat with i from 1 to windowCount
270
+ try
271
+ set currentWindow to window i
272
+ set currentTab to selected tab of currentWindow
273
+ set historyText to history of currentTab as text
274
+
275
+ -- Check for Claude AND correct repo path to avoid sending to wrong terminal
276
+ set hasClaudeCode to historyText contains "Claude Code" or historyText contains "claude --dangerously-skip-permissions"
277
+ set hasRepoPath to historyText contains "${escapedRepoPath}"
278
+ -- Check for Claude interactive prompts or working state
279
+ set hasClaudePrompt to historyText contains "claude>" or historyText contains "What can I help you build" or historyText contains "bypass permissions"
280
+
281
+ if hasClaudeCode and hasRepoPath and hasClaudePrompt then
282
+ set claudeWindow to currentWindow
283
+ set claudeTab to currentTab
284
+ exit repeat
285
+ end if
286
+ on error
287
+ -- Continue to next window
288
+ end try
289
+ end repeat
290
+
291
+ if claudeWindow is not null then
292
+ -- Found existing Claude terminal, bring it to front
293
+ set index of claudeWindow to 1
294
+ delay 1.0
295
+ else
296
+ error "No Claude terminal found in directory: ${escapedRepoPath}"
297
+ end if
298
+ end tell
299
+
300
+ -- Use System Events to send text
301
+ tell application "System Events"
302
+ tell process "Terminal"
303
+ set frontmost to true
304
+ delay 0.5
305
+
306
+ -- Type text
307
+ keystroke "${text.replace(/"/g, '\\"')}"
308
+ delay 1.0
309
+
310
+ -- Submit with return
311
+ keystroke return
312
+ delay 0.3
313
+ end tell
314
+ end tell
315
+ `;
316
+
317
+ try {
318
+ const tempFile = join(tmpdir(), `claude_script_${Date.now()}.scpt`);
319
+ writeFileSync(tempFile, findAndSendToClaudeScript, 'utf8');
320
+
321
+ let result;
322
+ try {
323
+ result = execSync(`osascript "${tempFile}"`, {
324
+ encoding: 'utf8',
325
+ timeout: 30000,
326
+ stdio: 'pipe'
327
+ }).toString().trim();
328
+ } finally {
329
+ try { unlinkSync(tempFile); } catch (cleanupError) { this.logger.log(`⚠️ [Claude] Failed to cleanup temp file: ${cleanupError.message}`); }
330
+ }
331
+
332
+ this.logger.log(`✅ [Claude] AppleScript execution output:`, result);
333
+ return {
334
+ success: true,
335
+ method: 'applescript',
336
+ message: `Text sent to Claude terminal: ${text}`,
337
+ note: result
338
+ };
339
+ } catch (error) {
340
+ this.logger.log('❌ [Claude] AppleScript failed:', error.message);
341
+ return {
342
+ success: false,
343
+ method: 'applescript',
344
+ error: `Failed to send text to Claude: ${error.message}`,
345
+ note: 'Claude AppleScript automation failed'
346
+ };
347
+ }
348
+ }
349
+
350
+ /**
351
+ * Send text to VS Code using dedicated method
352
+ * @param {string} text - Text to send
353
+ * @returns {Promise<Object>} Result object
354
+ */
355
+ async _sendTextToVSCode(text) {
356
+ const ideName = 'VS Code';
357
+ this.logger.log(`🚀 [${ideName}] Using dedicated sendTextToVSCode method with new chat session.`);
358
+
359
+ try {
360
+ // Get current extension from manager instance
361
+ const extension = this.currentExtension || 'gemini-code'; // Default to gemini-code
362
+ let commandText = 'Gemini Code Assist: Focus on Chat View'; // default for gemini
363
+
364
+ if (extension === 'amazon-q') {
365
+ commandText = 'Amazon Q: Open Chat';
366
+ } else if (extension === 'github-copilot') {
367
+ commandText = 'GitHub Copilot Chat: Open Chat';
368
+ } else if (extension === 'gemini-code') {
369
+ commandText = 'Gemini Code Assist: Focus on Chat View';
370
+ } else if (extension === 'windsurf') {
371
+ commandText = 'Windsurf: Open Chat';
372
+ }
373
+
374
+ const appleScript = `
375
+ tell application "System Events"
376
+ tell process "Visual Studio Code"
377
+ -- Check if process is running before attempting to interact
378
+ try
379
+ set frontmost to true
380
+ delay 1.5
381
+ -- Step 1: Start new chat session first (only for Gemini)
382
+ ${extension === 'gemini-code' ? `
383
+ key code 35 using {command down, shift down}
384
+ delay 1.0
385
+ keystroke "Gemini Code Assistant New Chat"
386
+ delay 1.5
387
+ key code 36
388
+ delay 2.0
389
+ ` : ''}
390
+ -- Step 2: Open Command Palette to focus on chat view
391
+ key code 35 using {command down, shift down}
392
+ delay 1.0
393
+ -- Type to open selected extension chat
394
+ keystroke "${commandText.replace(/"/g, '\\"')}"
395
+ delay 1.5
396
+ -- Press Enter
397
+ key code 36
398
+ delay 3.0
399
+ -- Type message
400
+ keystroke "${text.replace(/"/g, '\\"')}"
401
+ delay 1.0
402
+ -- Send with Cmd+Enter or Enter
403
+ key code 36 using {command down}
404
+ delay 0.5
405
+ key code 36
406
+ delay 1.5
407
+ on error
408
+ -- Process not running or not accessible
409
+ error "Process 'Visual Studio Code' is not running or not accessible. VibeCodingMachine does not open IDEs - please open VS Code manually first."
410
+ end try
411
+ end tell
412
+ end tell
413
+ `;
414
+
415
+ const tempFile = join(tmpdir(), `vscode_script_${Date.now()}.scpt`);
416
+ writeFileSync(tempFile, appleScript, 'utf8');
417
+ execSync(`osascript "${tempFile}"`, { stdio: 'pipe' });
418
+ unlinkSync(tempFile);
419
+
420
+ return { success: true, method: 'applescript', message: `Message sent to ${ideName}: ${text}` };
421
+ } catch (error) {
422
+ return { success: false, error: error.message, method: 'applescript' };
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Execute AppleScript and handle result
428
+ * @param {string} appleScript - AppleScript code
429
+ * @param {string} ideName - IDE name for logging
430
+ * @returns {Promise<Object>} Result object
431
+ */
432
+ async _executeAppleScript(appleScript, ideName) {
433
+ this.logger.log(`🚀 [${ideName}] Executing AppleScript with PRECISE CHAT TARGETING...`);
434
+
435
+ if (!appleScript) {
436
+ this.logger.error(`❌ [${ideName}] AppleScript variable is undefined - invalid code path`);
437
+ return {
438
+ success: false,
439
+ method: 'applescript',
440
+ error: 'AppleScript not generated - this should not happen for non-Claude IDEs',
441
+ note: 'Check IDE-specific code path logic'
442
+ };
443
+ }
444
+
445
+ const tempFile = join(tmpdir(), `applescript_${Date.now()}.scpt`);
446
+ try {
447
+ writeFileSync(tempFile, appleScript, 'utf8');
448
+ execSync(`osascript "${tempFile}"`, { stdio: 'pipe' });
449
+ this.logger.log(`✅ [${ideName}] AppleScript executed successfully - PRECISE TARGETING`);
450
+ this.logger.log(`✅ [${ideName}] Message sent successfully via precise element targeting`);
451
+ return {
452
+ success: true,
453
+ method: 'applescript',
454
+ message: `Message sent to ${ideName}`,
455
+ note: 'Message sent via AppleScript automation'
456
+ };
457
+ } finally {
458
+ try {
459
+ unlinkSync(tempFile);
460
+ } catch (cleanupError) {
461
+ this.logger.log(`⚠️ [${ideName}] Failed to cleanup temp file: ${cleanupError.message}`);
462
+ }
463
+ }
464
+ }
465
+
466
+ /**
467
+ * Handle AppleScript execution errors
468
+ * @param {Error} error - The error that occurred
469
+ * @param {string} ideName - IDE name
470
+ * @param {string} ide - IDE identifier
471
+ * @returns {Object} Error result object
472
+ */
473
+ _handleAppleScriptError(error, ideName, ide) {
474
+ this.logger.log('AppleScript interaction failed:', error.message);
475
+
476
+ // Check for Accessibility permission error
477
+ if (error.message.includes('not allowed to send keystrokes') ||
478
+ error.message.includes('assistive devices') ||
479
+ (error.message.includes('System Events') && error.message.includes('not allowed'))) {
480
+
481
+ this.logger.log('⚠️ Accessibility permissions missing. Opening System Settings...');
482
+ try {
483
+ // Open System Settings -> Privacy & Security -> Accessibility
484
+ execSync('open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"');
485
+ } catch (settingsErr) {
486
+ this.logger.log('Failed to open System Settings:', settingsErr.message);
487
+ }
488
+
489
+ return {
490
+ success: false,
491
+ error: 'Missing Accessibility Permissions',
492
+ message: 'Please grant Accessibility permissions to Terminal/Node in System Settings',
493
+ permissionError: true,
494
+ note: 'macOS blocked keystroke automation. Opened settings for user.'
495
+ };
496
+ }
497
+
498
+ // For Claude, don't fall back to simulated response - return actual failure
499
+ if (ide === 'claude' || ide === 'claude-code') {
500
+ return {
501
+ success: false,
502
+ method: 'applescript',
503
+ error: `Failed to send text to Claude: ${error.message}`,
504
+ note: 'Claude AppleScript automation failed. Check if Claude is running and accessible.'
505
+ };
506
+ }
507
+
508
+ // For Antigravity, also return failure to trigger user notification in auto.js
509
+ if (ide === 'antigravity' || ide === 'kiro') {
510
+ return {
511
+ success: false,
512
+ method: 'applescript',
513
+ error: `Failed to send text to ${ideName}: ${error.message}`,
514
+ note: `${ideName} automation failed.`
515
+ };
516
+ }
517
+
518
+ // For other IDEs, fall back to simulated response
519
+ return {
520
+ success: true,
521
+ method: 'simulated',
522
+ message: `Simulated ${ideName} response`,
523
+ note: `${ideName} AppleScript automation failed. Using simulated response for testing.`
524
+ };
525
+ }
526
+ }
527
+
528
+ module.exports = MacOSTextSender;