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.
- package/README.md +240 -0
- package/package.json +10 -2
- package/src/agents/Agent.js +300 -0
- package/src/agents/AgentAdditionService.js +311 -0
- package/src/agents/AgentCheckService.js +690 -0
- package/src/agents/AgentInstallationService.js +140 -0
- package/src/agents/AgentSetupService.js +467 -0
- package/src/agents/AgentStatus.js +183 -0
- package/src/agents/AgentVerificationService.js +634 -0
- package/src/agents/ConfigurationSchemaValidator.js +543 -0
- package/src/agents/EnvironmentConfigurationManager.js +602 -0
- package/src/agents/InstallationErrorHandler.js +372 -0
- package/src/agents/InstallationLog.js +363 -0
- package/src/agents/InstallationMethod.js +510 -0
- package/src/agents/InstallationOrchestrator.js +352 -0
- package/src/agents/InstallationProgressReporter.js +372 -0
- package/src/agents/InstallationRetryManager.js +322 -0
- package/src/agents/InstallationType.js +254 -0
- package/src/agents/OperationTypes.js +310 -0
- package/src/agents/PerformanceMetricsCollector.js +493 -0
- package/src/agents/SecurityValidationService.js +534 -0
- package/src/agents/VerificationTest.js +354 -0
- package/src/agents/VerificationType.js +226 -0
- package/src/agents/WindowsPermissionHandler.js +518 -0
- package/src/agents/config/AgentConfigManager.js +393 -0
- package/src/agents/config/AgentDefaultsRegistry.js +373 -0
- package/src/agents/config/ConfigValidator.js +281 -0
- package/src/agents/discovery/AgentDiscoveryService.js +707 -0
- package/src/agents/logging/AgentLogger.js +511 -0
- package/src/agents/status/AgentStatusManager.js +481 -0
- package/src/agents/storage/FileManager.js +454 -0
- package/src/agents/verification/AgentCommunicationTester.js +474 -0
- package/src/agents/verification/BaseVerifier.js +430 -0
- package/src/agents/verification/CommandVerifier.js +480 -0
- package/src/agents/verification/FileOperationVerifier.js +453 -0
- package/src/agents/verification/ResultAnalyzer.js +707 -0
- package/src/agents/verification/TestRequirementManager.js +495 -0
- package/src/agents/verification/VerificationRunner.js +433 -0
- package/src/agents/windows/BaseWindowsInstaller.js +441 -0
- package/src/agents/windows/ChocolateyInstaller.js +509 -0
- package/src/agents/windows/DirectInstaller.js +443 -0
- package/src/agents/windows/InstallerFactory.js +391 -0
- package/src/agents/windows/NpmInstaller.js +505 -0
- package/src/agents/windows/PowerShellInstaller.js +458 -0
- package/src/agents/windows/WinGetInstaller.js +390 -0
- package/src/analysis/analysis-reporter.js +132 -0
- package/src/analysis/boundary-detector.js +712 -0
- package/src/analysis/categorizer.js +340 -0
- package/src/analysis/codebase-scanner.js +384 -0
- package/src/analysis/line-counter.js +513 -0
- package/src/analysis/priority-calculator.js +679 -0
- package/src/analysis/report/analysis-report.js +250 -0
- package/src/analysis/report/package-analyzer.js +278 -0
- package/src/analysis/report/recommendation-generator.js +382 -0
- package/src/analysis/report/statistics-generator.js +515 -0
- package/src/analysis/reports/analysis-report-model.js +101 -0
- package/src/analysis/reports/recommendation-generator.js +283 -0
- package/src/analysis/reports/report-generators.js +191 -0
- package/src/analysis/reports/statistics-calculator.js +231 -0
- package/src/analysis/reports/trend-analyzer.js +219 -0
- package/src/analysis/strategy-generator.js +814 -0
- package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
- package/src/config/refactoring-config.js +307 -0
- package/src/health-tracking/json-storage.js +38 -2
- package/src/ide-integration/applescript-manager-core.js +233 -0
- package/src/ide-integration/applescript-manager.cjs +357 -28
- package/src/ide-integration/applescript-manager.js +89 -3599
- package/src/ide-integration/cdp-manager.js +306 -0
- package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
- package/src/ide-integration/continuation-handler.js +337 -0
- package/src/ide-integration/ide-status-checker.js +292 -0
- package/src/ide-integration/macos-ide-manager.js +627 -0
- package/src/ide-integration/macos-text-sender.js +528 -0
- package/src/ide-integration/response-reader.js +548 -0
- package/src/ide-integration/windows-automation-manager.js +121 -0
- package/src/ide-integration/windows-ide-manager.js +373 -0
- package/src/index.cjs +25 -3
- package/src/index.js +15 -1
- package/src/llm/direct-llm-manager.cjs +90 -2
- package/src/models/compliance-report.js +538 -0
- package/src/models/file-analysis.js +681 -0
- package/src/models/refactoring-plan.js +770 -0
- package/src/monitoring/alert-system.js +834 -0
- package/src/monitoring/compliance-progress-tracker.js +437 -0
- package/src/monitoring/continuous-scan-notifications.js +661 -0
- package/src/monitoring/continuous-scanner.js +279 -0
- package/src/monitoring/file-monitor/file-analyzer.js +262 -0
- package/src/monitoring/file-monitor/file-monitor.js +237 -0
- package/src/monitoring/file-monitor/watcher.js +194 -0
- package/src/monitoring/file-monitor.js +17 -0
- package/src/monitoring/notification-manager.js +437 -0
- package/src/monitoring/scanner-core.js +368 -0
- package/src/monitoring/scanner-events.js +214 -0
- package/src/monitoring/violation-notification-system.js +515 -0
- package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
- package/src/refactoring/boundaries/extraction-result.js +285 -0
- package/src/refactoring/boundaries/extraction-strategies.js +392 -0
- package/src/refactoring/boundaries/module-boundary.js +209 -0
- package/src/refactoring/boundary/boundary-detector.js +741 -0
- package/src/refactoring/boundary/boundary-types.js +405 -0
- package/src/refactoring/boundary/extraction-strategies.js +554 -0
- package/src/refactoring/boundary-extraction-result.js +77 -0
- package/src/refactoring/boundary-extraction-strategies.js +330 -0
- package/src/refactoring/boundary-extractor.js +384 -0
- package/src/refactoring/boundary-types.js +46 -0
- package/src/refactoring/circular/circular-dependency.js +88 -0
- package/src/refactoring/circular/cycle-detection.js +147 -0
- package/src/refactoring/circular/dependency-node.js +82 -0
- package/src/refactoring/circular/dependency-result.js +107 -0
- package/src/refactoring/circular/dependency-types.js +58 -0
- package/src/refactoring/circular/graph-builder.js +213 -0
- package/src/refactoring/circular/resolution-strategy.js +72 -0
- package/src/refactoring/circular/strategy-generator.js +229 -0
- package/src/refactoring/circular-dependency-resolver-original.js +809 -0
- package/src/refactoring/circular-dependency-resolver.js +200 -0
- package/src/refactoring/code-mover.js +761 -0
- package/src/refactoring/file-splitter.js +696 -0
- package/src/refactoring/functionality-validator.js +816 -0
- package/src/refactoring/import-manager.js +774 -0
- package/src/refactoring/module-boundary.js +107 -0
- package/src/refactoring/refactoring-executor.js +672 -0
- package/src/refactoring/refactoring-rollback.js +614 -0
- package/src/refactoring/test-validator.js +631 -0
- package/src/requirement-management/default-requirement-manager.js +321 -0
- package/src/requirement-management/requirement-file-parser.js +159 -0
- package/src/requirement-management/requirement-sequencer.js +221 -0
- package/src/rui/commands/AgentCommandParser.js +600 -0
- package/src/rui/commands/AgentCommands.js +487 -0
- package/src/rui/commands/AgentResponseFormatter.js +832 -0
- package/src/scripts/verify-full-compliance.js +269 -0
- package/src/sync/sync-engine-core.js +1 -0
- package/src/sync/sync-engine-remote-handlers.js +135 -0
- package/src/task-generation/automated-task-generator.js +351 -0
- package/src/task-generation/prioritizer.js +287 -0
- package/src/task-generation/task-list-updater.js +215 -0
- package/src/task-generation/task-management-integration.js +480 -0
- package/src/task-generation/task-manager-integration.js +270 -0
- package/src/task-generation/violation-task-generator.js +474 -0
- package/src/task-management/continuous-scan-integration.js +342 -0
- package/src/timeout-management/index.js +12 -3
- package/src/timeout-management/response-time-tracker.js +167 -0
- package/src/timeout-management/timeout-calculator.js +159 -0
- package/src/timeout-management/timeout-config-manager.js +172 -0
- package/src/utils/ast-analyzer.js +417 -0
- package/src/utils/current-requirement-manager.js +276 -0
- package/src/utils/current-requirement-operations.js +472 -0
- package/src/utils/dependency-mapper.js +456 -0
- package/src/utils/download-with-progress.js +4 -2
- package/src/utils/electron-update-checker.js +4 -1
- package/src/utils/file-size-analyzer.js +272 -0
- package/src/utils/import-updater.js +280 -0
- package/src/utils/refactoring-tools.js +512 -0
- package/src/utils/report-generator.js +569 -0
- package/src/utils/reports/report-analysis.js +218 -0
- package/src/utils/reports/report-types.js +55 -0
- package/src/utils/reports/summary-generators.js +102 -0
- package/src/utils/requirement-file-management.js +157 -0
- package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
- package/src/utils/requirement-helpers/requirement-mover.js +414 -0
- package/src/utils/requirement-helpers/requirement-parser.js +326 -0
- package/src/utils/requirement-helpers/requirement-status.js +320 -0
- package/src/utils/requirement-helpers-new.js +55 -0
- package/src/utils/requirement-helpers-refactored.js +367 -0
- package/src/utils/requirement-helpers.js +291 -1191
- package/src/utils/requirement-movement-operations.js +450 -0
- package/src/utils/requirement-movement.js +312 -0
- package/src/utils/requirement-parsing-helpers.js +56 -0
- package/src/utils/requirement-statistics.js +200 -0
- package/src/utils/requirement-text-utils.js +58 -0
- package/src/utils/rollback/rollback-handlers.js +125 -0
- package/src/utils/rollback/rollback-operation.js +63 -0
- package/src/utils/rollback/rollback-recorder.js +166 -0
- package/src/utils/rollback/rollback-state-manager.js +175 -0
- package/src/utils/rollback/rollback-types.js +33 -0
- package/src/utils/rollback/rollback-utils.js +110 -0
- package/src/utils/rollback-manager-original.js +569 -0
- package/src/utils/rollback-manager.js +202 -0
- package/src/utils/smoke-test-cli.js +362 -0
- package/src/utils/smoke-test-gui.js +351 -0
- package/src/utils/smoke-test-orchestrator.js +321 -0
- package/src/utils/smoke-test-runner.js +60 -0
- package/src/utils/smoke-test-web.js +347 -0
- package/src/utils/specification-helpers.js +39 -13
- package/src/utils/specification-migration.js +97 -0
- package/src/utils/test-runner.js +579 -0
- package/src/utils/validation-framework.js +518 -0
- package/src/validation/compliance-analyzer.js +197 -0
- package/src/validation/compliance-report-generator.js +343 -0
- package/src/validation/compliance-reporter.js +711 -0
- package/src/validation/compliance-rules.js +127 -0
- package/src/validation/constitution-validator-new.js +196 -0
- package/src/validation/constitution-validator.js +17 -0
- package/src/validation/file-validators.js +170 -0
- package/src/validation/line-limit/file-analyzer.js +201 -0
- package/src/validation/line-limit/line-limit-validator.js +208 -0
- package/src/validation/line-limit/validation-result.js +144 -0
- package/src/validation/line-limit-core.js +225 -0
- package/src/validation/line-limit-reporter.js +134 -0
- package/src/validation/line-limit-result.js +125 -0
- package/src/validation/line-limit-validator.js +41 -0
- package/src/validation/metrics-calculator.js +660 -0
- package/src/sync/sync-engine-backup.js +0 -559
|
@@ -0,0 +1,627 @@
|
|
|
1
|
+
// @vibecodingmachine/core - macOS IDE Manager
|
|
2
|
+
// macOS-specific IDE 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 IDE Manager for AppleScript-based interactions
|
|
11
|
+
* Handles all macOS-specific IDE operations
|
|
12
|
+
*/
|
|
13
|
+
class MacOSIDEManager {
|
|
14
|
+
constructor(appleScriptUtils) {
|
|
15
|
+
this.logger = console;
|
|
16
|
+
this.appleScriptUtils = appleScriptUtils;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Open IDE on macOS using AppleScript
|
|
21
|
+
* @param {string} ide - The IDE name
|
|
22
|
+
* @param {string} repoPath - Optional repository path to open
|
|
23
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
24
|
+
*/
|
|
25
|
+
async openIDE(ide, repoPath = null) {
|
|
26
|
+
const ideLower = (ide || '').toLowerCase();
|
|
27
|
+
|
|
28
|
+
switch (ideLower) {
|
|
29
|
+
case 'cursor':
|
|
30
|
+
return await this.openCursor(repoPath);
|
|
31
|
+
case 'windsurf':
|
|
32
|
+
return await this.openWindsurf(repoPath);
|
|
33
|
+
case 'antigravity':
|
|
34
|
+
return await this.openAntigravity(repoPath);
|
|
35
|
+
case 'vscode':
|
|
36
|
+
return await this.openVSCode(repoPath);
|
|
37
|
+
case 'github-copilot':
|
|
38
|
+
return await this.openVSCodeWithExtension('github-copilot', repoPath);
|
|
39
|
+
case 'amazon-q':
|
|
40
|
+
return await this.openVSCodeWithExtension('amazon-q', repoPath);
|
|
41
|
+
case 'replit':
|
|
42
|
+
return await this.openReplit(repoPath);
|
|
43
|
+
case 'kiro':
|
|
44
|
+
return await this.openKiro(repoPath);
|
|
45
|
+
case 'claude':
|
|
46
|
+
case 'claude-code':
|
|
47
|
+
return await this.openClaude(repoPath);
|
|
48
|
+
case 'gemini':
|
|
49
|
+
return await this.openGemini(repoPath);
|
|
50
|
+
default:
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: `Unknown IDE: ${ide}. Supported: cursor, windsurf, antigravity, vscode, github-copilot, amazon-q, replit, kiro, claude, claude-code, gemini`
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Open Cursor IDE with optional repository path and remote debugging enabled
|
|
60
|
+
* @param {string} repoPath - Optional repository path to open
|
|
61
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
62
|
+
*/
|
|
63
|
+
async openCursor(repoPath = null) {
|
|
64
|
+
try {
|
|
65
|
+
this.logger.log('Opening Cursor with remote debugging enabled...');
|
|
66
|
+
|
|
67
|
+
// Launch Cursor with remote debugging enabled
|
|
68
|
+
let command = 'open -a "Cursor" --args --remote-debugging-port=9225';
|
|
69
|
+
if (repoPath) {
|
|
70
|
+
command = `open -a "Cursor" "${repoPath}" --args --remote-debugging-port=9225`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
execSync(command, { stdio: 'pipe' });
|
|
74
|
+
|
|
75
|
+
// Wait for Cursor to start and bind the debugging port
|
|
76
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
77
|
+
|
|
78
|
+
this.logger.log('Cursor opened successfully with remote debugging on port 9225');
|
|
79
|
+
return {
|
|
80
|
+
success: true,
|
|
81
|
+
message: repoPath ? `Cursor opened with repository: ${repoPath} and remote debugging` : 'Cursor opened successfully with remote debugging',
|
|
82
|
+
method: 'applescript',
|
|
83
|
+
debugPort: 9225
|
|
84
|
+
};
|
|
85
|
+
} catch (error) {
|
|
86
|
+
this.logger.log('Error opening Cursor:', error.message);
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: error.message,
|
|
90
|
+
method: 'applescript'
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Open Gemini (in VS Code)
|
|
97
|
+
* @param {string} repoPath - Optional repository path to open
|
|
98
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
99
|
+
*/
|
|
100
|
+
async openGemini(repoPath = null) {
|
|
101
|
+
this.logger.log('Opening Gemini, which runs in VS Code...');
|
|
102
|
+
return await this.openVSCode(repoPath);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Open Claude in a new terminal or bring existing instance to foreground
|
|
107
|
+
* @param {string} repoPath - Optional repository path to open (will cd to this directory before starting Claude)
|
|
108
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
109
|
+
*/
|
|
110
|
+
async openClaude(repoPath = null) {
|
|
111
|
+
try {
|
|
112
|
+
this.logger.log('Opening Claude in terminal or bringing to foreground...');
|
|
113
|
+
|
|
114
|
+
// First, check if any Claude process is running using a simple shell command
|
|
115
|
+
try {
|
|
116
|
+
const claudeProcessCheck = execSync('ps aux | grep -i "claude" | grep -v grep | grep -v "Claude.app" | wc -l', { encoding: 'utf8' }).trim();
|
|
117
|
+
const claudeCount = parseInt(claudeProcessCheck);
|
|
118
|
+
this.logger.log(`🔍 [Claude] Found ${claudeCount} Claude processes running`);
|
|
119
|
+
|
|
120
|
+
if (claudeCount === 0) {
|
|
121
|
+
this.logger.log('No Claude process found, will create new terminal');
|
|
122
|
+
throw new Error('No Claude process running');
|
|
123
|
+
}
|
|
124
|
+
} catch (processCheckError) {
|
|
125
|
+
this.logger.log('No Claude process detected, will create new terminal');
|
|
126
|
+
// Jump to creating new terminal
|
|
127
|
+
const escapedPath = repoPath ? repoPath.replace(/'/g, "'\\''") : '';
|
|
128
|
+
const cdCommand = repoPath ? `cd '${escapedPath}' && ` : '';
|
|
129
|
+
const openClaudeScript = `
|
|
130
|
+
tell application "Terminal"
|
|
131
|
+
activate
|
|
132
|
+
set newWindow to do script "echo 'Starting Claude Code...' && ${cdCommand}claude --dangerously-skip-permissions"
|
|
133
|
+
delay 3
|
|
134
|
+
end tell
|
|
135
|
+
`;
|
|
136
|
+
|
|
137
|
+
const tempFile = join(tmpdir(), `claude_open_${Date.now()}.scpt`);
|
|
138
|
+
try {
|
|
139
|
+
writeFileSync(tempFile, openClaudeScript, 'utf8');
|
|
140
|
+
execSync(`osascript "${tempFile}"`, { stdio: 'pipe' });
|
|
141
|
+
|
|
142
|
+
this.logger.log('Claude opened in new terminal successfully');
|
|
143
|
+
return {
|
|
144
|
+
success: true,
|
|
145
|
+
message: repoPath ? `Claude opened in terminal with context: ${repoPath}` : 'Claude opened in new terminal',
|
|
146
|
+
method: 'applescript',
|
|
147
|
+
action: 'open'
|
|
148
|
+
};
|
|
149
|
+
} finally {
|
|
150
|
+
try {
|
|
151
|
+
unlinkSync(tempFile);
|
|
152
|
+
} catch (cleanupError) {
|
|
153
|
+
this.logger.log(`⚠️ Failed to cleanup temp file: ${cleanupError.message}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// If we get here, Claude process exists - find the specific Claude terminal window
|
|
159
|
+
// [Continued in next part due to size...]
|
|
160
|
+
return await this._findAndFocusClaudeTerminal(repoPath);
|
|
161
|
+
} catch (error) {
|
|
162
|
+
this.logger.log('Error opening Claude:', error.message);
|
|
163
|
+
return {
|
|
164
|
+
success: false,
|
|
165
|
+
error: error.message,
|
|
166
|
+
method: 'applescript'
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Find and focus existing Claude terminal window
|
|
173
|
+
* @param {string} repoPath - Repository path for context
|
|
174
|
+
* @returns {Promise<Object>} Result object
|
|
175
|
+
*/
|
|
176
|
+
async _findAndFocusClaudeTerminal(repoPath) {
|
|
177
|
+
try {
|
|
178
|
+
this.logger.log('🔍 [Claude] Claude process detected, searching for Claude terminal window...');
|
|
179
|
+
const escapedRepoPath = repoPath ? repoPath.replace(/'/g, "'\\''") : '';
|
|
180
|
+
const repoPathCheck = repoPath ? `and historyText contains "${escapedRepoPath}"` : '';
|
|
181
|
+
|
|
182
|
+
const findClaudeWindowScript = `
|
|
183
|
+
tell application "Terminal"
|
|
184
|
+
activate
|
|
185
|
+
delay 0.5
|
|
186
|
+
|
|
187
|
+
set claudeWindow to null
|
|
188
|
+
set windowCount to count of windows
|
|
189
|
+
|
|
190
|
+
-- Search through all terminal windows to find the one running Claude IN THE CORRECT DIRECTORY
|
|
191
|
+
repeat with i from 1 to windowCount
|
|
192
|
+
try
|
|
193
|
+
set currentWindow to window i
|
|
194
|
+
set currentTab to selected tab of currentWindow
|
|
195
|
+
set historyText to history of currentTab as text
|
|
196
|
+
|
|
197
|
+
-- Check for Claude AND optionally the correct repo path to avoid wrong terminal
|
|
198
|
+
if (historyText contains "Claude Code" or historyText contains "claude --dangerously-skip-permissions") ${repoPathCheck} then
|
|
199
|
+
set claudeWindow to currentWindow
|
|
200
|
+
exit repeat
|
|
201
|
+
end if
|
|
202
|
+
on error
|
|
203
|
+
-- Continue to next window
|
|
204
|
+
end try
|
|
205
|
+
end repeat
|
|
206
|
+
|
|
207
|
+
if claudeWindow is not null then
|
|
208
|
+
-- Found Claude window - bring it to front
|
|
209
|
+
set index of claudeWindow to 1
|
|
210
|
+
delay 0.5
|
|
211
|
+
return "claude-window-found"
|
|
212
|
+
else
|
|
213
|
+
return "claude-window-not-found"
|
|
214
|
+
end if
|
|
215
|
+
end tell
|
|
216
|
+
`;
|
|
217
|
+
|
|
218
|
+
const tempFile = join(tmpdir(), `claude_find_${Date.now()}.scpt`);
|
|
219
|
+
try {
|
|
220
|
+
writeFileSync(tempFile, findClaudeWindowScript, 'utf8');
|
|
221
|
+
const result = execSync(`osascript "${tempFile}"`, { stdio: 'pipe', encoding: 'utf8' }).trim();
|
|
222
|
+
|
|
223
|
+
if (result === 'claude-window-found') {
|
|
224
|
+
this.logger.log('✅ [Claude] Found and focused Claude terminal window');
|
|
225
|
+
return {
|
|
226
|
+
success: true,
|
|
227
|
+
message: 'Claude terminal window found and focused',
|
|
228
|
+
method: 'applescript',
|
|
229
|
+
action: 'focus'
|
|
230
|
+
};
|
|
231
|
+
} else {
|
|
232
|
+
this.logger.log('⚠️ [Claude] Claude window not found despite process running, will create new one');
|
|
233
|
+
}
|
|
234
|
+
} finally {
|
|
235
|
+
try {
|
|
236
|
+
unlinkSync(tempFile);
|
|
237
|
+
} catch (cleanupError) {
|
|
238
|
+
this.logger.log(`⚠️ Failed to cleanup temp file: ${cleanupError.message}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// No existing Claude found, open a new terminal with Claude
|
|
243
|
+
return await this._openNewClaudeTerminal(repoPath);
|
|
244
|
+
} catch (focusError) {
|
|
245
|
+
this.logger.log('⚠️ [Claude] Error finding Claude window, will create new one:', focusError.message);
|
|
246
|
+
return await this._openNewClaudeTerminal(repoPath);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Open new Claude terminal
|
|
252
|
+
* @param {string} repoPath - Repository path for context
|
|
253
|
+
* @returns {Promise<Object>} Result object
|
|
254
|
+
*/
|
|
255
|
+
async _openNewClaudeTerminal(repoPath) {
|
|
256
|
+
const escapedPath = repoPath ? repoPath.replace(/'/g, "'\\''") : '';
|
|
257
|
+
const cdCommand = repoPath ? `cd '${escapedPath}' && ` : '';
|
|
258
|
+
const openClaudeScript = `
|
|
259
|
+
tell application "Terminal"
|
|
260
|
+
activate
|
|
261
|
+
set newWindow to do script "echo 'Starting Claude Code...' && ${cdCommand}claude --dangerously-skip-permissions"
|
|
262
|
+
delay 3
|
|
263
|
+
end tell
|
|
264
|
+
`;
|
|
265
|
+
|
|
266
|
+
const tempFile = join(tmpdir(), `claude_open_${Date.now()}.scpt`);
|
|
267
|
+
try {
|
|
268
|
+
writeFileSync(tempFile, openClaudeScript, 'utf8');
|
|
269
|
+
execSync(`osascript "${tempFile}"`, { stdio: 'pipe' });
|
|
270
|
+
|
|
271
|
+
this.logger.log('Claude opened in new terminal successfully');
|
|
272
|
+
return {
|
|
273
|
+
success: true,
|
|
274
|
+
message: repoPath ? `Claude opened in terminal with context: ${repoPath}` : 'Claude opened in new terminal',
|
|
275
|
+
method: 'applescript',
|
|
276
|
+
action: 'open'
|
|
277
|
+
};
|
|
278
|
+
} finally {
|
|
279
|
+
try {
|
|
280
|
+
unlinkSync(tempFile);
|
|
281
|
+
} catch (cleanupError) {
|
|
282
|
+
this.logger.log(`⚠️ Failed to cleanup temp file: ${cleanupError.message}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Open VS Code with optional repository path
|
|
289
|
+
* @param {string} repoPath - Optional repository path to open
|
|
290
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
291
|
+
*/
|
|
292
|
+
async openVSCode(repoPath = null) {
|
|
293
|
+
try {
|
|
294
|
+
this.logger.log('Opening VS Code with remote debugging enabled...');
|
|
295
|
+
|
|
296
|
+
// First, check if VS Code is already running
|
|
297
|
+
try {
|
|
298
|
+
const isRunning = execSync('pgrep -x "Code"', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
299
|
+
if (isRunning) {
|
|
300
|
+
this.logger.log('VS Code is already running - closing it to enable remote debugging...');
|
|
301
|
+
execSync('pkill -x "Code"', { stdio: 'pipe' });
|
|
302
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
303
|
+
}
|
|
304
|
+
} catch (err) {
|
|
305
|
+
// VS Code not running, that's fine
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Launch VS Code with remote debugging enabled for quota detection
|
|
309
|
+
let command = 'open -a "Visual Studio Code" --args --remote-debugging-port=9222';
|
|
310
|
+
if (repoPath) {
|
|
311
|
+
command = `open -a "Visual Studio Code" "${repoPath}" --args --remote-debugging-port=9222`;
|
|
312
|
+
this.logger.log(`Opening VS Code with repository: ${repoPath}`);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
execSync(command, { stdio: 'pipe' });
|
|
316
|
+
|
|
317
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
318
|
+
|
|
319
|
+
// Verify remote debugging port is accessible
|
|
320
|
+
try {
|
|
321
|
+
const CDP = require('chrome-remote-interface');
|
|
322
|
+
await CDP.List({ port: 9222 });
|
|
323
|
+
this.logger.log('✅ VS Code remote debugging port 9222 is accessible');
|
|
324
|
+
} catch (cdpError) {
|
|
325
|
+
this.logger.log(`⚠️ Warning: VS Code remote debugging port not accessible: ${cdpError.message}`);
|
|
326
|
+
this.logger.log(' Waiting additional 2 seconds for VS Code to fully start...');
|
|
327
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
this.logger.log('VS Code opened successfully with remote debugging');
|
|
331
|
+
return { success: true, message: `VS Code opened with repository: ${repoPath}`, method: 'applescript' };
|
|
332
|
+
} catch (error) {
|
|
333
|
+
this.logger.log('Error opening VS Code:', error.message);
|
|
334
|
+
return { success: false, error: error.message, method: 'applescript' };
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Open VS Code with a specific extension installed
|
|
340
|
+
* @param {string} extension - Extension key (e.g., 'github-copilot', 'amazon-q')
|
|
341
|
+
* @param {string} repoPath - Optional repository path to open
|
|
342
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
343
|
+
*/
|
|
344
|
+
async openVSCodeWithExtension(extension, repoPath = null) {
|
|
345
|
+
try {
|
|
346
|
+
this.logger.log(`Opening VS Code with ${extension} extension...`);
|
|
347
|
+
|
|
348
|
+
// Extension IDs mapping
|
|
349
|
+
const extensionIds = {
|
|
350
|
+
'github-copilot': 'GitHub.copilot',
|
|
351
|
+
'amazon-q': 'amazonwebservices.amazon-q-vscode',
|
|
352
|
+
'continue': 'Continue.continue'
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const extensionId = extensionIds[extension];
|
|
356
|
+
if (!extensionId) {
|
|
357
|
+
return { success: false, error: `Unknown extension: ${extension}`, method: 'applescript' };
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// First, check if the extension is installed
|
|
361
|
+
try {
|
|
362
|
+
const checkCmd = `code --list-extensions | grep -i "${extensionId}"`;
|
|
363
|
+
execSync(checkCmd, { stdio: 'pipe' });
|
|
364
|
+
this.logger.log(`Extension ${extension} is already installed`);
|
|
365
|
+
} catch (checkError) {
|
|
366
|
+
// Extension not found, try to install it
|
|
367
|
+
this.logger.log(`Extension ${extension} not found, installing...`);
|
|
368
|
+
try {
|
|
369
|
+
execSync(`code --install-extension ${extensionId} --force`, { stdio: 'pipe', timeout: 60000 });
|
|
370
|
+
this.logger.log(`Extension ${extension} installed successfully`);
|
|
371
|
+
} catch (installError) {
|
|
372
|
+
this.logger.log(`Failed to install extension ${extension}:`, installError.message);
|
|
373
|
+
return { success: false, error: `Failed to install extension: ${installError.message}`, method: 'applescript' };
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// First, check if VS Code is already running
|
|
378
|
+
try {
|
|
379
|
+
const isRunning = execSync('pgrep -x "Code"', { encoding: 'utf8', stdio: 'pipe' }).trim();
|
|
380
|
+
if (isRunning) {
|
|
381
|
+
this.logger.log('VS Code is already running - closing it to enable remote debugging...');
|
|
382
|
+
execSync('pkill -x "Code"', { stdio: 'pipe' });
|
|
383
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
384
|
+
}
|
|
385
|
+
} catch (err) {
|
|
386
|
+
// VS Code not running, that's fine
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Open VS Code with the repository and remote debugging enabled
|
|
390
|
+
let command = 'open -a "Visual Studio Code" --args --remote-debugging-port=9222';
|
|
391
|
+
if (repoPath) {
|
|
392
|
+
command = `open -a "Visual Studio Code" "${repoPath}" --args --remote-debugging-port=9222`;
|
|
393
|
+
this.logger.log(`Opening VS Code with repository: ${repoPath}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
execSync(command, { stdio: 'pipe' });
|
|
397
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
398
|
+
|
|
399
|
+
// Verify remote debugging port is accessible
|
|
400
|
+
try {
|
|
401
|
+
const CDP = require('chrome-remote-interface');
|
|
402
|
+
await CDP.List({ port: 9222 });
|
|
403
|
+
this.logger.log('✅ VS Code remote debugging port 9222 is accessible');
|
|
404
|
+
} catch (cdpError) {
|
|
405
|
+
this.logger.log(`⚠️ Warning: VS Code remote debugging port not accessible: ${cdpError.message}`);
|
|
406
|
+
this.logger.log(' Waiting additional 2 seconds for VS Code to fully start...');
|
|
407
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
this.logger.log(`VS Code opened successfully with ${extension} extension and remote debugging`);
|
|
411
|
+
return { success: true, message: `VS Code opened with ${extension} extension`, method: 'applescript' };
|
|
412
|
+
} catch (error) {
|
|
413
|
+
this.logger.log(`Error opening VS Code with ${extension}:`, error.message);
|
|
414
|
+
return { success: false, error: error.message, method: 'applescript' };
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Open Replit Agent with optional repository path
|
|
420
|
+
* @param {string} repoPath - Optional repository path to open
|
|
421
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
422
|
+
*/
|
|
423
|
+
async openReplit(repoPath = null) {
|
|
424
|
+
try {
|
|
425
|
+
this.logger.log('Opening Replit...');
|
|
426
|
+
this.logger.log(`Platform detected: ${process.platform}`);
|
|
427
|
+
|
|
428
|
+
// Replit typically uses web browser, so we'll open the Replit website
|
|
429
|
+
// If Replit has a desktop app or CLI, this can be updated
|
|
430
|
+
const replitUrl = repoPath
|
|
431
|
+
? `https://replit.com/@replit/agent?path=${encodeURIComponent(repoPath)}`
|
|
432
|
+
: 'https://replit.com/@replit/agent';
|
|
433
|
+
|
|
434
|
+
const command = `open "${replitUrl}"`;
|
|
435
|
+
this.logger.log(`Using macOS command: ${command}`);
|
|
436
|
+
|
|
437
|
+
execSync(command, { stdio: 'pipe' });
|
|
438
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
439
|
+
|
|
440
|
+
this.logger.log('Replit opened successfully');
|
|
441
|
+
return { success: true, message: 'Replit opened in browser', method: 'applescript' };
|
|
442
|
+
} catch (error) {
|
|
443
|
+
this.logger.log('Error opening Replit:', error.message);
|
|
444
|
+
return { success: false, error: error.message, method: 'applescript' };
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Open Windsurf IDE with optional repository path
|
|
450
|
+
* @param {string} repoPath - Optional repository path to open
|
|
451
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
452
|
+
*/
|
|
453
|
+
async openWindsurf(repoPath = null) {
|
|
454
|
+
try {
|
|
455
|
+
this.logger.log('Opening Windsurf...');
|
|
456
|
+
|
|
457
|
+
// Try to find Windsurf installation
|
|
458
|
+
const possiblePaths = [
|
|
459
|
+
'/Users/jesseolsen/.codeium/windsurf/bin/windsurf', // macOS - Codeium installation
|
|
460
|
+
'/Applications/Windsurf.app/Contents/MacOS/Windsurf', // macOS - App Store
|
|
461
|
+
'/usr/local/bin/windsurf', // Linux
|
|
462
|
+
'/opt/windsurf/windsurf' // Linux alternative
|
|
463
|
+
];
|
|
464
|
+
|
|
465
|
+
let windsurfPath = possiblePaths.find(path => {
|
|
466
|
+
try {
|
|
467
|
+
const fs = require('fs');
|
|
468
|
+
fs.accessSync(path);
|
|
469
|
+
return true;
|
|
470
|
+
} catch {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
if (!windsurfPath) {
|
|
476
|
+
// Try using the 'windsurf' command directly
|
|
477
|
+
windsurfPath = 'windsurf';
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
let command;
|
|
481
|
+
if (windsurfPath.includes('Windsurf.app')) {
|
|
482
|
+
// macOS app bundle
|
|
483
|
+
command = `open -a "Windsurf"`;
|
|
484
|
+
if (repoPath) {
|
|
485
|
+
command += ` "${repoPath}"`;
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
// Direct executable - use --reuse-window flag to avoid hanging when Windsurf is already running
|
|
489
|
+
command = `"${windsurfPath}" --reuse-window`;
|
|
490
|
+
if (repoPath) {
|
|
491
|
+
command += ` "${repoPath}"`;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
this.logger.log(`Executing command: ${command}`);
|
|
496
|
+
|
|
497
|
+
// For Windsurf, we don't wait for the command to complete since it runs in background
|
|
498
|
+
if (windsurfPath.includes('windsurf')) {
|
|
499
|
+
// Use spawn to run in background
|
|
500
|
+
const { spawn } = require('child_process');
|
|
501
|
+
const windsurfProcess = spawn(windsurfPath, ['--reuse-window', repoPath], {
|
|
502
|
+
stdio: 'pipe',
|
|
503
|
+
detached: true
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Don't wait for completion, just give it a moment to start
|
|
507
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
508
|
+
} else {
|
|
509
|
+
execSync(command, { stdio: 'pipe' });
|
|
510
|
+
// Wait a moment for Windsurf to start
|
|
511
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
this.logger.log('Windsurf opened successfully');
|
|
515
|
+
return {
|
|
516
|
+
success: true,
|
|
517
|
+
message: repoPath ? `Windsurf opened with repository: ${repoPath}` : 'Windsurf opened successfully',
|
|
518
|
+
method: 'applescript'
|
|
519
|
+
};
|
|
520
|
+
} catch (error) {
|
|
521
|
+
this.logger.log('Error opening Windsurf:', error.message);
|
|
522
|
+
return {
|
|
523
|
+
success: false,
|
|
524
|
+
error: error.message,
|
|
525
|
+
method: 'applescript'
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Open Google Antigravity with optional repository path
|
|
532
|
+
* @param {string} repoPath - Optional repository path to open
|
|
533
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
534
|
+
*/
|
|
535
|
+
async openAntigravity(repoPath = null) {
|
|
536
|
+
try {
|
|
537
|
+
this.logger.log('Opening Google Antigravity...');
|
|
538
|
+
|
|
539
|
+
// Google Antigravity app path
|
|
540
|
+
const antigravityPath = '/Applications/Antigravity.app';
|
|
541
|
+
|
|
542
|
+
// Check if Antigravity is installed
|
|
543
|
+
try {
|
|
544
|
+
const fs = require('fs');
|
|
545
|
+
fs.accessSync(antigravityPath);
|
|
546
|
+
} catch {
|
|
547
|
+
throw new Error('Google Antigravity is not installed at /Applications/Antigravity.app');
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
let command = `open -a "Antigravity"`;
|
|
551
|
+
if (repoPath) {
|
|
552
|
+
command += ` "${repoPath}"`;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
this.logger.log(`Executing command: ${command}`);
|
|
556
|
+
execSync(command, { stdio: 'pipe' });
|
|
557
|
+
|
|
558
|
+
// Wait a moment for Antigravity to start
|
|
559
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
560
|
+
|
|
561
|
+
this.logger.log('Google Antigravity opened successfully');
|
|
562
|
+
return {
|
|
563
|
+
success: true,
|
|
564
|
+
message: repoPath ? `Google Antigravity opened with repository: ${repoPath}` : 'Google Antigravity opened successfully',
|
|
565
|
+
method: 'applescript'
|
|
566
|
+
};
|
|
567
|
+
} catch (error) {
|
|
568
|
+
this.logger.log('Error opening Google Antigravity:', error.message);
|
|
569
|
+
return {
|
|
570
|
+
success: false,
|
|
571
|
+
error: error.message,
|
|
572
|
+
method: 'applescript'
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Open AWS Kiro IDE with optional repository path
|
|
579
|
+
* @param {string} repoPath - Optional repository path to open
|
|
580
|
+
* @returns {Promise<Object>} Result object with success status and details
|
|
581
|
+
*/
|
|
582
|
+
async openKiro(repoPath = null) {
|
|
583
|
+
try {
|
|
584
|
+
this.logger.log('Opening AWS Kiro...');
|
|
585
|
+
|
|
586
|
+
let command = 'open -a "AWS Kiro"';
|
|
587
|
+
if (repoPath) {
|
|
588
|
+
command += ` "${repoPath}"`;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
try {
|
|
592
|
+
this.logger.log(`Executing command: ${command}`);
|
|
593
|
+
execSync(command, { stdio: 'pipe' });
|
|
594
|
+
} catch (e) {
|
|
595
|
+
// Fallback to just "Kiro"
|
|
596
|
+
this.logger.log('Failed to open "AWS Kiro", trying "Kiro"...');
|
|
597
|
+
command = 'open -a "Kiro"';
|
|
598
|
+
if (repoPath) {
|
|
599
|
+
command += ` "${repoPath}"`;
|
|
600
|
+
}
|
|
601
|
+
execSync(command, { stdio: 'pipe' });
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Wait a moment for Kiro to start
|
|
605
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
606
|
+
|
|
607
|
+
this.logger.log('AWS Kiro opened successfully');
|
|
608
|
+
return {
|
|
609
|
+
success: true,
|
|
610
|
+
message: repoPath ? `AWS Kiro opened with repository: ${repoPath}` : 'AWS Kiro opened successfully',
|
|
611
|
+
method: 'applescript'
|
|
612
|
+
};
|
|
613
|
+
} catch (error) {
|
|
614
|
+
this.logger.log('Error opening AWS Kiro:', error.message);
|
|
615
|
+
return {
|
|
616
|
+
success: false,
|
|
617
|
+
error: error.message,
|
|
618
|
+
method: 'applescript'
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Continue with sendText, closePreviousChatThread, and other methods...
|
|
624
|
+
// These will be split into additional files to stay under 555 lines
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
module.exports = MacOSIDEManager;
|