# CDP Connection Management Robust Chrome DevTools Protocol (CDP) connection system for Aesthetic Computer, designed for VS Code integration and devcontainer environments. ## Overview The CDP system provides: - **Automatic target discovery** - finds aesthetic.computer pages in VS Code - **Smart caching** - remembers last connection for fast reconnection - **Connection pooling** - reuses connections where possible - **Error resilience** - handles disconnections and retries - **Multiple interfaces** - Node.js module, CLI tools, and fish shell commands ## Quick Start (Inside Devcontainer) When running VS Code inside the devcontainer (e.g., via Electron desktop app), CDP is directly accessible: ```bash # List all CDP targets curl -s http://localhost:9333/json | jq '.[].title' # Find News webview curl -s http://localhost:9333/json | jq '.[] | select(.url | contains("news"))' # Find KidLisp.com editor curl -s http://localhost:9333/json | jq '.[] | select(.url | contains("kidlisp.com"))' ``` **Target hierarchy for webviews:** 1. `type: "page"` — VS Code main workbench window 2. `type: "iframe"` — Webview container (parentId = main page) 3. `type: "iframe"` — Actual content iframe (e.g., `localhost:8888/news.aesthetic.computer`) Connect to the innermost iframe for page control. ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ Windows Host (VS Code) │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ VS Code with --remote-debugging-port=9333 │ │ │ │ ├─ Simple Browser: https://localhost:8888/prompt │ │ │ │ ├─ CDP targets exposed on port 9333 │ │ │ │ └─ SSH tunnel forwards to devcontainer │ │ │ └──────────────────────────────────────────────────────┘ │ │ ▲ │ │ │ port 9333 │ │ ▼ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ DevContainer (Fedora Linux) │ │ │ │ ├─ artery/cdp.mjs - CDP connection module │ │ │ │ ├─ artery/cdp-cli.mjs - CLI tools │ │ │ │ ├─ dotfiles/fish/functions/ac-cdp.fish - shell cmds │ │ │ │ └─ artery/.cdp-cache.json - cached target │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ## Components ### 1. `artery/cdp.mjs` - Core Module The main CDP connection manager. ```javascript import CDP, { createCDP, withCDP } from './artery/cdp.mjs'; // Manual connection const cdp = new CDP({ targetUrl: 'https://localhost:8888/prompt' }); await cdp.connect(); const result = await cdp.eval('document.title'); cdp.close(); // Auto-connection helper const cdp = await createCDP(); const result = await cdp.eval('2 + 2'); cdp.close(); // Auto-cleanup wrapper await withCDP(async (cdp) => { const title = await cdp.eval('document.title'); console.log(title); }); ``` **Key Methods:** - `listTargets()` - Get all CDP targets - `findAestheticPages()` - Find localhost:8888 pages - `findPage(pattern)` - Find specific page by URL - `connect(target)` - Connect to a target (auto-discovers if not provided) - `eval(expression)` - Execute JavaScript in the page - `send(method, params)` - Send CDP command - `getPageInfo()` - Get page metadata - `waitForReady()` - Wait for page to load - `cacheTarget(target)` - Cache target for fast reconnection - `loadCachedTarget()` - Load cached target - `close()` - Disconnect **Options:** ```javascript const cdp = new CDP({ port: 9333, // CDP port (default: 9333) targetUrl: 'https://localhost:8888', // URL pattern to find verbose: true // Enable debug logging }); ``` ### 2. `artery/cdp-cli.mjs` - CLI Tools Command-line interface for CDP management. ```bash # List all targets node artery/cdp-cli.mjs list # Find a specific target node artery/cdp-cli.mjs find prompt # Test connection node artery/cdp-cli.mjs connect # Evaluate JavaScript node artery/cdp-cli.mjs eval "document.title" # Cache current page node artery/cdp-cli.mjs cache # Run connection tests node artery/cdp-cli.mjs test # Show help node artery/cdp-cli.mjs help ``` ### 3. Fish Shell Commands Convenient shell functions for CDP management. ```bash # Show status ac-cdp-status # List targets ac-cdp-list # Find target ac-cdp-find prompt # Test connection ac-cdp-test # Connect to page ac-cdp-connect # Evaluate JS ac-cdp-eval "document.title" # Cache target ac-cdp-cache # Show help ac-cdp-help ``` ## Usage Examples ### Basic Page Interaction ```javascript import { withCDP } from './artery/cdp.mjs'; await withCDP(async (cdp) => { // Get page info const info = await cdp.getPageInfo(); console.log(`Title: ${info.title}`); console.log(`URL: ${info.url}`); // Execute code const result = await cdp.eval(` document.querySelector('h1')?.textContent `); console.log(result); }); ``` ### Performance Monitoring ```javascript import { withCDP } from './artery/cdp.mjs'; await withCDP(async (cdp) => { const metrics = await cdp.eval(` (() => { const entries = performance.getEntriesByType('resource'); return { totalResources: entries.length, totalDuration: entries.reduce((sum, e) => sum + e.duration, 0), slowest: entries .sort((a, b) => b.duration - a.duration) .slice(0, 5) .map(e => ({ name: e.name, duration: e.duration })) }; })() `); console.log(metrics); }); ``` ### Multi-Target Discovery ```javascript import CDP from './artery/cdp.mjs'; const cdp = new CDP(); const pages = await cdp.findAestheticPages(); console.log(`Found ${pages.length} aesthetic.computer pages:`); pages.forEach(page => { console.log(` ${page.url} (${page.type})`); }); ``` ### Cached Connection ```javascript import { createCDP } from './artery/cdp.mjs'; // First connection - discovers and caches target const cdp1 = await createCDP(); await cdp1.eval('console.log("first")'); cdp1.close(); // Second connection - uses cache (faster) const cdp2 = await createCDP(); await cdp2.eval('console.log("second")'); cdp2.close(); ``` ## Cache System The CDP system caches the last connected target in `artery/.cdp-cache.json`: ```json { "id": "1D22CC826937AB2A7657C4662C203999", "url": "https://localhost:8888/prompt", "webSocketDebuggerUrl": "ws://localhost:9333/devtools/page/1D22CC826937AB2A7657C4662C203999", "timestamp": 1734556800000 } ``` **Cache Behavior:** - Auto-cached on successful connection - Expires after 5 minutes - Validated before use (checks if target still exists) - Fallback to discovery if cache invalid **Manual Cache Management:** ```bash # Cache current page ac-cdp-cache # Clear cache rm artery/.cdp-cache.json # View cache cat artery/.cdp-cache.json | jq ``` ## Error Handling The CDP system provides detailed error messages: ```javascript import { createCDP } from './artery/cdp.mjs'; try { const cdp = await createCDP(); await cdp.eval('invalid syntax here'); } catch (err) { console.error(err.message); // "Evaluation failed: SyntaxError: Unexpected identifier" } ``` **Common Errors:** - `CDP port 9333 not accessible` - VS Code not running or tunnel down - `No aesthetic.computer pages found` - App not open in Simple Browser - `Connection timeout` - Network issues or wrong port - `Cached target no longer exists` - Page closed, will auto-discover - `Evaluation failed` - JavaScript syntax error in eval() ## Integration with Artery The existing `Artery` class now exports the CDP module: ```javascript import Artery, { CDP } from './artery/artery.mjs'; // Use Artery's connection (legacy) const artery = new Artery(); await artery.connect(); const result = await artery.eval('2 + 2'); // Or use CDP directly (simpler) import { withCDP } from './artery/cdp.mjs'; await withCDP(async (cdp) => { const result = await cdp.eval('2 + 2'); }); ``` ## Troubleshooting ### CDP Port Not Accessible ```bash # Check if port is open ac-cdp-status # Check VS Code is running with CDP enabled # On Windows host, the aesthetic.ps1 script should launch with: # code --remote-debugging-port=9333 ``` ### No Aesthetic Pages Found ```bash # List all targets to see what's available ac-cdp-list # Make sure aesthetic.computer is open in Simple Browser # URL should be https://localhost:8888/... ``` ### Connection Timeouts ```bash # Test connection ac-cdp-test # If it fails, check: # 1. Is VS Code running? # 2. Is the app loaded in Simple Browser? # 3. Is the SSH tunnel working? (check aesthetic.ps1) ``` ### Cache Issues ```bash # Clear cache and reconnect rm artery/.cdp-cache.json ac-cdp-cache # Check cache status ac-cdp-status ``` ## Best Practices 1. **Use `withCDP` for one-off scripts** - auto-cleanup 2. **Cache targets for frequent connections** - faster startup 3. **Check `ac-cdp-status` before scripting** - verify connectivity 4. **Use verbose mode for debugging** - `new CDP({ verbose: true })` 5. **Handle errors gracefully** - connection can fail 6. **Close connections when done** - prevent resource leaks ## Performance **First connection (uncached):** - Target discovery: ~50-100ms - WebSocket handshake: ~50-100ms - Total: ~100-200ms **Cached connection:** - Cache validation: ~20-30ms - WebSocket handshake: ~50-100ms - Total: ~70-130ms **Evaluation overhead:** - Simple eval: ~5-10ms - Complex eval: ~10-50ms - DOM queries: ~20-100ms ## Future Enhancements - [ ] Connection pooling (reuse existing connections) - [ ] Multiple target management (connect to multiple pages) - [ ] Event streaming (listen to console/network events) - [ ] Auto-reconnect on disconnect - [ ] TypeScript definitions - [ ] Browser target support (Chrome/Edge directly, not just VS Code)