ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
140 lines • 5.07 kB
JavaScript
import { spawn } from 'child_process';
import path from 'path';
export class SwiftScreenshotBridge {
process = null;
binaryPath;
requestId = 0;
pendingRequests = new Map();
responseBuffer = '';
isReady = false;
constructor() {
this.binaryPath = path.join(process.cwd(), 'swift-screenshot-service');
}
async start() {
return new Promise((resolve, reject) => {
console.log('🚀 Starting Swift screenshot service...');
this.process = spawn(this.binaryPath, [], {
stdio: ['pipe', 'pipe', 'pipe']
});
this.process.stdout.on('data', (data) => {
this.handleOutput(data.toString());
});
this.process.stderr.on('data', (data) => {
const message = data.toString();
console.log('Swift Screenshot:', message.trim());
if (message.includes('started')) {
this.isReady = true;
resolve();
}
});
this.process.on('error', (error) => {
console.error('Swift screenshot service error:', error);
reject(error);
});
// Test connection with ping after startup
setTimeout(async () => {
try {
await this.ping();
console.log('✅ Swift screenshot service connection confirmed');
}
catch (e) {
reject(e);
}
}, 500);
});
}
handleOutput(data) {
this.responseBuffer += data;
const lines = this.responseBuffer.split('\n');
this.responseBuffer = lines.pop() || '';
for (const line of lines) {
if (line.trim()) {
try {
const response = JSON.parse(line);
const pending = this.pendingRequests.get(response.id);
if (pending) {
clearTimeout(pending.timeout);
this.pendingRequests.delete(response.id);
if (response.success) {
pending.resolve(response.result);
}
else {
pending.reject(new Error(response.error));
}
}
}
catch (e) {
console.error('Swift screenshot parse error:', e);
}
}
}
}
sendRequest(action, params = {}) {
return new Promise((resolve, reject) => {
if (!this.process) {
reject(new Error('Swift screenshot service not started'));
return;
}
const id = this.requestId++;
const timeout = setTimeout(() => {
this.pendingRequests.delete(id);
reject(new Error(`Timeout: ${action}`));
}, 10000); // 10 second timeout for screenshots
this.pendingRequests.set(id, { resolve, reject, timeout });
const request = JSON.stringify({ id, action, params }) + '\n';
this.process.stdin.write(request);
});
}
async ping() {
const result = await this.sendRequest('ping');
return result?.pong === true;
}
async captureFullScreen(options) {
return this.sendRequest('capture_full_screen', options || {});
}
async captureWindow(windowId, options) {
return this.sendRequest('capture_window', { window_id: windowId, ...options });
}
async captureRegion(x, y, width, height, options) {
return this.sendRequest('capture_region', { x, y, width, height, ...options });
}
async captureApplication(bundleId, appName, options) {
return this.sendRequest('capture_application', { bundle_id: bundleId, app_name: appName, ...options });
}
async captureVisibleWindows(options) {
return this.sendRequest('capture_visible_windows', options || {});
}
async shutdown() {
if (this.process) {
try {
await this.sendRequest('quit').catch(() => { });
}
catch (e) {
// Ignore quit errors
}
this.process.kill();
this.process = null;
this.isReady = false;
}
}
get ready() {
return this.isReady;
}
}
// Singleton instance for reuse
let globalScreenshotBridge = null;
export async function getSwiftScreenshotBridge() {
if (!globalScreenshotBridge) {
globalScreenshotBridge = new SwiftScreenshotBridge();
await globalScreenshotBridge.start();
}
return globalScreenshotBridge;
}
export async function shutdownSwiftScreenshotBridge() {
if (globalScreenshotBridge) {
await globalScreenshotBridge.shutdown();
globalScreenshotBridge = null;
}
}
//# sourceMappingURL=swift-screenshot-bridge.js.map