UNPKG

@typecad/typecad

Version:

🤖programmatically 💥create 🛰️hardware

145 lines (116 loc) 4.54 kB
#!/usr/bin/env node import { exec } from 'child_process'; import os from 'os'; class WindowCapture { constructor() { this.platform = os.platform(); } async getWindowTitles() { return new Promise((resolve, reject) => { let command; if (this.platform === 'win32') { // Windows: Use PowerShell to get window titles command = `powershell "Get-Process | Where-Object {$_.MainWindowTitle -ne ''} | Select-Object MainWindowTitle | ForEach-Object {$_.MainWindowTitle}"`; } else if (this.platform === 'linux') { // Linux: Use wmctrl or xdotool (fallback to xwininfo) command = `wmctrl -l | awk '{for(i=4;i<=NF;i++) printf "%s ", $i; print ""}' 2>/dev/null || xdotool search --name ".*" getwindowname %@ 2>/dev/null || xwininfo -root -tree | grep -E "^\s+0x" | grep -o '".*"' | sed 's/"//g'`; } else if (this.platform === 'darwin') { // macOS: Use osascript to get window titles command = `osascript -e 'tell application "System Events" to get name of (processes whose background only is false and name is not "")' | tr ',' '\n' | sed 's/^[[:space:]]*//'`; } else { reject(new Error(`Unsupported platform: ${this.platform}`)); return; } exec(command, (error, stdout, stderr) => { if (error) { reject(new Error(`Command failed: ${error.message}`)); return; } const titles = stdout .split('\n') .map(line => line.trim()) .filter(line => line.length > 0) .filter(title => title !== 'N/A' && title !== ''); resolve(titles); }); }); } filterTitles(titles, filterString) { if (!filterString) return titles; return titles.filter(title => title.toLowerCase().includes(filterString.toLowerCase()) ); } async capture(filterString = null) { try { console.log(`🔍 Capturing window titles on ${this.platform}...`); const allTitles = await this.getWindowTitles(); console.log(`📊 Found ${allTitles.length} windows total`); const filteredTitles = this.filterTitles(allTitles, filterString); if (filterString) { console.log(`🎯 Filtered for "${filterString}": ${filteredTitles.length} matches\n`); } else { console.log(`📋 All window titles:\n`); } if (filteredTitles.length === 0) { console.log('❌ No matching windows found'); return []; } filteredTitles.forEach((title, index) => { console.log(`${index + 1}. ${title}`); }); return filteredTitles; } catch (error) { console.error(`❌ Error: ${error.message}`); if (this.platform === 'linux') { console.log('\n💡 Install required tools:'); console.log(' Ubuntu/Debian: sudo apt-get install wmctrl xdotool'); console.log(' Fedora: sudo dnf install wmctrl xdotool'); console.log(' Arch: sudo pacman -S wmctrl xdotool'); } return []; } } } // CLI Interface function parseArgs() { const args = process.argv.slice(2); let filterString = null; for (const arg of args) { if (arg.startsWith('--filter=')) { filterString = arg.split('=')[1].replace(/['"]/g, ''); } else if (arg === '--help' || arg === '-h') { showHelp(); process.exit(0); } } return { filterString }; } function showHelp() { console.log(` 🪟 Window Title Capture Tool Usage: node index.js # Show all window titles node index.js --filter="Chrome" # Filter for windows containing "Chrome" npm start # Show all window titles npm test # Example with Chrome filter Options: --filter=<string> Filter window titles containing this string (case-insensitive) --help, -h Show this help message Examples: node index.js --filter="Visual Studio" node index.js --filter="firefox" node index.js --filter="Terminal" `); } // Main execution async function main() { const { filterString } = parseArgs(); const windowCapture = new WindowCapture(); await windowCapture.capture(filterString); } // Run if called directly if (import.meta.url === `file://${process.argv[1]}`) { main().catch(console.error); } export default WindowCapture;